Как переместить видимое изображение по диагонали?
Я пытался выяснить, как заставить видимое изображение двигаться по диагонали в окне апплета.
Если вы нажимаете вверх, вниз, влево или вправо, изображение (рисунок) перемещается соответствующим образом, однако, если вы пытаетесь нажать две клавиши одновременно (например, вверх и вправо одновременно), изображение перемещается только в направлении, которое вы нажали второе (даже если вы нажмете клавиши одновременно, микроскопическая задержка все еще сохраняется).
Возможно, есть простой способ исправить это, о котором я просто не знаю, или, возможно, кто-то нашел обходной путь... Я ценю любую помощь или совет, который можно дать.
Спасибо
Класс героя (этот класс определяет, что такое "герой"; в данном случае это простой пиксельный человек и что он может делать)
import objectdraw.*;
import java.awt.*;
public class Hero extends ActiveObject {
private DrawingCanvas canvas;
private VisibleImage player;
public Hero(Location initLocation, Image playerPic, DrawingCanvas aCanvas) {
canvas = aCanvas;
player = new VisibleImage(playerPic, canvas.getWidth()/3,
canvas.getWidth()/3, canvas);
start();
}
public void run()
{
}
public void move(double dx, double dy)
{
player.move(dx, dy);
}
}
Класс HeroGame (этот класс создает "Героя" и указывает местоположение, а также какие ключи используются для его перемещения)
import objectdraw.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HeroGame extends WindowController implements KeyListener {
private Hero theHero;
private Image playerPic;
private Location initLocation;
public void begin() {
playerPic = getImage("player.gif");
canvas.addKeyListener ( this );
this.addKeyListener ( this );
requestFocusInWindow();
theHero = new Hero(initLocation, playerPic, canvas);
}
public void keyTyped( KeyEvent e ) { }
public void keyReleased( KeyEvent e ) { }
public void keyPressed( KeyEvent e ) {
if ( e.getKeyCode() == KeyEvent.VK_UP ) {
theHero.move(0,-5);
}
else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
theHero.move(0,5);
}
else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
theHero.move(-5,0);
}
else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
theHero.move(5,0);
}
}
}
Спасибо еще раз, что нашли время, чтобы прочитать это и, надеюсь, помочь.
5 ответов
Это довольно обычная ситуация в играх, которые принимают ввод с клавиатуры. Проблема в том, что ваша игра должна воздействовать на все клавиши, которые в данный момент нажаты, насколько это касается игры (то есть все клавиши, для которых еще не было инициировано событие KEY_RELEASE).
KeyListener
будет уведомлять вас только о последней нажатой клавише (и будет продолжать уведомлять вас о той же клавише, если вы удерживаете ее нажатой), поэтому вам нужно самостоятельно отслеживать состояние остальных клавиш.
Чтобы получить представление о том, как это сделать, выполните поиск опроса клавиатуры ( здесь пример), популярного метода, при котором вы не реагируете сразу на вход игрока, а скорее сохраняете нажатия клавиш в очереди, а затем опрашиваете эту очередь через равные промежутки времени. (т.е. в вашем игровом цикле), чтобы решить, какие клавиши нажаты или нет, и действовать соответственно.
надеюсь, это поможет
Я бы посоветовал вам использовать Swing (JApplet) и привязки клавиш. См. Раздел " Движение с помощью клавиатуры", где описаны проблемы с использованием KeyListener, а также решение для одновременного нажатия нескольких клавиш.
Менять
if ( e.getKeyCode() == KeyEvent.VK_UP ) {
theHero.move(0,-5);
}
else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
theHero.move(0,5);
}
else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
theHero.move(-5,0);
}
else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
theHero.move(5,0);
}
в
if ( e.getKeyCode() == KeyEvent.VK_UP ) {
theHero.move(0,-5);
}
if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
theHero.move(0,5);
}
if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
theHero.move(-5,0);
}
if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
theHero.move(5,0);
}
И это должно реагировать на оба ключа.
Вместо вашего if-else
Заявление для ключа, вы должны использовать серию if
заявления.
Вместо установки hero
Направление для обоих x
а также y
движение в этих if
заявления, вы должны только обновлять соответствующие delta
Для (очень упрощенного) примера...
if (up) yDelta = -5;
if (down) yDelta = 5;
if (left) xDelta = -5;
if (right) xDelta = 5;
hero.move(xDelta, yDelta);
Я тоже согласен с camickr
Что вам нужно сделать, это получить доступ к базовому классу AffineTransform изображения и установить правильные методы перевода. Это позволит вам в любом случае переместить изображение (на любое количество градусов в любом направлении) одним нажатием клавиши (которую вы связываете с этим вызовом).
Читайте об этом: http://docs.oracle.com/javase/7/docs/api/java/awt/geom/AffineTransform.html