我有以下程序,这是一个SubKiller游戏,我有一个问题。每当我按下向下键时,如何使船只发射炸弹?到目前为止,我已经多次启动了它。我可以发射第一个炸弹,但是当我尝试发射第二个炸弹时,第一个炸弹消失了,而且没有继续下去。我在这件事上停留了将近两天,请帮助我。
我将为您提供SSCCE代码。
这是一个名为SubKillerPanel的类,基本上所有东西都在这里,船在这里,炸弹在这里,潜艇在这里。
import java.awt.event.*;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.Color;
public class SubKillerPanel extends JPanel {
private static final long serialVersionUID = 1L;
private Timer timer;
private int width, height;
private Boat boat;
private Bomb bomb;
private Submarine sub;
public SubKillerPanel() {
setBackground(Color.WHITE);
ActionListener action = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (boat != null) {
boat.updateForNewFrame();
bomb.updateForNewFrame();
sub.updateForNewFrame();
}
repaint();
}
};
timer = new Timer( 20, action );
addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
requestFocus();
}
}
);
addFocusListener( new FocusListener() {
public void focusGained(FocusEvent evt) {
timer.start();
repaint();
}
public void focusLost(FocusEvent evt) {
timer.stop();
repaint();
}
}
);
addKeyListener( new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
int code = evt.getKeyCode(); // ce tasta a fost apasata
if (code == KeyEvent.VK_LEFT) {
boat.centerX -= 15;
}
else
if (code == KeyEvent.VK_RIGHT) {
boat.centerX += 15;
}
else
if (code == KeyEvent.VK_DOWN) {
if (bomb.isFalling == false)
bomb.isFalling = true;
bomb.centerX = boat.centerX;
bomb.centerY = boat.centerY;
}
}
}
);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (boat == null) {
width = getWidth();
height = getHeight();
boat = new Boat();
sub = new Submarine();
bomb = new Bomb();
}
if (hasFocus())
g.setColor(Color.CYAN);
else {
g.setColor(Color.RED);
g.drawString("CLICK TO ACTIVATE", 20, 30);
g.setColor(Color.GRAY);
}
g.drawRect(0,0,width-1,height-1);
g.drawRect(1,1,width-3,height-3);
g.drawRect(2,2,width-5,height-5);
boat.draw(g);
sub.draw(g);
bomb.draw(g);
}
private class Boat {
int centerX, centerY;
Boat() {
centerX = width/2;
centerY = 80;
}
void updateForNewFrame() {
if (centerX < 0)
centerX = 0;
else
if (centerX > width)
centerX = width;
}
void draw(Graphics g) {
g.setColor(Color.blue);
g.fillRoundRect(centerX - 40, centerY - 20, 80, 40, 20, 20);
}
}
private class Bomb {
int centerX, centerY;
boolean isFalling;
Bomb() {
isFalling = false;
}
void updateForNewFrame() {
if (isFalling) {
if (centerY > height) {
isFalling = false;
}
else
if (Math.abs(centerX - sub.centerX) <= 36 && Math.abs(centerY - sub.centerY) <= 21) {
sub.isExploding = true;
sub.explosionFrameNumber = 1;
isFalling = false; // Bomba reapare in barca
}
else {
centerY += 10;
}
}
}
void draw(Graphics g) {
if ( !isFalling ) {
centerX = boat.centerX;
centerY = boat.centerY + 23;
}
g.setColor(Color.RED);
g.fillOval(centerX - 8, centerY - 8, 16, 16);
}
}
private class Submarine {
int centerX, centerY;
boolean isMovingLeft;
boolean isExploding;
int explosionFrameNumber;
Submarine() {
centerX = (int)(width*Math.random());
centerY = height - 40;
isExploding = false;
isMovingLeft = (Math.random() < 0.5);
}
void updateForNewFrame() {
if (isExploding) {
explosionFrameNumber++;
if (explosionFrameNumber == 30) {
centerX = (int)(width*Math.random());
centerY = height - 40;
isExploding = false;
isMovingLeft = (Math.random() < 0.5);
}
}
else {
if (Math.random() < 0.04) {
isMovingLeft = ! isMovingLeft;
}
if (isMovingLeft) {
centerX -= 5;
if (centerX <= 0) {
centerX = 0;
isMovingLeft = false;
}
}
else {
centerX += 5;
if (centerX > width) {
centerX = width;
isMovingLeft = true;
}
}
}
}
void draw(Graphics g) {
g.setColor(Color.BLACK);
g.fillOval(centerX - 30, centerY - 15, 60, 30);
if (isExploding) {
g.setColor(Color.YELLOW);
g.fillOval(centerX - 4*explosionFrameNumber, centerY - 2*explosionFrameNumber,
8*explosionFrameNumber, 4*explosionFrameNumber);
g.setColor(Color.RED);
g.fillOval(centerX - 2*explosionFrameNumber, centerY - explosionFrameNumber/2,
4*explosionFrameNumber, explosionFrameNumber);
}
}
}
}
SubKiller类,主要方法位于该类中。
import javax.swing.JFrame;
public class SubKiller {
public static void main(String[] args) {
JFrame window = new JFrame("Sub Killer Game");
SubKillerPanel content = new SubKillerPanel();
window.setContentPane(content);
window.setSize(700, 700);
window.setLocation(0,0);
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setResizable(false);
window.setVisible(true);
}
}
最佳答案
在任何时候,图形只能跟踪一个炸弹。您应该构建一个炸弹集合,并在按下向下键时实例化一个新炸弹,然后遍历所有炸弹集合并根据需要绘制它们。
因此,而不是private Bomb bomb;
您将有private List<Bomb> bombs;
之后,在更新单个bomb
的任何位置,都可以使用for循环遍历bombs
的列表并使它们全部更新,然后,如果不再绘制它们,则将它们从列表中删除。
关于java - 按我的开火键时,SubKiller游戏无法正确触发,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20056429/