java - java - 如何修复Java一次听多个键?
问题描述
我和我的伙伴正在尝试为我们的计算机科学期末项目创建游戏 Pong。我们创建了一个参考代码,其中可以上下控制 2 个立方体,它工作正常。尝试同时控制两个立方体时会出现问题(一次只能移动 1 个立方体)。我们想让两个立方体同时移动。
我们想说:
yPos - is the y position of the black cube
xPos - is the x position of the black cube
xPos2 - is the x position of the blue cube
YPos2 - is the y position of the blue cube
键:
A - Go up for black cube
Z - Go down for black cube
K - Go up for blue cube
M - go down for blue cube
我们尝试过使用更复杂的版本,它使用了 j-label 动画。我们想如何通过图形功能制作我们的乒乓球游戏。但我们不明白:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class PongHelpNeed extends JFrame implements KeyListener
{
// booleans to tell which key is pressed
boolean upKey;
boolean downKey;
boolean upKey2;
boolean downKey2;
// the position variables
int yPos;
int xPos;
int xPos2;
int yPos2;
public PongHelpNeed ()
{
//create window
super ("Controller");
setSize (660, 700);
// set keys to false and original positions
upKey = false;
downKey = false;
upKey2 = false;
downKey2 = false;
xPos = 100;
yPos = 350;
xPos2 = 500;
yPos2 = 350;
// add the frame as a listener to your keys
addKeyListener (this);
// Show the frame
setVisible(true);
}
//needs to be here because the class implements KeyListener
public void keyTyped (KeyEvent e)
{
System.out.println (e.getKeyCode () + " Typed");
}
//needs to be here because the class implements KeyListener
public void keyPressed (KeyEvent e) {
//check if keys a,z or k,m are pressed
if (e.getKeyCode () == KeyEvent.VK_A)
{
upKey = true;
}
else if (e.getKeyCode () == KeyEvent.VK_Z)
{
downKey = true;
}
else if (e.getKeyCode () == KeyEvent.VK_K)
{
upKey2 = true;
}
else if (e.getKeyCode () == KeyEvent.VK_M)
{
downKey2 = true;
}
//repaint the window everytime you press a key
repaint ();
}
//needs to be here because the class implements KeyListener
public void keyReleased (KeyEvent e)
{
System.out.println (e.getKeyCode () + " Released");
}
//paints the pictures
public void paint (Graphics g)
{
//set background
g.setColor(Color.WHITE);
g.fillRect(0, 0, 660, 700);
//cube 1
g.setColor(Color.BLACK);
g.fillRect(xPos,yPos,50, 50);
//draw cube 2
g.setColor(Color.BLUE);
g.fillRect(xPos2,yPos2, 50, 50);
//if keys are pressed move the cubes accordingly up or down
if (upKey == true)
{
yPos = yPos - 15;
upKey = false;
}
else if (downKey == true)
{
yPos = yPos + 15;
downKey = false;
}
else if (downKey2 == true){
yPos2 = yPos2 + 15;
downKey2 = false;
}
else if (upKey2 == true) {
yPos2 = yPos2 - 15;
upKey2 = false;
}
}
public static void main (String[] args)
{
new PongHelpNeed ();
}
}
我们的预期结果是我们试图同时移动两个立方体。因此,当我们按下A
键和K
键时,黑色方块应该移动,蓝色方块应该移动。
解决方案
调用repaint()
不会paint
立即触发对 的调用,因此可能会在keyPressed
之前触发两次(或更多)paint
。
在您的paint
方法中,您正在检查 if-else 中的键,这意味着如果其中一个标志为真,则不检查其余标志。你也有一个竞争条件,他们keyPressed
正在争夺paint
旗帜。此外,如果您多次快速按下一个键,您将丢失第一次处理的事件和下一次重绘之间的所有额外按键。
而不是在内部进行移动paint
,您应该在keyPressed
处理程序中进行。不要将标志设置为 eg upKey = true;
,而是直接执行操作:yPos = yPos - 15;
. 然后该paint
方法将刷新视图以反映当前(更新)状态。
推荐阅读
- android - 可以在同一个应用程序中使用多个离子版本
- ajax - MVC 与 AJAX 删除表格行
- docker - 在 docker-compose 中为特定服务添加 cron 作业(计划任务)的最佳方法是什么
- ios - 带有大文本问题的 UICollection 视图单元格
- java - 如何使用 Log4j 编辑和打印 webelement 的规范?
- javascript - 图像在 Chrome 选项卡上加载正常,但在 React 代码中返回 403
- authentication - 使用 vert.x 在微服务架构中实现身份验证的更好方法
- input - 用户在 jogl 中按下键“0”我该怎么做?
- android - 从 firebase 检索用户 ID 下的数据
- ruby - 将字符串数组分类为关闭正则表达式