What I'm trying to achieve is that the entity moves in a parabolic curve, and no this has nothing to do with gravity before you ask.
I give the entity a target position which it should move to, but not in a straight line, it should move to that target position in a parabolic curve.
It doesn't matter where the start or target it, I just want the calculate the proper velocity separately for x and y. so that the x, y of the entity arrive at the target position at the exact same time. My entity can move in 8 directions based on targetXY.
What I do is calculate the middle point for each x ,y I separately between startPositionXY and targetPositionXY. I increase the velocity until the middle point and after the middle point I decrease it. But it the Entity x and y do not reach the intented target at the same time instead one either x or y always gets there before the other depending on which direction it's moving in.
Here is what I have so far.
public function update():void {
if(!_hasInitialized){throw new ReferenceError("Fish.initialize must be called once before calling update");}
determineDirection();
determineVelocityBreakpoint();
determineDistance();
determineVelocity();
move();
}
private function move():void {
switch(this._direction){
case "left":
if(getX() > this.pos_target_x){
this. x -= velocity_x;
}else{
setX(this.pos_target_x);
}
break;
case "right":
if(getX() < this.pos_target_x){
this.x += velocity_x;
}else{
setX(this.pos_target_x);
}
break;
case "up":
if(getY() > this.pos_target_y){
this.y -= velocity_y;
}else{
setY(this.pos_target_y);
}
break;
case "down":
if(getY() < this.pos_target_y){
this.y += velocity_y;
}else{
setY(this.pos_target_y);
}
break;
case "left-up":
if(getX() > this.pos_target_x){
this.x -= velocity_x;
}else{
setX(this.pos_target_x);
}
if(getY() > this.pos_target_y){
this.y -= velocity_y;
}else{
setY(this.pos_target_y);
}
break;
case "left-down":
if(getX() > this.pos_target_x){
this.x -= velocity_x;
}else{
setX(this.pos_target_x);
}
if(getY() < this.pos_target_y){
this.y += velocity_y;
}else{
setY(this.pos_target_y);
}
break;
case "right-up":
if(getX() < this.pos_target_x){
this.x += velocity_x;
}else{
setX(this.pos_target_x);
}
if(getY() > this.pos_target_y){
this.y -= velocity_y;
}else{
setY(this.pos_target_y);
}
break;
case "right-down":
if(getX() < this.pos_target_x){
this.x += velocity_x;
}else{
setX(this.pos_target_x);
}
if(getY() < this.pos_target_y){
this.y += velocity_y;
}else{
setY(this.pos_target_y);
}
break;
case "idle":
break;
}
}
/**
* Determines the Direction
*/
private function determineDirection():void {
if( getX() as int == pos_target_x && getY() as int == pos_target_y){//Idle
this._direction = "idle";
}else{//No Idle
if( getX() != pos_target_x && getY() == pos_target_y ){//Linear X
if(getX() < pos_target_x){//right
this._direction = "right";
}else if(getX() > pos_target_x){//left
this._direction = "left";
}
}else if( getX() == pos_target_x && getY() != pos_target_y ){//Linear Y
if(getY() < pos_target_y){//down
this._direction = "down";
}else if(getY() > pos_target_y){//up
this._direction = "up";
}
}else if(getX() != pos_target_x && getY() != pos_target_y ){//Diagonal
if(getX() < pos_target_x && getY() < pos_target_y){//Right Down
this._direction = "right-down";
}else if(getX() > pos_target_x && getY() > pos_target_y){//Left Up
this._direction = "left-up";
}else if(getX() > pos_target_x && getY() < pos_target_y){//Left Down
this._direction = "left-down";
}else if(getX() < pos_target_x && getY() > pos_target_y){//Right Up
this._direction = "right-up";
}
}
}
}
/**
* Determines when the velocity should be decreased.
*/
private function determineVelocityBreakpoint():void {
_mPointX = (this.pos_old_x + this.pos_target_x) / 2;
_mPointY = (this.pos_old_y + this.pos_target_y) / 2;
}
private function determineDistance():void {
//Distance for x, y combined
this.distance_point = Math.sqrt((getX() - this.pos_target_x) * (getX() - this.pos_target_x) +
(getY() - this.pos_target_y) * (getY() - this.pos_target_y))
this.distance_x = Math.sqrt((getX() - this.pos_target_x) * (getX() - this.pos_target_x));
this.distance_y = Math.sqrt((getY() - this.pos_target_y) * (getY() - this.pos_target_y));
}
/**
* Increases and decreased the velocity.
*/
private function determineVelocity():void {
switch(this._direction){
case "left":
if(getX() <= this._mPointX){
if(this.velocity_x > this.velocity_min){
this.velocity_x -= this.velocity_inc;
}
}else{
if(velocity_x < velocity_max){
this.velocity_x += this.velocity_inc;
}
}
break;
case "right":
if(getX() >= this._mPointX){
if(this.velocity_x > this.velocity_min){
this.velocity_x -= this.velocity_inc;
}
}else{
if(velocity_x < velocity_max){
this.velocity_x += this.velocity_inc;
}
}
break;
case "up":
if(getY() <= this._mPointY){
if(this.velocity_y > this.velocity_min){
this.velocity_y -= this.velocity_inc;
}
}else{
if(velocity_y < velocity_max){
this.velocity_y += this.velocity_inc;
}
}
break;
case "down":
if(getY() >= this._mPointY){
if(this.velocity_y > this.velocity_min){
this.velocity_y -= this.velocity_inc;
}
}else{
if(velocity_y < velocity_max){
this.velocity_y += this.velocity_inc;
}
}
break;
case "left-up":
if(getX() <= this._mPointX){
if(this.velocity_x > this.velocity_min){
this.velocity_x -= this.velocity_inc;
}
}else{
if(velocity_x < velocity_max){
this.velocity_x += this.velocity_inc;
}
}
if(getY() <= this._mPointY){
if(this.velocity_y > this.velocity_min){
this.velocity_y -= this.velocity_inc;
}
}else{
if(velocity_y < velocity_max){
this.velocity_y += this.velocity_inc;
}
}
break;
case "left-down":
if(getX() <= this._mPointX){
if(this.velocity_x > this.velocity_min){
this.velocity_x -= this.velocity_inc;
}
}else{
if(velocity_x < velocity_max){
this.velocity_x += this.velocity_inc;
}
}
if(getY() >= this._mPointY){
if(this.velocity_y > this.velocity_min){
this.velocity_y -= this.velocity_inc;
}
}else{
if(velocity_y < velocity_max){
this.velocity_y += this.velocity_inc;
}
}
break;
case "right-up":
if(getX() >= this._mPointX){
if(this.velocity_x > this.velocity_min){
this.velocity_x -= this.velocity_inc;
}
}else{
if(velocity_x < velocity_max){
this.velocity_x += this.velocity_inc;
}
}
if(getY() <= this._mPointY){
if(this.velocity_y > this.velocity_min){
this.velocity_y -= this.velocity_inc;
}
}else{
if(velocity_y < velocity_max){
this.velocity_y += this.velocity_inc;
}
}
break;
case "right-down":
if(getX() >= this._mPointX){
if(this.velocity_x > this.velocity_min){
this.velocity_x -= this.velocity_inc;
}
}else{
if(velocity_x < velocity_max){
this.velocity_x += this.velocity_inc;
}
}
if(getY() >= this._mPointY){
if(this.velocity_y > this.velocity_min){
this.velocity_y -= this.velocity_inc;
}
}else{
if(velocity_y < velocity_max){
this.velocity_y += this.velocity_inc;
}
}
break;
case "idle":
break;
}
}
/**
* Set the target position and start position
*/
public function setTargetPosition(target_x:int, target_y:int):void {
this.pos_target_x = target_x;
this.pos_target_y = target_y;
this.pos_old_x = getX();
this.pos_old_y = getY();
}