- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在制作一款游戏,遇到了按键重影问题(程序一次仅检测到一个按键,因此玩家无法沿对角线走)。我正在看这个教程:https://www.youtube.com/watch?v=5UaEUrbpDPE我按照他们所说的一切进行操作,但它仍然一次只能检测到一个键。
主要:
public class Main extends JApplet implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
public static int width = 900;
public static int height = 600;
public static int fps = 60;
public static Main instance;
public static Ailoid ailoid = new Ailoid();
public static Player player = new Player();
// Initialize
public void init() {
setSize(width, height);
setBackground(Color.white);
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
requestFocus();
instance = this;
ailoid.setLocation(new Location(100, 100));
AlienManager.registerAlien(ailoid);
player.setLocation(new Location(400, 400));
}
// Paint graphics
public void paint(Graphics g) {
super.paint(g);
paintComponent(g);
}
public void paintComponent(Graphics g) {
for (Alien alien : AlienManager.getAliens()) {
Location loc = alien.getLocation();
g.setColor(Color.GREEN);
g.fillRect(loc.getX(), loc.getY(), 10, 25);
}
g.setColor(Color.BLUE);
Location loc = Main.player.getLocation();
g.fillRect(loc.getX(), loc.getY(), 10, 25);
}
// Thread start
@Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
// Thread stop
@Override
public void destroy() {
}
// Thread run
@Override
public void run() {
Thread thread = new Thread(this);
while (thread != null) {
Updater.run();
repaint();
try {
// 1000 divided by fps to get frames per second
Thread.sleep(1000 / fps);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void keyPressed(KeyEvent evt) {
if (!KeysDown.get().contains(evt.getKeyCode()))
KeysDown.add(new Integer(evt.getKeyCode()));
KeyPress.run(evt);
}
@Override
public void keyReleased(KeyEvent evt) {
KeysDown.remove(new Integer(evt.getKeyCode()));
}
@Override
public void keyTyped(KeyEvent evt) {
}
}
按下按键:
public class KeysDown {
private static ArrayList<Integer> keysDown = new ArrayList<Integer>();
public static ArrayList<Integer> get() {
return keysDown;
}
public static void add(Integer key) {
keysDown.add(key);
}
public static void remove(Integer key) {
keysDown.remove(key);
}
}
按键:
public class KeyPress {
public static void run(KeyEvent evt) {
if (KeysDown.get().contains(KeyEvent.VK_RIGHT)) {
Main.player.moveRight();
}
else if (KeysDown.get().contains(KeyEvent.VK_LEFT)) {
Main.player.moveLeft();
}
else if (KeysDown.get().contains(KeyEvent.VK_DOWN)) {
Main.player.moveDown();
}
else if (KeysDown.get().contains(KeyEvent.VK_UP)) {
Main.player.moveUp();
}
}
}
谢谢!
最佳答案
正如我在之前的评论中提到的:
Direction
的枚举。将方向的想法封装在屏幕上。Boolean.FALSE
放在一起在 Map<Direction, Boolean>
叫dirMap
.true
,释放后,Direction.DOWN 关联值将改回 false
.例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.EnumMap;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class AnimateExample extends JPanel {
public static final String DUKE_IMG_PATH = // https://duke.kenai.com/iconSized/duke.gif
"https://duke.kenai.com/iconSized/duke4.gif";
private static final int PREF_W = 800;
private static final int PREF_H = 800;
private static final int TIMER_DELAY = 20;
private static final String KEY_DOWN = "key down";
private static final String KEY_RELEASE = "key release";
public static final int TRANSLATE_SCALE = 3;
private static final String BACKGROUND_STRING = "Use Arrow Keys to Move Image";
private static final Font BG_STRING_FONT = new Font(Font.SANS_SERIF,
Font.BOLD, 32);
private EnumMap<Direction, Boolean> dirMap =
new EnumMap<AnimateExample.Direction, Boolean>(Direction.class);
private BufferedImage image = null;
private int imgX = 0;
private int imgY = 0;
private int bgStringX;
private int bgStringY;
public AnimateExample() {
for (Direction dir : Direction.values()) {
dirMap.put(dir, Boolean.FALSE);
}
try {
URL imgUrl = new URL(DUKE_IMG_PATH);
image = ImageIO.read(imgUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
new Timer(TIMER_DELAY, new TimerListener()).start();
// here we set up our key bindings
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
for (final Direction dir : Direction.values()) {
// for the key down key stroke
KeyStroke keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0,
false);
inputMap.put(keyStroke, dir.name() + KEY_DOWN);
actionMap.put(dir.name() + KEY_DOWN, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
dirMap.put(dir, true);
}
});
// for the key release key stroke
keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0, true);
inputMap.put(keyStroke, dir.name() + KEY_RELEASE);
actionMap.put(dir.name() + KEY_RELEASE, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
dirMap.put(dir, false);
}
});
}
FontMetrics fontMetrics = getFontMetrics(BG_STRING_FONT);
int w = fontMetrics.stringWidth(BACKGROUND_STRING);
int h = fontMetrics.getHeight();
bgStringX = (PREF_W - w) / 2;
bgStringY = (PREF_H - h) / 2;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setFont(BG_STRING_FONT);
g.setColor(Color.LIGHT_GRAY);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(BACKGROUND_STRING, bgStringX, bgStringY);
if (image != null) {
g.drawImage(image, imgX, imgY, this);
}
}
private class TimerListener implements ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e) {
for (Direction dir : Direction.values()) {
if (dirMap.get(dir)) {
imgX += dir.getX() * TRANSLATE_SCALE;
imgY += dir.getY() * TRANSLATE_SCALE;
}
}
repaint();
};
}
enum Direction {
Up(KeyEvent.VK_UP, 0, -1), Down(KeyEvent.VK_DOWN, 0, 1), Left(
KeyEvent.VK_LEFT, -1, 0), Right(KeyEvent.VK_RIGHT, 1, 0);
private int keyCode;
private int x;
private int y;
private Direction(int keyCode, int x, int y) {
this.keyCode = keyCode;
this.x = x;
this.y = y;
}
public int getKeyCode() {
return keyCode;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
private static void createAndShowGui() {
AnimateExample mainPanel = new AnimateExample();
JFrame frame = new JFrame("Animate Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
有关按键绑定(bind)的更多信息,请查看信息丰富的教程 here .
关于java - 关键重影问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24717104/
如何在拖动图像时去除重影。我们已经尝试过代码,它可以在 Firefox 和 chrome 中运行,但不能在 Safari 中运行。请任何人帮助我的代码有什么错误。 https://jsfiddle.n
我做了一个小程序: 将 Canvas 内的鼠标光标更改为黑色方 block 给黑色方 block 留下一条漂亮的轨迹,随着时间的推移逐渐消失(程序的要点) 代码如下: var canvas = doc
我使用 CALayer 的自定义扩展绘制为可滚动图形,并在 [MyCustomCALayer drawInContext] 中调用了一堆 CGContextAddCurveToPoint。 我实际上并
好吧,我刚刚开始学习java(我通常用Objective-C 编程)。我的第一款游戏是一款类似于神奇宝贝的游戏,但是,它显然要简化得多...... 我遇到的麻烦是我找不到方法来阻止 2 个 Sprit
我一直在尝试设置一个 javascript 游戏循环,但我遇到了两个问题。我发现在 chrome 中,当我失去浏览器窗口的焦点,然后单击返回我正在运行的动画时,会发生这种奇怪的“ catch ”事情,
在我将其切换为使用 DrawerLayout 内的 fragment 之前,我的布局工作正常。之后,主视图中的 ListView 在滚动时会重影列表的副本。 ListView 内容滚动,但第一页的副本
我是一名优秀的程序员,十分优秀!