我正在使用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重叠它们。
答案 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);
}
}