如何为每个级别仅给出一次得分?

时间:2016-09-12 16:35:55

标签: c# unity3d scripting points multi-level

在我的游戏中,我有很多关卡。每个级别都有3个目标。为了在每个级别完成一个目标,玩家获得一个星级。所有星级玩家获得的所有级别的值都被保存为总数。现在问题我希望每个级别的每个目标只增加一次totalstars的值。例如,如果玩家第一次玩第1级并完成一个目标,他将获得1个总星,但是当他再次玩第一级并且再次完成相同的目标时总星的价值不应该增加。我怎么能这样做?我希望我说得够清楚.Below是其中一个目标。

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

3 个答案:

答案 0 :(得分:0)

执行此操作的最基本方法是创建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;}
}

并且在递增之前再次查询这些

我希望这会有所帮助

编辑:额外信息

所以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
   }

}

然后你的主要将所有这些级别添加到列表

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

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

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

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

https://mva.microsoft.com/

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

答案 1 :(得分:0)

有许多可能的解决方案。例如,您可以使用三个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 :(得分:-1)

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

枚举的支持类型是整数。整数是一系列位,(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;
}