gpt4 book ai didi

Java Space Invader 子弹运动

转载 作者:行者123 更新时间:2023-12-01 23:57:29 25 4
gpt4 key购买 nike

我正在尝试编写一款《太空入侵者》游戏,以温习我在 AP 计算机科学中学到的技能。我遇到了问题。当我按下空格键(开火按钮)时,子弹移动到顶部的动画不可见。相反,子弹只是出现在您发射的屏幕顶部。这是包含子弹发射的代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;

public class AlienInvader extends JPanel implements KeyListener, ActionListener {

Constants constant = new Constants();
Timer timer = new Timer(5, this);
Sprite images = new Sprite();

public void update() {
timer.start();
images.loadImage();
addKeyListener(this);
setFocusable(true);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, 500, 500);
g.drawImage(images.spaceship, constant.x, constant.y, null);
g.drawImage(images.bullet, constant.bulletx, constant.bullety, null);
}

@Override
public void keyPressed(KeyEvent e) {
System.out.println(constant.x);
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
constant.xvel = -1 * constant.STEP;
repaint();
break;
case KeyEvent.VK_RIGHT:
constant.xvel = 1 * constant.STEP;
repaint();
break;
case KeyEvent.VK_SPACE:
constant.xvel = 0;
constant.bulletx = constant.x;
constant.bullety = constant.y;
while (constant.bullety > 0) {
constant.bullety = constant.bullety - 1;
repaint();
}
}
constant.x += constant.xvel;
}

@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
constant.xvel = -1;
break;
case KeyEvent.VK_RIGHT:
constant.xvel = 1;
break;
}
}

@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub

}

@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub

}

}

我该如何做才能让用户在你开火时看到子弹在屏幕上移动?

最佳答案

您遇到了“阻塞事件调度线程”问题,这似乎是这里的一个非常常见的问题......

基本上,当这段代码正在执行时......

while (constant.bullety > 0) {
constant.bullety = constant.bullety - 1;
repaint();
}

无法绘制任何内容,因为您阻塞了负责处理重绘的线程。

重绘是向重绘管理器发出的更新屏幕上的一部分的请求。重绘管理器是为性能而设计的,因此它将尝试将所有各种重绘请求折叠为尽可能少的调用,然后将重绘请求添加到事件调度线程中......

因此,当您阻止 EDT 时,无法重新绘制任何内容。

看看Concurrency in SwingPainting in AWT and Swing了解更多详情。

现在,找到解决方案。

有很多方法可以实现这一目标。一般来说,您需要某种能够运行后台、更新游戏中的各种对象并将结果渲染到屏幕上的“引擎”或“ Controller ”。

这提出了许多重大问题。首先,与 UI 的所有交互都必须在 EDT 上下文中执行。这意味着,您永远不应该从 EDT 外部创建或更新任何 UI 组件。

第二个是确保您不会改变渲染器所依赖的游戏模型的任何部分(因为您实际上并不控制重绘过程)。

这个最简单的解决方案是使用 BufferedImage,您可以将其绘制到它(在后台 Thread 内)。

这将允许您更新游戏模型,将结果渲染到后备缓冲区,将该缓冲区重新同步到 UI,然后进行短暂的等待以使 UI 有时间 catch 。简单:D

关于Java Space Invader 子弹运动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15351514/

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