【问题标题】:How to give score only once for each level?每个级别如何只给分数一次?
【发布时间】:2016-09-12 16:35:55
【问题描述】:

在我的游戏中,我有很多关卡。每个关卡有 3 个目标。为了在每个关卡中完成一个目标,玩家将获得一颗星。玩家在所有关卡中获得的所有星星的值都保存为总星数。现在问题出在我是否只想为每个关卡中的每个目标增加一次总星数的值。例如,如果玩家第一次玩关卡 1 并完成一个目标,他会得到 1 颗星,但当他再次玩关卡并再次完成相同的目标时总星数的值不应该增加。我该怎么做?我希望我说得足够清楚。以下是目标之一。

void OnTriggerEnter2D (Collider2D Ball)
{
    EndGame.SetActive(true);
    WinStar.SetActive(true);
    PlayerPrefs.SetInt("Level" + CurrentLevel.ToString() + "_win", 1);  
    deactive();
    COuntAndTime();

    TotalStars.Totalstars += 1; //this value should increase only once for each objective in each level.
    TotalStars.totstar.Save();
}

【问题讨论】:

    标签: c# unity3d scripting points multi-level


    【解决方案1】:

    有许多可能的解决方案。例如,您可以使用三个bool 变量,这样每颗星都有自己的bool 变量。然后创建一个只读属性 int TotalStars 并将其计算为这三个变量中的多个 true 值。

    bool starA, starB, starC;
    
    if(solved) starA = true; //an example
    
    int TotalStars() {
      int sum = 0;
      if(starA) sum++;
      if(starB) sum++;
      if(starC) sum++;
      return sum;
    }
    

    【讨论】:

    • 谢谢你的建议,也许我用错了方法,但它不会在每个级别单独工作
    【解决方案2】:

    执行此操作的最基本方法是创建一个 N * 3(n 是级别数)数组。所以用布尔值。所以它会喜欢这个

    int[,] objectives = new bool[N, 3]
    {true , false, true},
    {false, false, false}
    

    然后在增量时检查他们是否已经获得了星星

    您可以在每个级别中使用更动态的结构或对象,其中包含您可以查询的这些布尔值。所以在级别中您将拥有

    CompletedObjectives objectives{get; set;}
    

    完成的目标看起来像

    Public class CompletedObjectives
    {
    bool ObjectiveOne {get ;set;}
    bool ObjectiveTwo {get ;set;}
    bool ObjectiveThree {get ;set;}
    }
    

    在递增之前再次查询这些

    希望对你有帮助

    编辑:额外信息

    所以 c# 是一种面向对象的语言,因此每个级别都应该是一个对象,它将包含有关级别的信息,您需要决定每个级别具有的信息,例如级别编号、难度和星级。您还需要一个名为 play level 之类的虚拟方法,虚拟方法是您可以在另一个类中覆盖的方法。如果类中没有实现该方法,下面的代码会抛出异常。

    public class level
    {
      public int level number {get; set;}
    
      public string difficulty {get ; set;}
    
      public CompletedObjectives objectives {get;set;}
    
      public virtual void PlayLevel()
      {
        System.NotImplementedException(); 
      }
    
    }
    

    所以你的下一步是制作你的关卡

    1 级示例

    public class Level1 : level
    {
       this.levelnumber = 1;
       this.difficulty = "easy";
    
       public override void Playlevel()
       {
          //level logic goes here
       }
    
    }
    

    然后你的 main 会将所有这些级别添加到列表中

    List<Level> levels = new List<Level>{new Level1(), new Level2()}
    

    所以第一次从列表中调用 level1 时,所有目标都是错误的,当它们完成时,您将它们的值更改为 true,如果它们为 true,则第二次增加总星数,您不增加。

    如果您需要更多帮助,请随时询问上述代码是一个粗略的大纲,以解释可以完成此操作的基本方法。它们是提供更多好处的更先进的方法,但您必须从某个地方开始。

    https://www.coursera.org/learn/game-programming

    https://mva.microsoft.com/

    youtube 也是学习基本编程的绝佳资源。他们有很多书,尤其是关于面向对象的一般书籍,这将帮助您更好地设计类/接口等。

    【讨论】:

    • 感谢您回复我在哪里可以获得有关此方式的更多信息,因为我是初学者,仅通过此方式很难实现这一点
    • 我添加了更多的解释我稍后会添加学习资源的链接
    【解决方案3】:

    我会探索使用枚举作为标志。它将为您提供灵活性和速度,同时降低存储要求并提高可读性。

    枚举的支持类型是整数。整数是一系列位(0 或 1)。基本前提是使用位作为关卡的存储。

    Example
    00000000 - No bits are set, so no levels are set.
    00000001 - The rightmost bit is set so first level is set.
    00001001 - The 4th to right and rightmost bit is set so the 4th and first level is set.
    

    https://msdn.microsoft.com/en-us/library/system.flagsattribute(v=vs.110).aspx

    以下示例使用枚举来存储关卡状态。

    [Flags]
    public enum Levels 
    {
        Level01 = 1, /* note values are powers of 2*/
        Level02 = 2,
        Level03 = 4,
        Level04 = 8
    }
    
    void OnTriggerEnter2D (Collider2D Ball)
    {
        EndGame.SetActive(true);
        WinStar.SetActive(true);
    
        /* Note enum value can be calculated as 2^Level 
           May want to internalize logic in method on PlayerPrefs class */
        PlayerPrefs.LevelState |= (int) Math.Pow(2, CurrentLevel);
        deactive();
        COuntAndTime();
    
        /* new method for determining TotalStars 
           May want to internalize logic in method on TotalStars Class */
        TotalStars.Totalstars = CountBits(PlayerPrefs.LevelState); 
        //this value should increase only once for each objective in each level.
        TotalStars.totstar.Save();
    }
    
    /* Method modified from http://stackoverflow.com/questions/12171584/what-is-the-fastest-way-to-count-set-bits-in-uint32-in-c-sharp 
    Counts the number of set bits in Levels */
    public static int CountBits(Levels value)
    {    
        int count = 0;
        while (value != 0)
        {
            count++;
            value &= value - 1;
        }
        return count;
    }
    

    【讨论】:

    • 感谢您的回复,但对于初学者来说似乎太复杂了
    • 我删除了单元测试并添加了链接以使解决方案更加清晰。在原始函数中,仅更改了 2 行代码(注意 PlayerPrefs.LevelState 只是一个整数变量)。这个想法是使用枚举来表示不同的级别。学习如何使用位运算符可以大大降低数据结构的复杂性。
    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 2017-09-21
    • 2017-03-24
    • 1970-01-01
    • 2019-11-18
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多