旋转物体面对另一个物体

时间:2011-06-28 01:51:29

标签: flash actionscript-3

目前我有一个功能,我的对象鱼将移动到食物我很难让它旋转到食物目前我的功能如下所示。如果食物在鱼的上方,我的鱼旋转为0面朝上,如果食物低于我的鱼,我会给它一个180度的旋转,使它面朝下,但旋转太突然,它不会给旋转食物带来美妙而逼真的效果。

如何旋转移动一段距离并同时旋转?因为它不能旋转到同一地点的食物,因为它不太现实。

public function moveToFood():void
        {   
            var foodTarget:Food = fishArray[fishArray.length - 1];
            trace("Popped food with position" + foodTarget.x + " " +foodTarget.y);
            var dx:Number = x - foodTarget.x;
            var dy:Number = y - foodTarget.y;
            if (foodTarget.y > this.y)
            {
                trace("Food below fish")
                rotation = 180;
                this.x -= dx / 15;
                this.y -= dy / 15;
            }else if (foodTarget.y < this.y)
            {
                trace("Food above fish")
                rotation = 0;
                this.x -= dx / 15;
                this.y -= dy / 15;
            }

        //removing food when both hit boxes hit
        if (hit.hitTestObject(foodTarget.hit))
            {
                foodIsDropped = false;
                foodTarget.removeSelf();
            }
        }

5 个答案:

答案 0 :(得分:1)

虽然上一个答案(关于Tweener)是一个可能的解决方案,但我认为这有点过分。

你已经有一种触发移动鱼的方法。你正在用x和y做一个 - =操作。那么为什么不用旋转来做同样的事情而不是立即改变呢?

public function moveToFood():void
{   
    var foodTarget:Food = fishArray[fishArray.length - 1];
    trace("Popped food with position" + foodTarget.x + " " +foodTarget.y);

    var targetRotation:Number = 0;
    if (foodTarget.y > y)
    {
        trace("Food below fish")
        targetRotation = 180;
    } else if (foodTarget.y < y)
    {
        trace("Food above fish")
        targetRotation = 0;
    }

    var dx:Number = x - foodTarget.x;
    var dy:Number = y - foodTarget.y;
    x -= dx / 15;
    y -= dy / 15;

    // *** update rotation ***
    rotation += (targetRotation-rotation)*.2;

    //removing food when both hit boxes hit
    if (hit.hitTestObject(foodTarget.hit))
        {
            foodIsDropped = false;
            foodTarget.removeSelf();
        }
    }
}

答案 1 :(得分:1)

......我刚刚针对每种可能的情况强制执行了公式。一堆如果上面的意思就是:

 if there is need to turn
    if we are now in + arc
        if target in - arc
            if target is lefter
                if difference is more than turnrate
                    turn left
                else
                    align
                end
            else //target is righter
                if difference is more than turnrate
                    turn right
                else
                    align
                end
            end
        else //target is in + arc
            if target is lefter or opposite
                if difference is more than turnrate
                    turn left
                else
                    align
                end
            else //target is righter
                if difference is more than turnrate
                    turn right
                else
                    align
                end
            end
        end
    else //same thing as above but for us being in - arc
    ...

答案 2 :(得分:0)

你可以使用补间引擎。

我建议您使用Tweener而不是标准Flash Tween类。与Tweener相比,fl.transitions.Tween类有点荒谬,如果您不使用Flash Professional IDE,甚至可能无法访问它。您可以查看其他几种补间引擎,但其中一些可以带许可费(IE:TweenLite

所以,如果您使用的是Tweener,您只需导入一些类:

import caurina.transitions.Equations;
import caurina.transitions.Tweener;

然后补间旋转,如下所示:

trace("Food below fish")
Tweener.addTween(this, {time: 0.25, transition: Equations.easeInOutCubic, rotation: 180});

通过Tweener文档阅读(它真的很短)。如果你之前没有听说过,你可能会最终使用它。

答案 3 :(得分:0)

我已将以下代码用于我的Java应用程序。这里的atan2(y,x)函数返回-PI和PI之间的角度。请注意,该函数很可能将Y作为其第一个参数,然后才是X.算法的X和Y是目标和对象位置之间的差异,在您的情况下分别是食物和鱼。简单的数学。只值得注意的是0角是向右,+角向上和向左,而 - 角向下和向左,看看这个图像:http://iepro.files.wordpress.com/2009/12/atan2.jpg?w=280&h=283 或这个 http://www.mathworks.com/help/techdoc/ref/math_a20.gif (论坛不允许我发布图片)

float heading;
float targetHeading = atan2(target.y - this.y, target.x - this.x);

...

if(this.heading != this.targetHeading){
    if(this.heading <=0){ //heading in minus
        if(this.targetHeading > -PI && this.targetHeading <=0){ //target in minus
            if(this.targetHeading < this.heading){  // both in minus and target is lefter
                if(this.heading - this.targetHeading > this.mManeuverSpeed){
                    this.turnLeft();
        //          System.out.println("SHIP: A");
                }else{
                    this.resetHeading();
                }
            }else{                                  // both in minus and target is righter
                if(this.targetHeading - this.heading > this.mManeuverSpeed){
                    this.turnRight();
        //          System.out.println("SHIP: B");
                }else{
                    this.resetHeading();
                }
            }
        }else{                                                  //target in plus
            if(this.heading + PI <= this.targetHeading){            //target in plus and is lefter or opposite
                if(PI + this.heading + (PI - this.targetHeading) > this.mManeuverSpeed){
                    this.turnLeft();
        //          System.out.println("SHIP: C "  + this.heading + " > " + this.targetHeading);
                }else{
                    this.resetHeading();
                }
            }else{                                              //target in plus and is righter
                if(this.targetHeading - this.heading > this.mManeuverSpeed){
                    this.turnRight();
        //          System.out.println("SHIP: D");
                }else{
                    this.resetHeading();
                }
            }
        }
    }else{                                  //heading in plus
        if(this.targetHeading > -PI && this.targetHeading <=0){ //target in minus
            if(this.heading - this.targetHeading < PI){     //if target is in minus and lefter
                if(this.heading - this.targetHeading > this.mManeuverSpeed){
                    this.turnLeft();
        //          System.out.println("SHIP: E");
                }else{
                    this.resetHeading();
                }
            }else{
                if(PI + this.targetHeading + (PI - this.heading) > this.mManeuverSpeed){
                    this.turnRight();
        //          System.out.println("SHIP: F");
                }else{
                    this.resetHeading();
                }
            }
        }else{                                              //if target in plus
            if(this.heading <= this.targetHeading){
                if(this.targetHeading - this.heading > this.mManeuverSpeed){
                    this.turnRight();
        //          System.out.println("SHIP: G " + this.heading + " < " + this.targetHeading);
                }else{
                    this.resetHeading();
                }
            }else{
                if(this.heading - this.targetHeading > this.mManeuverSpeed){
                    this.turnLeft();
        //          System.out.println("SHIP: H " + this.heading);
                }else{
                    this.resetHeading();
                }
            }
        }
    }
}//heading != targetHeading

void turnLeft(){
    this.heading -= this.mManeuverSpeed;
}

void turnRight(){
    this.heading += this.mManeuverSpeed;
}

void resetHeading(){
    this.heading = this.targetHeading;
}

答案 4 :(得分:0)

不过,还有一种更简单的方法。你可以为你制作“传感器”。就像这样放置它们:

     \  o
>--fish--)
     /  o

在那里你看到o标志。然后计算每个人到目标的距离。如果左边距离较小,则向左转,如果右边距离较小 - 向右转。很简单,我在童年时就用过这个。但是,由于对单个对象使用两个dists,它比其他“iffed”方法慢得多。并且不要忘记在两个距离之间的差异小于DELTA时包含一个条件,你不要转鱼,但与目标对齐(角度= atan2(difx,dify))......