アニメーションを駆動するための「ゲームループ」を使用し、それを移動させます。これはおそらくSwingまたはAWT GUIに見えるので、スイングタイマーを使用するのが最善の方法です - tutorialをご覧ください。要点は、TimerのActionListener内で、ヘビの位置をインクリメントし、キーの押下の状態に応じて方向を変更することです。
私は{RIGHT、UP、DOWN LEFT}の方向性を示すために、列挙型を使用します。
public enum Direction {
UP,
DOWN,
LEFT,
RIGHT
}
、その後Map<Direction, Boolean>
頭にどの方向を示すために、:
他の場所
private Map<Direction, Boolean> dirMap = new EnumMap<>(Direction.class);
ますでしょうマップを初期化してすべての値がfalseになるようにします。
// initialize the map to all false
for (Direction dir : Direction.values()) {
dirMap.put(dir, false);
}
コード内のキープレスとリリースのリッスンのためのマップ内の項目は、たとえば上キーが押されたときにmap.put(Direction.UP, true)
と呼び出し、同様に解放されたときはmap.put(Direction.UP, false)
と呼びます。他のキーと同じです。あなたのアプリケーションがSwingアプリケーションの場合は、KeyBindingsを使用し、KeyListenerは使用しません。リスナーでは、GUI上でrepaint()
と呼ぶことにします。
スイングタイマー内で、マップを繰り返して、マップの状態に基づいて方向を設定します。
クラスフィールド:ActionListenerの例
// within the Swing Timer's ActionListener
if (dirMap.get(Direction.UP)) {
directionY -= 1;
}
if (dirMap.get(Direction.DOWN)) {
directionY += 1;
}
if (dirMap.get(Direction.RIGHT)) {
directionX += 1;
}
if (dirMap.get(Direction.LEFT)) {
directionY -= 1;
}
// here multiply directionX and directionY by some scale factor and use to place new snake head
// then call repaint();
以内
private int spriteX = 0; // location of sprite
private int spriteY = 0;
private int directionX = 0; // direction sprite is heading
private int directionY = 0;
(ないヘビしかし、ボール - 私はあなたに蛇を残しておきます)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.*;
@SuppressWarnings("serial")
public class DirTest extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = PREF_W;
private static final int TIMER_DELAY = 40;
private static final Color SPRITE_COLOR = Color.RED;
private static final int SPRITE_W = 20;
private static final Color BG = Color.BLACK;
public static final int SCALE = 1;
private Map<Direction, Boolean> dirMap = new EnumMap<>(Direction.class);
private int spriteX = 0;
private int spriteY = 0;
private int directionX = 0;
private int directionY = 0;
private Timer gameLoopTimer = new Timer(TIMER_DELAY, new TimerListener());
public DirTest() {
setKeyBindings();
setBackground(BG);
// initialize map to all 0;
for (Direction dir : Direction.values()) {
dirMap.put(dir, false);
}
gameLoopTimer.start();
}
private void setKeyBindings() {
int condition = WHEN_IN_FOCUSED_WINDOW; // bind to keys if component in active window
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
setKeyBinding(inputMap, actionMap, KeyEvent.VK_UP, Direction.UP);
setKeyBinding(inputMap, actionMap, KeyEvent.VK_DOWN, Direction.DOWN);
setKeyBinding(inputMap, actionMap, KeyEvent.VK_LEFT, Direction.LEFT);
setKeyBinding(inputMap, actionMap, KeyEvent.VK_RIGHT, Direction.RIGHT);
}
private void setKeyBinding(InputMap inputMap, ActionMap actionMap, int keyCode, Direction dir) {
KeyStroke press = KeyStroke.getKeyStroke(keyCode, 0, false);
KeyStroke released = KeyStroke.getKeyStroke(keyCode, 0, true);
Action pressAction = new PressedAction(dir, true);
Action releasedAction = new PressedAction(dir, false);
inputMap.put(press, press.toString());
inputMap.put(released, released.toString());
actionMap.put(press.toString(), pressAction);
actionMap.put(released.toString(), releasedAction);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(SPRITE_COLOR);
g2.fillOval(spriteX, spriteY, SPRITE_W, SPRITE_W);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class PressedAction extends AbstractAction {
private boolean pressed;
private Direction dir;
public PressedAction(Direction dir, boolean pressed) {
this.dir = dir;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent e) {
dirMap.put(dir, pressed);
}
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
for (Entry<Direction, Boolean> entry : dirMap.entrySet()) {
if (entry.getValue()) {
directionX += entry.getKey().getX();
directionY += entry.getKey().getY();
}
}
spriteX += SCALE * directionX;
spriteY += SCALE * directionY;
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DirTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DirTest());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
enum Direction {
UP(0, -1),
DOWN(0, 1),
LEFT(-1, 0),
RIGHT(1, 0);
private int x;
private int y;
private Direction(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
中断されるまで動きをループするメソッドを呼び出しましたか? – DejaVuSansMono