我有以下程序,这是一个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/

10-09 01:06