如何在特定时间内使物体消失?

时间:2016-03-30 20:18:52

标签: java libgdx

我正在使用libgdx制作一个简单的游戏,其中characther收集硬币以获得分数,我想让它变成硬币只出现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秒钟获得硬币产生,并且移除硬币的唯一方法是让charachter重叠它们。

2 个答案:

答案 0 :(得分:1)

您只需在硬币上添加一个计时器。

目前您有一个类Coin,它应该代表一枚硬币。但你在那里拿着你的硬币。 OOP编程的力量是抽象硬币。将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 1}}。

将一切都视为对象。就像我把价值放在硬币里面,因为硬币可能有价值。它仍然取决于你想要做什么以及你的课程有多大和(不)可读。一个简单的驾驶游戏的Car课程可能应该在其内部持有Wheels。但是更高级的游戏可能会将Chassis放入汽车中,Chassis会获得Suspension,暂停最终会获得Wheels。所以他们每个人都可以拥有自己的功能。由于人工逻辑和更小的类,这使得代码更具可读性。

答案 1 :(得分:-1)

你看过ScheduledThreadPoolExecutor吗?

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

你必须要小心,因为迭代器的删除可能会抛出一个ConcurrentModificationException,如果你在一个单独的线程从列表中删除项目时进行迭代,并且最好不确定该行为。但是,如果你正在寻求这样的线程化解决方案,你可以让一个单独的线程检查重叠。

另外,我很抱歉我不熟悉Array接口,但我认为有一些删除任意索引对象的方法。

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);
    }
}