AS3/Flash Develop - Radial Gravity (симуляция персонажа на планете)

Я пытаюсь создать программу, в которой форма персонажа будет постоянно приближаться к центру формы планеты. Я воспользовался предыдущим советом по использованию физических уравнений для получения желаемого эффекта, но я думаю, что мне не хватает некоторых, и поэтому это не работает (я использую только v ^ 2 = u ^ 2 + 2as). Я слишком усложняю вещи? Все, что мне нужно, это чтобы объект игрока постоянно тянулся к центру объекта планеты; не будет необходимости, чтобы другие планетарные объекты вступали в игру и влияли на гравитацию игрока.

edit: Чтобы уточнить, мой вопрос должен был быть «где я ошибся?». С тех пор я решил проблему с ответами, опубликованными ниже, которые присутствовали, потому что я не собирался пытаться достичь того, чего хотел, правильным путем. Я не рассчитал фактическое направление движения, как ожидалось, и поэтому персонаж не мог двигаться в ожидаемом направлении.

Вот мой Main.as:

package
{
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.Event;
import Math
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.*;

/**
 * ...
 * @author Me
 */
public class Main extends Sprite 
{
    public var planet1:Planet;
    public var character1:Character;
    public var initialXVelocity:Number = 0;
    public var initialYVelocity:Number = 0;
    public var finalXVelocity:Number;
    public var finalYVelocity:Number;
    public const gravitationalAcceleration:Number = 3;
    public var xDistance:Number;
    public var yDistance:Number;



    public function Main() 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void 
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // entry point
        planet1 = new Planet;
        character1 = new Character;

        //place entites in position to test note: planet 1 is 100*100 pixels, character 1 is 10*10 pixels
        planet1.x = 350;
        planet1.y = 250;
        character1.y = 100; //295
        character1.x = 396; //395
        addChild(planet1);
        addChild(character1);

        //Make sure character has gravity applied constantly
        setInterval(playerMove, 1000);

    }

    public function playerMove():void
    {
        //Calculate the distance between the character and the planet in terms of x and y coordinate
        xDistance = (character1.x + 5) - (planet1.x + 50);
        yDistance = (character1.y + 5) - (planet1.y + 50);

        //Make sure this distance is a positive value
        if (xDistance < 0) {
            xDistance = -xDistance;
        }

        if (yDistance < 0) {
            yDistance = -yDistance;
        }

        //Calculate velocity using physics equation v^2=(u^2)+2as
        finalXVelocity = Math.sqrt((initialXVelocity * initialXVelocity) + (2 * gravitationalAcceleration) * xDistance);
        finalYVelocity = Math.sqrt((initialYVelocity * initialYVelocity) + (2 * gravitationalAcceleration) * yDistance);
        /*trace(initialXVelocity);
        trace(gravitationalAcceleration);
        trace(xDistance);
        trace(finalXVelocity);
        trace(initialYVelocity);
        trace(gravitationalAcceleration);
        trace(yDistance);
        trace(finalYVelocity);*/

        //Make sure the character is moving towards the centre of the planet at all times by reversing the appropriate velocity once it passes the axis of the centre of the planet
        if (planet1.x < character1.x) {
            finalXVelocity = -finalXVelocity;
        }

        if (planet1.y < character1.y) {
            finalYVelocity = -finalYVelocity;
        }

        //Update the current velocity before new velocity is calculated
        initialXVelocity = finalXVelocity;
        initialYVelocity = finalYVelocity;

        //Send the character into the correct direction
        character1.x += finalXVelocity;
        character1.y += finalYVelocity;
    }

}

}

person Denver Thomas    schedule 04.02.2016    source источник
comment
Какой вопрос? Что вы пробовали? Не работает не вопрос. Вы отлаживали свой код? Какие значения имели переменные при использовании отладчика? Какие значения вы ожидали?   -  person null    schedule 04.02.2016


Ответы (1)


Гравитацию обычно можно описать как константу ускорения:

const gravity:Number = 3;

С помощью чего-то вроде сайдскроллера вы можете просто добавлять гравитацию к скорости по оси y на каждом такте:

vy += gravity;

В вашем случае это действительно то же самое, за исключением того, что гравитация не добавляется просто к вектору y, а добавляется к x и y в зависимости от направления к центру планеты, как если бы вы постоянно прилагали тягу к центру планеты. Итак, все, что вам нужно, это найти угол между игроком и центром планеты:

var angle:Number = Math.atan2(planet.y - player.y, planet.x - player.x);

А по углу можно найти вектор гравитации:

var gravityX:Number = Math.cos(angle) * gravity;
var gravityY:Number = Math.sin(angle) * gravity;

И просто добавьте это к вектору вашего игрока:

vx += gravityX;
vy += gravityY;

Это заставит игрока постоянно тянуться к центру планеты. Конечно, без какого-либо столкновения с планетой он будет бесконечно вращаться вокруг центра планеты.

person Aaron Beall    schedule 04.02.2016