Java 未正确生成动画岩石

Java 未正确生成动画岩石,java,animation,timer,Java,Animation,Timer,我正在制作一个游戏,一个穴居人在扔石头,当你点击时,一块石头就诞生了。前五个左右工作正常,然后等待岩石离开屏幕,然后它们可以再次产卵。我希望它们在我点击时繁殖 提前谢谢 代码: package com.russell.raphael.birds; 导入java.awt.Toolkit; 导入java.awt.event.MouseAdapter; 导入java.awt.event.MouseEvent; 导入java.awt.event.MouseListener; 导入javax.swing

我正在制作一个游戏,一个穴居人在扔石头,当你点击时,一块石头就诞生了。前五个左右工作正常,然后等待岩石离开屏幕,然后它们可以再次产卵。我希望它们在我点击时繁殖

提前谢谢

代码:

package com.russell.raphael.birds;
导入java.awt.Toolkit;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
@抑制警告(“串行”)
公共类开始扩展JFrame{
ImageIcon landImage、manImage、skyImage、RockPileImage、RockImage;
JLabel skylbl、manlbl、landbl、rockpillebl;
鸟[]鸟=新鸟[10];
岩石[]岩石=新岩石[10000];
公共静电鼠标听筒;
公共静态void main(字符串[]args){
新开始();
}
公共启动(){
setVisible(真);
initComp();
设置大小(10001100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(空);
片名(“不是鸟!!!”;
setIconImage(Toolkit.getDefaultToolkit().getImage(Start.class.getResource(“/com/russell/raphael/images/Icon.png”));
}
私有void initComp(){
throwrock=newmouseadapter(){
@凌驾
公共无效mouseClicked(MouseEvent e){
int-eventX=0,eventY=0,sourceX=420,sourceY=840;
整数上升=0,运行=0;
试一试{
JLabel source=(JLabel)e.getSource();
eventX=(source.getLocation().x)+(e.getX());
eventY=(source.getLocation().y)+(e.getY());
rise=Math.abs(eventY-sourceY);
run=eventX-sourceX;
nextRock().启动(上升、运行);
}捕获(例外情况除外){
例如printStackTrace();
}
}
};
可设置大小(假);
用于(int counter=0;counter

下一节课:

package com.russell.raphael.birds; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.Timer; @SuppressWarnings("serial") public class Rock extends JLabel { Timer timer; Thread thread; boolean hasBeenUsed = false; public Rock() { super(); setBounds(415, 840, 37, 35); setIcon(new ImageIcon( Rock.class.getResource("/com/russell/raphael/images/Rock.png"))); setVisible(true); } public void start(final int rise, final int run) { hasBeenUsed = true; thread = new Thread() { public void run() { timer = new Timer(30, new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { setBounds(getBounds().x + run / 20, getBounds().y + -rise / 20, getBounds().width, getBounds().height); if (getBounds().x < 0 || getBounds().y < 0 || getBounds().y > 1000) { timer.stop(); hasBeenUsed = false; setBounds(415, 840, 37, 35); thread.stop(); } } }); timer.start(); } }; thread.start(); } } </code>
包com.russell.raphael.birds; 导入java.awt.event.ActionEvent; 导入java.awt.event.ActionListener; 导入javax.swing.ImageIcon; 导入javax.swing.JLabel; 导入javax.swing.JOptionPane; 导入javax.swing.Timer; @抑制警告(“串行”) 公开级摇滚乐{ 定时器; 螺纹; 布尔hasBeenUsed=false; 公共摇滚乐(){ 超级(); 挫折(41584037 35); 设置图标(新图像图标( Rock.class.getResource(“/com/russell/raphael/images/Rock.png”); setVisible(真); } 公共无效开始(最终整数上升,最终整数运行){ hasBeenUsed=true; 线程=新线程(){ 公开募捐{ 计时器=新计时器(30,新ActionListener(){ @凌驾 已执行的公共无效行动(行动事件ae){ setBounds(getBounds().x+run/20,getBounds().y +-上升/20,getBounds().宽度, getBounds().高度); 如果(getBounds().x<0 | | getBounds().y<0 ||getBounds().y>1000){ timer.stop(); hasBeenUsed=false; 挫折(41584037 35); thread.stop(); } } }); timer.start(); } }; thread.start(); } }

我对清空岩石池然后等待它们消失没有问题,但我还有很多其他问题

让我们从

nextRock().start(rise, run);
这可能会返回一个
null
对象,这将导致
NullPointerException

正如我之前说过的,你不应该
nextRock().start(rise, run);
public class Rock extends JLabel {

    Timer timer;
    private volatile boolean hasBeenUsed = false;

    public Rock() {
        super();
        setIcon(new ImageIcon(Rock.class.getResource("/Rock.png")));
        setBounds(415, 840, getPreferredSize().width, getPreferredSize().height);
        setVisible(false);
    }

    public void start(final int rise, final int run) {
        hasBeenUsed = true;
        setVisible(true);
        timer = new Timer(30, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                setBounds(getBounds().x + run / 20, getBounds().y
                                + -rise / 20, getBounds().width,
                                getBounds().height);

                if (getBounds().x < 0 || getBounds().y < 0
                                || getBounds().y > 1000) {
                    timer.stop();
                    hasBeenUsed = false;
                    setBounds(415, 840, getPreferredSize().width, getPreferredSize().height);
                }
            }
        });
        timer.start();
    }
}
public Rock nextRock() {
    for (int counter = 0; counter < rocks.length; counter++) {
        if (!rocks[counter].hasBeenUsed) {
            return rocks[counter];
        }
    }
    return null;
}
public class RockManager {

    private List<Rock> rockPile;
    private List<Rock> inFlight;
    public static final int MAX_ROCKS = 2;

    public RockManager() {
        rockPile = new ArrayList<Rock>(MAX_ROCKS);
        inFlight = new ArrayList<Rock>(MAX_ROCKS);
        for (int index = 0; index < MAX_ROCKS; index++) {
            rockPile.add(new Rock(this));
        }
    }

    public Rock[] getRocksOnPile() {
        return rockPile.toArray(new Rock[rockPile.size()]);
    }

    public Rock[] getRocksInFlight() {
        return inFlight.toArray(new Rock[inFlight.size()]);
    }

    public Rock pickRockOfPile() {
        Rock rock = null;
        if (!rockPile.isEmpty()) {
            rock = rockPile.remove(0);
            inFlight.add(rock);
        }
        return rock;
    }

    public void putRockBackOnPile(Rock rock) {
        if (inFlight.contains(rock)) {
            inFlight.remove(rock);
            rockPile.add(rock);
        }
    }
}
for(int counter =0; counter < rocks.length; counter++){
    rocks[counter] = new Rock();
    getContentPane().add(rocks[counter]);
}
rockManager = new RockManager();
for (Rock rock : rockManager.getRocksOnPile()) {
    getContentPane().add(rock);
}
public Rock nextRock() {
    return rockManager.pickRockOfPile();
}
private RockManager manager;

public Rock(RockManager manager) {
    super();
    this.manager = manager;
manager.putRockBackOnPile(Rock.this);