【发布时间】:2015-12-07 12:05:46
【问题描述】:
我正在尝试添加一个仅限于我的游戏的有效盾牌,但现在由于某种原因它不起作用,我只是不知道为什么。
首先,这是屏蔽类:
class Shield : SpriteGameObject
{
protected float counter;
protected float limit;
public bool isShieldOn;
protected bool startCounting;
public Shield(int layer = 0, string id = "") : base("Sprites/spr_shield", layer, id)
{
counter = 0;
limit = 5;
isShieldOn = false;
startCounting = false;
}
public override void Update(GameTime gameTime)
{
//Stuff here
while (startCounting)
counter += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (counter >= limit)
{
isShieldOn = false;
counter = 0;
startCounting = false;
}
Player player = GameWorld.Find("player") as Player;
if (this.visible && this.CollidesWith(player))
{
isShieldOn = true;
startCounting = true;
this.visible = false; GameEnvironment.AssetManager.PlaySound("Sounds/snd_shieldcollected");
}
}
}
现在,当玩家触摸盾牌时游戏会冻结,但这与包含计数器的 while 语句有关。我不知道为什么,但首先让我解释一下我一直遇到问题的 isShieldOn 布尔值。
这里是使用 isShieldOn 布尔值的地方:
class Health : GameObjectList
{
Shield shield;
public Health(int layer = 3, string id = "") : base(layer, id)
{
//Stuff here
shield = new Shield(1, "shields");
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
if (shield.isShieldOn == false)
{
//Remove health
}
}
}
目前,当我在构造函数中将值设置为 true 时,盾牌就起作用了。但是,如果我尝试在 Shield 类的 Update 方法中为其分配 if 语句,它就不会成为真的。我 100% 确定执行了 if 语句,因为盾牌在触摸时确实会消失(this.visible = false)并且会播放音效。
如果您对如何解决此问题有任何想法,我将非常感谢,如果您对如何解决计时器有任何想法。
【问题讨论】:
-
更新被调用每一帧。您希望
while改为if。您还需要在成员中缓存Find("player")的结果(假设它始终是同一个对象),因为查找对象的成本很高。 (我实际上并不熟悉 xna,但我很确定我所说的都是相关的) -
好吧,他的 Find("player") 方法是他自己创建的(或导入的库),所以如果不查看在该方法中执行的实际代码,就无法判断这是否昂贵.然而,你是正确的'while to if' - 事情。
-
@BjarkeSøgaard 我明白了。然而,即使它在 O(1) 中被缓存和检索,在需要的地方保存直接引用肯定会更快。 0 次操作优于
k操作 :P 。无论如何,这只是给 OP 的一个额外说明 -
@SimpleVar 当然,我明白你的意思。但一般来说,当有人说某样东西“昂贵”时,他们的意思通常是指它对整个应用程序有明显的影响。
-
您应该将“while”替换为“if”以删除无限循环,但如果您不能这样做,则意味着您的游戏逻辑有问题。首先请说你的盾应该做什么?以及为什么要与播放器检查以使其不可见?