有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使对象在特定时间内消失?

我正在使用libgdx制作一个简单的游戏,角色收集硬币以获得分数,我想让硬币在再次消失之前只出现1-2秒。我不知道该怎么做。我尝试了一些技术,比如调度器或nanoTime(),但我就是无法让它工作

我正在使用迭代器在硬币中生成。(这是在更新方法中)

if(TimeUtils.nanoTime() - coin.lastDropTime > 2000000000){
            coin.spawnCoin();
    }

    Iterator<Rectangle> iter = coin.coins.iterator();
    while(iter.hasNext()) {
        Rectangle gold_coin = iter.next(); 
        if(snail.bounds.overlaps(gold_coin)){
            score += 10;
            iter.remove();
        }
    }

这是硬币课

public class Coin {

Sprite image;

boolean isVisible = true;

public Array<Rectangle> coins;
public long lastDropTime;

public Coin(){
    image = GameScreen.coin_sprite;
    coins = new Array<Rectangle>();
}

public void spawnCoin(){
    Rectangle bounds = new Rectangle();
    bounds.x = MathUtils.random(20, 1920 - 16);
    bounds.y = MathUtils.random(20, 1080 - 50);
    bounds.width = image.getWidth();
    bounds.height = image.getHeight();
    coins.add(bounds);
    lastDropTime = TimeUtils.nanoTime();
}

}

我只能让硬币在两秒钟后繁殖,而移除硬币的唯一方法是让字符重叠


共 (2) 个答案

  1. # 1 楼答案

    你只需在硬币上加一个计时器

    目前你有一个类Coin,它应该代表一枚硬币。但你手里拿着所有的硬币。面向对象编程的力量在于抽象硬币。将一枚硬币视为它自己的对象,从而仅为这个闪亮的小对象创建一个类

    public class Coin {
    
        //Fields specific for the coin
        private Vector2 position;
        private int worth;
        private Sprite sprite;
    
        //Fields for the timer, since this coin dissapears it should hold it's own self destruct timer
        public float timeAlive = 0;
        public float despawnTime = 2;
    
        public Coin(Vector2 position, int worth, Sprite sprite, float despawnTime) {
            this.position = position;
            this.worth = worth;
            this.sprite = sprite;
            this.despawnTime = despawnTime;
        }
    
        //Since we hold a list somewhere else of the objects represented by this class we should be able to delete them from the list when the time is up.
        public boolean isAlive()
        {
            return timeAlive < despawnTime;
        }
    
        //I like to abstract update and draw from render. In update we put the logic, which in this case is updating it's time alive.
        public void update()
        {
            timeAlive += Gdx.graphics.getDeltaTime();
        }
    
        public void draw(SpriteBatch batch)
        {
    
    
            //Draw your object
        }
    }
    
    public class SomethingHoldingCoins {
    
        //A list to hold our coins
        List<Coin> coins = new ArrayList<Coin>();
    
        //A timer system to spawn coins
        private int spawnTime = 4;
        private int timer = 0;
    
        public void update()
        {
            //Increment timer by the time since last frame
            timer += Gdx.graphics.getDeltaTime();
    
            //check if timer past the spawn time
            if (timer >= spawnTime)
            {
                //Add a coin to the list
                coins.add(new Coin(somePosition, 100, coinSprite, 2));
                //subtract spawntime from timer
                timer -= spawnTime;
            }
    
            //iterate over the list of coins to do stuff like drawing and removing despawned coins
    
            for (Iterator<Coin> iterator = coins.iterator(); iterator.hasNext())
            {
                Coin coin = iterator.next();
                //Update the coin
                coin.update();
                //Check if it is still alive
                if (!coin.isAlive())
                {
                    //remove the coin from the list since it is despawned anyway, then continue with the next iteration
                    iterator.remove();
                    continue;
                }
    
                coin.draw(spriteBatch);
            }
        }
    }
    

    当我们通过new Coin(...)创建一枚硬币时,我们会生成它,只要我们在每一帧上不断调用update(),计时器就会运行。因此,在持有硬币的对象中,我们创建一个列表,生成它们,更新它们,等等。也许你的地图是放置硬币的好地方,至少对于Mario来说是这样,因为地图持有coins

    把每件事都看成是物体。就像我把价值放在硬币里,因为一枚硬币可能有价值。这仍然取决于你正在尝试做什么,以及你的类有多大和(不)可读性。一个简单驾驶游戏的Car类应该包含它的Wheels。但是一个更高级的游戏可能会把Chassis放进车里,而Chassis会得到Suspension,而悬挂最终会得到Wheels。因此,它们中的每一个都可以保留自己的功能。由于人类逻辑和更小的类,这使得代码更具可读性

  2. # 2 楼答案

    你看过ScheduledThreadPoolExecutor吗

    它有一个方法scheduleWithFixedDelay,我认为它可以完成你需要做的事情

    不过,您必须小心,因为迭代器的删除操作可能会引发ConcurrentModificationException,如果您正在迭代,而另一个线程正在从列表中删除项,并且最多该行为是未定义的。但是如果你正在寻求这样的线程解决方案,你可以有一个单独的线程来检查重叠

    另外,我很抱歉我不熟悉数组接口,但我假设有一些方法可以删除任何任意索引的对象

    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    executor.scheduleWithFixedDelay(new CoinRemover(coin, coins), 0, 2, TimeUnit.SECONDS);
    
    class CoinRemover implements Runnable {
        Coin coin;
        List<Coin> coins;
    
        public CoinRemover(Coin coin, List<Coin> coins) {
            this.coin = coin;
            this.coins = coins;
        }
    
        @Override
        public void run() {
            coins.remove(coin);
        }
    }