移动抛物线弧时基于距离XY的二维变速

时间:2015-10-23 11:26:12

标签: actionscript-3 math 2d game-physics

我想要实现的是实体以抛物线形式移动,在你问之前,这与引力无关。

我给实体一个它应该移动到的目标位置,但不是直线,它应该以抛物线曲线移动到那个目标位置。

我将在下面给出一个例子:
example

无论起点或目标位置无关紧要,我只想分别为x和y计算合适的速度。以便实体的x,y在同一时间到达目标位置。 我的实体可以根据targetXY在8个方向上移动。

我所做的是在startPositionXY和targetPositionXY之间分别计算每个x,y I的中间点。我将速度增加到中间点,在中间点之后我减小速度。但是实体x和y并没有同时到达目标,而是x或y总是先到达另一个目标,这取决于它移动的方向。

这是我到目前为止所拥有的。

    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();
    }

0 个答案:

没有答案