为什么我的arraylist项在禁用时不自动删除?

tez616oj  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(337)

我试图让我的小行星游戏在java有arraylist容器被删除,一旦它离开屏幕。我知道如何在屏幕外停止打印,但在我的控制台中可以看到阵列继续增长。不知道从这里到哪里去。
我认为在屏幕外删除它们的方法是使用arraylists的remove或set特性。从视觉上看,一切都在消失,但在控制台中,我的数组列表仍在增长。我想定一个时间限制,但不确定是否有更好的办法。

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;

public class AsteroidGame extends Frame {

    private int FrameWidth = 500;
    private int FrameHeight = 400;

    static public void main(String[] args) {
        AsteroidGame world = new AsteroidGame();
        world.show();
        world.run();
    }

    public AsteroidGame() {
        setTitle("Asteroid Game0");
        setSize(FrameWidth, FrameHeight);
        addKeyListener(new keyDown());
        addWindowListener(new CloseQuit());
    }

    public void run() {
        while (true) {
            movePieces();
            repaint();
            try {
                Thread.sleep(100);

            } catch (Exception e) {
            }
        }
    }

    private ArrayList asteroids = new ArrayList();
    private ArrayList rockets = new ArrayList();
    private Station station = new Station(FrameWidth / 2, FrameHeight - 20);

    public void paint(Graphics g) {
        station.paint(g);
        Iterator astIt = asteroids.iterator();
        while (astIt.hasNext()) {
            Asteroid rock = (Asteroid) astIt.next();
            if (rock.y >= 400 || rock.x >= 500){
                rock = null;
            } else {
                rock.paint(g);
            }

        }
        Iterator rocIt = rockets.iterator();
        while (rocIt.hasNext()) {
            Rocket rock = (Rocket) rocIt.next();
            if (rock.y >= 400 || rock.x >= 500) {
                rock = null;
            } else {
                rock.paint(g);
            }
        }

    }

    public void movePieces() {
        if (Math.random() < 0.3) {
            Asteroid newRock = new Asteroid(FrameWidth * Math.random(), 20, 10 * Math.random() - 5, 3 + 3 * Math.random());
            if (newRock.y >= 500 || newRock.x >= 500){

                asteroids.remove(0);

            } else{
                asteroids.add(newRock);
            }
            System.out.println(asteroids.size());

        }

        Iterator astIt = asteroids.iterator();
        while (astIt.hasNext()) {
            Asteroid rock = (Asteroid) astIt.next();
            if (rock.y >= 400 || rock.x >= 500) {
                rock = null;
            } else {
                rock.move();
                station.checkHit(rock);
            }

        }
        Iterator rocIt = rockets.iterator();
        while (rocIt.hasNext()) {
            Rocket rock = (Rocket) rocIt.next();
            if (rock.y >= 400 || rock.x >= 500) {
                rock = null;
            } else {
                rock.move(asteroids);
            }

        }

    }

    private class gameMover extends Thread {

        public void run() {
            while (true) {
                movePieces();
                repaint();
                try {
                    sleep(100);

                } catch (Exception e) {
                }
            }
        }
    }
eeq64g8w

eeq64g8w1#

更改:

rock = null;

收件人:

astIt.remove();

分配 null 对于已经分配了列表元素值的变量,列表或列表中的元素绝对不起任何作用;它只影响变量所持有的值。
作为一个旁白,很好的变量名选择 rock -这两种类型的物体都是合适的——要么是“火箭”的缩写,要么是星象的合理同义词。

k5ifujac

k5ifujac2#

改变 rock = null;asteroids.remove(rock); 或者 astIt.remove(); 这应该很好,也不需要将变量设置为null,因为垃圾收集器将为您处理它。
编辑
事实上 asteroids.remove(rock); 将抛出一个异常,正如在这个答案的评论中所说的,所以不要终止它并使用另一个。
我也认为在 movePieces() 你创建一个新的岩石,然后检查这个新岩石是否在屏幕外,我不认为删除arraylist中的第一个小行星是正确的,因为你不会添加新的岩石(如果岩石可以在屏幕外随机繁殖,这可能是正确的),但你也会从arraylist中删除一个可能工作良好的小行星(从而从游戏和屏幕)。
所以,就我个人而言,我会将这部分代码改为:

if (Math.random() < 0.3) {
        Asteroid newRock = new Asteroid(FrameWidth * Math.random(), 20, 10 * Math.random() - 5, 3 + 3 * Math.random());
        if (!(newRock.y >= 500 || newRock.x >= 500)){

            asteroids.add(newRock);
        }
        System.out.println(asteroids.size());

    }

但告诉我这是否对你有用。

相关问题