Как я могу переместить спрайт в направлении, в котором он находится?

11

Я использую Java / Slick 2D. Я пытаюсь использовать мышь, чтобы вращать спрайт, и клавиши со стрелками, чтобы переместить спрайт. Я могу заставить спрайт вращаться без проблем, но я не могу заставить его двигаться в том направлении, в котором он должен. Когда я нажимаю «вперед», спрайт не обязательно движется к мышке. На самом деле, он будет двигаться только к левой части экрана. Я уверен, что для этого должен быть какой-то стандартный код, так как многие игры используют этот стиль движения. Кто-нибудь может мне помочь с тем, что триг должен быть? Спасибо

РЕДАКТИРОВАТЬ: Вот код поворота (который делает что-то еще странное: /programming/12610320/why-is-my-image-rotating-off-center )

int mX = Mouse.getX();
        int mY = HEIGHT - Mouse.getY();
        int pX = sprite.x;
        int pY = sprite.y;
        int tempY, tempX;
        double mAng, pAng = sprite.angle;
        double angRotate=0;

        if(mX!=pX){
            mAng = Math.toDegrees(Math.atan2(mY - pY, mX - pX));
            if(mAng==0 && mX<=pX)
                mAng=180;
        }
        else{
            if(mY>pY)
                mAng=90;
            else
                mAng=270;
        }

        sprite.angle = mAng;
        sprite.image.setRotation((float) mAng); 

И код движения. Я могу двигаться только к левой стороне экрана ...

double ang = sprite.angle;
            Input input = gc.getInput();

            if(input.isKeyDown(sprite.up)){
                sprite.x += Math.cos(ang)*sprite.moveSpeed;
                sprite.y += Math.sin(ang)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.down)){
                sprite.x += -1*Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y += -1*Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.left)){
                sprite.x -= Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y += Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.right)){
                sprite.x += Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y -= Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }
rphello101
источник
Какой смысл кода, который вы добавили? Это новая проблема? Если это новая проблема, пожалуйста, откройте новый вопрос. Пожалуйста, обновляйте этот вопрос только информацией, касающейся перемещения спрайта в направлении, в котором он находится.
MichaelHouse
Нет, именно код, который я использовал, вызвал проблему. Смотрите комментарии ниже. Кто-то просил об этом.
rphello101
Я не вижу, где вы рассчитываете sprite.movespeed?
AturSams
MoveSeded является константой, в этом случае установлен на .3
rphello101

Ответы:

14

Вы хотите получить вектор на основе вашей текущей скорости и курса. Затем используйте этот вектор, чтобы увеличить вашу позицию.

//first get the direction the entity is pointed
direction.x = (float) Math.cos(Math.toRadians(rotation));
direction.y = (float) Math.sin(Math.toRadians(rotation));
if (direction.length() > 0) {
    direction = direction.normalise();
}
//Then scale it by the current speed to get the velocity
velocity.x = direction.x * speed;
velocity.y = direction.y * speed;

Итак, теперь вы знаете свою скорость на основе вашего вращения. Вы можете обновить свою позицию с этой информацией.

//Update the position based on our current speed
//This is basic s = vt physics
position.x += velocity.x * timeElapsed;
position.y += velocity.y * timeElapsed;
MichaelHouse
источник
Для (небрежного) класса, который содержит все это, вы можете увидеть запись Ludum Dare 21, которую я собрал здесь: bitbucket.org/byte56/ld21/src/af3dfc2c4c48/src/Byte56_LD21/…
MichaelHouse
Спасибо. После нескольких модификаций это сработало. У меня есть еще один вопрос к вам, хотя, если вы случайно прочитаете это: заставить спрайт двигаться назад - это просто - = того, что у вас здесь есть. Как мне заставить его двигаться влево или вправо?
rphello101
@ rphello101 Хороший вопрос, вы должны задать новый вопрос. Больше людей получат пользу, и вы можете получить лучший ответ, чем тот, который у меня есть.
MichaelHouse
3

Вы получаете положение мыши

mouseX = ... 
mouseY = ...

Вы получаете позицию спрайта

spriteX = ...
spriteY = ...

Вы находите угол

angle = Math.atan2(mouseY - spriteY, mouseX - spriteX);

Ваше движение будет:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;
AturSams
источник
Совет: создайте таблицу (массив) для cos и sin с предварительно вычисленными значениями. так что вы можете просто сделать cosTable [(int) angle] * скорость * время и sinTable [(int) angle] * speed * time Это не так точно. Но вы получаете свои ценности намного быстрее.
Сидар
Это сместит спрайт в сторону мыши, но это не то же самое, что направление, в котором направлен спрайт. Спрайт все еще может поворачиваться лицом к мыши, если скорость вращения ограничена или по какой-либо другой причине. По сути, вы отвечаете не на тот вопрос.
MichaelHouse
@ Byte56 он сказал: «Когда я нажимаю« вперед », спрайт не обязательно движется к мышке». Я думаю, это то, о чем он спрашивал. Вы могли бы быть правы, хотя.
AturSams
Это, конечно, двусмысленно. Я просто по умолчанию назвал вопрос в этом случае. Не поймите меня неправильно, ваш ответ хороший. Я думаю, мы узнаем, чего хотел ОП, когда / если они вернутся.
MichaelHouse
2
@ Сидар Это было бы преждевременной оптимизацией. Создание таблиц sin / cos без определения операций sin / cos как узкого места является пустой тратой времени.
Bummzack