如何在每个关卡只给一次分数

本文关键字:一次 | 更新日期: 2023-09-27 18:06:44

在我的游戏中我有许多关卡。每个关卡有3个目标。在每个关卡中完成一个目标,玩家将获得一颗星。玩家在所有关卡中获得的所有星星的价值被保存为总星星。现在的问题是,我只想为每个关卡中的每个目标增加一次totalstars的值。例如,如果玩家第一次玩第1关并完成了一个目标,他将获得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();
}

如何在每个关卡只给一次分数

有很多可能的解决方案。例如,您可以使用三个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;
}

最基本的方法是创建一个N * 3 (N是关卡的数量)数组。对于布尔值。所以它会像这样

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

然后在递增时检查它们是否已经获得了星号

你可以使用一个更动态的结构,或者在每一层使用一个对象,它有这些你可以查询的bool。在这一层,你会看到

CompletedObjectives objectives{get; set;}

和完成的目标看起来像

Public class CompletedObjectives
{
bool ObjectiveOne {get ;set;}
bool ObjectiveTwo {get ;set;}
bool ObjectiveThree {get ;set;}
}
在 加1之前再查询这些

我希望这对你有帮助

编辑:EXTRA INFO

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

那么下一步就是设置关卡

所以第一级的例子

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

那么你的主程序将把所有这些关卡添加到List

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

所以当你第一次从列表中调用level1时,所有目标都是假的,当它们完成时,你将它们的值更改为真,并增加总星星,第二次如果它们为真,你不增加。

如果您需要更多的帮助,请随时询问上面的代码是一个粗略的大纲,以解释这可以做到的基本方式。他们有更先进的方法,提供更多的好处,但你必须从某个地方开始。

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

https://mva.microsoft.com/

youtube也是学习基础编程的一个很好的资源。他们有很多书,特别是关于面向对象的,这将帮助你更好地设计你的类/接口等。

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

enum的后端类型为整型。整数是一串位(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

下面的示例使用enum来存储级别状态。

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