发生碰撞时分数不变

本文关键字:碰撞 | 更新日期: 2023-09-27 17:57:06

我一直在尝试在玩家与其中一个收藏品碰撞时让我的分数正常工作,但当碰撞发生时分数似乎没有变化,我不确定为什么会发生这种情况。

在我的收藏品中,我有这个:

class BlueBall : Obj
{
    public BlueBall(Vector2 pos) 
        : base(pos)
    {
        position = pos;
        spriteName = "BlueBall";
        solid = false;
        score = 0;
    }
    public override void Update()
    {
        if (!alive) return;
        Player player = CheckCollisionAgainst<Player>();
        if (player != null)
        {
            score = score + 20;
            alive = false;
        }

我在Game1课上画画:

spriteBatch.DrawString(font, "Score: " + score.ToString(), scorePos, Color.White);

因此,如果玩家与蓝球碰撞,20 应该添加到分数中,蓝球应该消失,它确实消失了,但分数没有变化,这是为什么?

此刻,我正在用public int score宣布我在 Game1 类中的分数,并Vector2 scorePos定位它。然后,我用score = 0;初始化分数,然后在更新中加载分数Pos值。

发生碰撞时分数不变

从您的代码和注释中可以清楚地看出,实际上有两个分数变量。游戏拥有的一个:

public class Game
{
    private int score;
    void Draw(...)
    {
       spriteBatch.DrawString(font, "Score: " + score.ToString(), scorePos, Color.White);
    }
}

还有一个由拥有的:

public class BlueBall : Obj
{
    private int score;
    public void CheckCollisions()
    {
        if (collision)
           score += 20;
    }
}

现在,这两个分数变量彼此完全没有关系。它们被命名相同的事实是完全无关紧要的。

为了做一个快速的类比,想象编程对象是盒子。每个变量都是一个"计数器"。您在"游戏"框中放置一个计数器并将其称为"分数"。您在"球"框中放置另一个计数器,也称其为"得分"。显然,修改"球"框中的计数器不会影响"游戏"框中的计数器,反之亦然。通常,此概念在编程中称为"范围"。每个变量的作用域都限定在其框内,该框可以是类、函数,甚至是 using 块(范围由 {} 创建)。

现在您已经了解了问题,有几种方法可以解决它:

  1. 创建全局变量。实际上无法在 C# 中执行此操作,但可以创建其他两个对象都有权访问的另一个对象。两个对象都引用/修改它的"score"属性。一个简单(和糟糕的做法)的例子是:

    public static class GlobalState
    {
        public static int GameScore { get; set; }
    }
    

所有对分数的引用都将变为GlobalState.GameScore。同样,这只是为了让你开始,这种代码是非常糟糕的做法,可能会导致错误(尤其是在多线程情况下)。

  1. 让球在碰撞时引发事件。游戏将注册此事件并适当增加其"分数"变量。

  2. 通过 ref 将游戏的"score"变量传递给碰撞方法,以便它可以更改它。警告:这是为了完整起见而包含的,并且只能在特定情况下进行,而您的可能不是其中之一。

  3. 在创建时将委托传递给球,以便在需要增加分数时调用。这实际上是事件方法的变体。

我相信还有其他人。鉴于您的经验水平,我会从全球方法开始(因为它最简单,需要的知识最少),然后转向学习事件并在将来使用这种方法。