gpt4 book ai didi

java - 如何防止我的 KeyEvent 重新绘制两个对象?

转载 作者:行者123 更新时间:2023-12-01 09:53:19 25 4
gpt4 key购买 nike

我正在开发一个简单的游戏,需要 1 名玩家(方 block )和一些在游戏区域内随机生成的敌人。我目前遇到一个问题,因为当我运行我的程序时,按任意箭头键不仅会重新绘制玩家的新位置,而且还会将所有敌人重新生成到新位置。

我已经检查了我的代码几次,但我仍然对为什么会发生这种情况感到困惑。任何帮助将不胜感激。

P.S. 我不是一个非常有经验的程序员,所以有些代码可能不太高效,有些东西可能不正确;除了手头的问题之外,请随时指出任何错误。谢谢!

主类

    public class Eat {

public static void main(String[] args) {

// Creating the main frame
JFrame main = new JFrame("Eat 'Em All - Version 1.0.2");
main.setSize(497, 599);
main.setLocationRelativeTo(null);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setResizable(false);

// Colours and borders
Border areaBorder = new LineBorder(Color.LIGHT_GRAY, 3);

// Creating main JPanel
JPanel area = new JPanel();
area.setLayout(new BoxLayout(area, BoxLayout.PAGE_AXIS));
area.setBackground(Color.WHITE);
main.setContentPane(area);

// Creating the drawing/image/player
DrawPlayer player = new DrawPlayer();
player.setPreferredSize(new Dimension(497, 539));
player.setOpaque(false);

// Enemies
DrawEnemy enemy = new DrawEnemy();
enemy.setPreferredSize(new Dimension(497, 539));
enemy.setBackground(Color.WHITE);

// Creating the control panel for buttons, etc
JPanel control = new JPanel();
control.setPreferredSize(new Dimension(497, 60));
control.setLayout(new GridLayout(1, 2, 0, 0));
control.setBorder(areaBorder);

JLabel welcome = new JLabel(" Welcome to Eat 'Em All |--| Press 'Start'");
JButton start = new JButton("Start");

// Adding it all to the frame
main.add(enemy);
enemy.add(player);
control.add(welcome);
control.add(start);
area.add(control);

// Adding keylistener and making button false
player.addKeyListener(player);
player.setFocusable(true);
start.setFocusable(false);
enemy.setFocusable(false);

// Bring frame to front and visible
main.toFront();
main.setVisible(true);

System.out.println(player.getWidth() / 2);
System.out.println(player.getHeight() / 2);

}

}

绘图玩家类别

    public class DrawPlayer extends JPanel implements KeyListener {

long xPosition = 0;
long yPosition = 0;

public void paintComponent(Graphics g) {
super.paintComponent(g);

// Making loop to get points and move it
// Center of area is x: 245 y: 255
int xPoints[] = {235, 255, 255, 235, 235, 255};
int yPoints[] = {265, 265, 245, 245, 265, 245};
for (int i = 0; i < xPoints.length; i++) {
xPoints[i] += xPosition;
yPoints[i] += yPosition;
}

g.setColor(Color.BLUE);
g.drawPolygon(xPoints, yPoints, xPoints.length);
}

public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
if (yPosition == 245) {
yPosition -= 5;
} else {
yPosition += 5;
}
break;
case KeyEvent.VK_UP:
if (yPosition == -245) {
yPosition += 5;
} else {
yPosition -= 5;
}
break;
case KeyEvent.VK_LEFT:
if (xPosition == -235) {
xPosition += 5;
} else {
xPosition -= 5;
}
break;
case KeyEvent.VK_RIGHT:
if (xPosition == 235) {
xPosition -= 5;
} else {
xPosition += 5;
}
break;
}
repaint();
}

public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

}
}

绘制敌人类

public class DrawEnemy extends JPanel {

public void paintComponent(Graphics f) {
super.paintComponent(f);

for (int i = 0; i < 10; i++ ){
f.setColor(Color.RED);
f.drawOval((int)(Math.random() * ((440 - 0) + 0) + 0), (int)(Math.random() * ((500 - 0) + 0) + 0), 50, 50);
}
}
}

最佳答案

您在这里遇到问题:

public void paintComponent(Graphics f) {
super.paintComponent(f);

for (int i = 0; i < 10; i++ ){
f.setColor(Color.RED);
f.drawOval((int)(Math.random() * ((440 - 0) + 0) + 0), (int)(Math.random() * ((500 - 0) + 0) + 0), 50, 50);
}
}

您在绘画方法内有程序逻辑,这是您永远不应该做的事情,因为您永远无法完全控制何时或是否调用绘画方法。解决方案是,将随机化从paintComponent方法中取出并放入其自己的单独方法中,当且仅当您想要随机化敌人时才调用该方法,而不是每次重新绘制时都调用该方法。

其他问题:

  • 将程序逻辑与 GUI 分开。
  • 例如,您应该有一个非 GUI Enemy 类,该类具有用于其自身位置、大小、运动的字段,也许是一个 move() 方法,也许是一个 碰撞(玩家p)方法。
  • 您应该只有一个 JPanel 来进行绘图,并且这应该是它唯一的工作。
  • 再次强调,您不会将任何物体的运动与绘画方法联系起来。
  • 您可能需要某种游戏循环,也许是一个 Swing Timer。这将生成规则间隔的刻度,促使敌人和玩家移动。
  • 摆脱 KeyListener 代码并支持按键绑定(bind)。当涉及到组件焦点时,后者就不那么笨拙了。请查看教程。

关于java - 如何防止我的 KeyEvent 重新绘制两个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37450720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com