stackoverflow社区! 我正在JAVA制作一个基于GUI的小游戏。 我现在遇到一些麻烦。 为了让您对我的课程有基本的了解,
我有一个首先显示菜单(JPanel)的窗口。当我点击"开始游戏"按钮。它进入另一个我可以玩游戏的JPanel。 ![menu_window] [1]
我有一个计时器正在处理一个定期移动的小子弹。每次计时器工作时,小组都会重新弹出子弹。我可以看到重绘方法有效,但它不会删除之前的跟踪。
![在此输入图片说明] [2]
这是我的主要课程
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main {
private final int window_x_size = 500;
private final int window_y_size = 500;
private JFrame frame;
private JPanel Menu;
private Game myGame = new Game();//extends from JPanel
private JButton startButton = new JButton("Game Start");
private JButton exitButton = new JButton("Game Exit");
private JButton showRank = new JButton("Rank");
private JButton OneOnOne = new JButton("One on One");
private ActionListener MyButtonListener = new MyButtonListener();
public class MyButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == startButton) {
frame.remove(Menu);
frame.setContentPane(myGame);
frame.validate();
frame.repaint(); // prefer to write this always.
} else if (source == exitButton) {
System.exit(1);
} else if (source == showRank) {
} else {// one on one
}
}
}
public Main() {
frame = new JFrame();
frame.setBackground(Color.white);
frame.setSize(window_x_size, window_y_size);
frame.setTitle("My First GUI Game");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
Menu = new JPanel();
startButton.addActionListener(MyButtonListener);
exitButton.addActionListener(MyButtonListener);
showRank.addActionListener(MyButtonListener);
OneOnOne.addActionListener(MyButtonListener);
Menu.setLayout(new GridLayout(4, 1));
Menu.add(startButton);
Menu.add(OneOnOne);
Menu.add(showRank);
Menu.add(exitButton);
frame.setContentPane(Menu);
frame.setVisible(true);
}
public static void main(String[] args) {
/*
* This is the most important part of your GUI app, never forget
* to schedule a job for your event dispatcher thread :
* by calling the function, method or constructor, responsible
* for creating and displaying your GUI.
*/
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new Main();
}
});
}
}
这是我的游戏类
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game extends JPanel {
private Random rnd = new Random();
private ActionListener MyBulletListener = new BulletListener();
public KeyListener myKeyListen = new MyKeyListener();
Timer bullet_timer;
private boolean IsExplosion = false;
private ImageIcon spacecraftImg = new ImageIcon("spacecraft.png");
private Rectangle spacecraftBox = new Rectangle(5, 10,
spacecraftImg.getIconWidth(), spacecraftImg.getIconHeight());
private ImageIcon explosionImg = new ImageIcon("explosion.png");
private ImageIcon bulletImg = new ImageIcon("bullet.png");
private Rectangle bulletBox = new Rectangle(70, 200,
bulletImg.getIconWidth(), bulletImg.getIconHeight());
private MySound explosion_sound = new MySound();
public Game() {
addKeyListener(myKeyListen);
bullet_timer = new Timer(500, MyBulletListener);
bullet_timer.start();
}
public class MyKeyListener implements KeyListener {
private int x;
private int y;
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode = e.getKeyCode();
if (keyCode == 37) {
x = -10;
y = 0;
} else if (keyCode == 38) {
x = 0;
y = -10;
} else if (keyCode == 39) {
x = 10;
y = 0;
} else {
x = 0;
y = 10;
}
if (spacecraftBox.x + x < 0
|| spacecraftBox.x + x > 500
|| spacecraftBox.y + y < 0
|| spacecraftBox.y + y > 500) {
} else {
move_plane(x, y);
repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
public class BulletListener implements ActionListener {
private int x;
private int y;
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Object source = e.getSource();
if (source == bullet_timer) {
int dir = rnd.nextInt(4);
if (dir == 0) {// move left
x = -10;
y = 0;
} else if (dir == 1) {// move right
x = 10;
y = 0;
} else if (dir == 2) {// move up
x = 0;
y = -10;
} else {// move down
x = 0;
y = 10;
}
if (bulletBox.x + x < 0
|| bulletBox.x + x > 500
|| bulletBox.y + y < 0
|| bulletBox.y + y > 500) {
} else {
move_bullets(x, y);
repaint();
}
}
}
}
@Override
public void paint(Graphics g) {
g.drawImage(bulletImg.getImage(), (int) bulletBox.getX(),
(int) bulletBox.getY(), null);
g.drawImage(spacecraftImg.getImage(), (int) spacecraftBox.getX(),
(int) spacecraftBox.getY(), null);
if (IsExplosion) {
g.drawImage(explosionImg.getImage(), (int) bulletBox.getX(),
(int) bulletBox.getY(), null);
MySound.play();
IsExplosion = false;
}
}
public void move_plane(int x, int y) {
spacecraftBox.translate(x, y);
if (spacecraftBox.intersects(bulletBox)) {
IsExplosion = true;
}
}
public void move_bullets(int x, int y) {
bulletBox.translate(x, y);
if (spacecraftBox.intersects(bulletBox)) {
IsExplosion = true;
}
}
}
另外我添加了KeyListener,但它不起作用。我不知道如何解决它。
我试着用谷歌搜索这个问题。我尝试过可以在主要课程中集中讨论的游戏小组,但它没有用。
我真的很感谢你的帮助。
最诚挚的问候,
Dongseop
答案 0 :(得分:2)
这几乎总是由于你的绘画方法没有调用超级的绘画方法来清理脏像素。由于您要覆盖绘制,因此需要在绘制覆盖中调用super.paint(g);
作为第一个方法调用。
其他问题:
paintComponent(Graphics g)
,因为这会为动画提供自动双缓冲并使动画更流畅。再次,在方法覆盖中调用super.paintComponent(g);
。Java Key Bindings Tutorial
查看有关如何使用这些内容的官方教程。