вращение объекта лицом к другому объекту - PullRequest
2 голосов
/ 28 июня 2011

В настоящее время у меня есть функция, в которой моя объектная рыба перемещается в корм. У меня возникают проблемы с тем, чтобы заставить ее правильно вращаться в корм. В настоящее время моя функция такая же, как и ниже. Если корм находится над рыбой, мой оборот рыбы равен 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 ]

1 голос
/ 01 июля 2011

... я только что подстроил формулу для каждой возможной ситуации. куча если выше означает только то, что:

 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
    ...
1 голос
/ 28 июня 2011

Хотя предыдущий ответ (о Tweener) является возможным решением, я думаю, что это немного излишне.

У вас уже есть метод, который срабатывает для перемещения вашей рыбы. И вы делаете - = операция с х и у там. Так почему бы не сделать то же самое с вращением, а не менять его мгновенно?

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();
        }
    }
}
0 голосов
/ 01 июля 2011

Кстати, есть и более простой способ. Вы можете сделать «датчики» для вашей рыбы. просто разместите их так:

     \  o
>--fish--)
     /  o

там, где вы видите знаки o. затем посчитайте расстояние от каждого из них до цели. если левое расстояние меньше, поверните налево, если правое меньше - поверните направо. очень просто, я использовал это в детстве. однако из-за использования двух дисков для одного объекта он работает намного медленнее, чем другой метод «iffed». И не забудьте включить условие, когда разница между этими двумя расстояниями меньше, чем DELTA, рыба, но выровняйте ее с целью (angle = atan2 (difx, dify)) ...

0 голосов
/ 29 июня 2011

Я использовал код ниже для моего приложения 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;
}
0 голосов
/ 28 июня 2011

вы можете использовать анимацию движения.

я бы порекомендовал вам использовать Tweener вместо стандартного Flash Tween класса.Класс fl.transitions.Tween довольно смешен по сравнению с Tweener, и вы можете даже не иметь к нему доступа, если не используете 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 (она действительно короткая).вы, вероятно, в конечном итоге будете часто его использовать, если не слышали об этом раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...