游戏生命值计数器问题:跨窗体切换后生命值为何重置?
问题原因与解决方案
问题根源
你在Level2的Level2_Load方法里执行了Level1 l1 = new Level1();,这会创建一个全新的Level1窗体实例——这个新实例和玩家之前操作的、已经修改过score的Level1完全是两个独立对象。新实例的score是初始值3,所以不管之前Level1里的score被改成2、1还是0,这里拿到的永远是初始值。
修复方案
方案1:通过构造函数传递生命值(推荐)
这是最规范的做法,直接在打开Level2时把当前的score传递过去。
修改Level2代码:
private int score2; // 添加带参数的构造函数 public Level2(int currentScore) { InitializeComponent(); score2 = currentScore; } private void Level2_Load(object sender, EventArgs e) { // 删除原来创建Level1实例的代码 label2.Text = score2.ToString(); label1.Hide(); label2.Hide(); textLVL2 = labelLVL2.Text; len3 = textLVL2.Length; labelLVL2.Text = ""; timer1.Start(); player.Play(); }
修改Level1的点击事件(以错误答案的label3_Click为例,其他事件同理):
public void label3_Click(object sender, EventArgs e) { Thread.Sleep(200); score--; labelSouls.Text = score.ToString(); // 传递当前score给Level2 Level2 l2 = new Level2(score); l2.ShowDialog(); Hide(); }
方案2:使用静态变量存储全局生命值
如果生命值是全局共享的状态,可以把score定义为静态变量,这样所有Level1实例都会共享同一个值。
修改Level1代码:
// 将score改为静态字段 public static int score = 3; // 可选:如果需要从label初始化,在Load事件里处理 private void Level1_Load(object sender, EventArgs e) { if (!int.TryParse(labelSouls.Text, out score)) { score = 3; // 初始化默认值 } }
修改Level2代码:
private void Level2_Load(object sender, EventArgs e) { // 直接访问静态变量,无需创建新的Level1实例 score2 = Level1.score; label2.Text = score2.ToString(); // 其他原有代码保持不变 }
方案3:通过公共属性传递
和构造函数类似,给Level2添加一个公共属性,在创建实例后赋值。
修改Level2代码:
private int score2; // 定义公共属性 public int CurrentScore { get; set; } private void Level2_Load(object sender, EventArgs e) { score2 = CurrentScore; label2.Text = score2.ToString(); // 其他原有代码保持不变 }
修改Level1的点击事件:
public void label3_Click(object sender, EventArgs e) { Thread.Sleep(200); score--; labelSouls.Text = score.ToString(); Level2 l2 = new Level2(); l2.CurrentScore = score; // 给属性赋值 l2.ShowDialog(); Hide(); }
内容的提问来源于stack exchange,提问作者Kaydah
相关产品推荐
相关产品推荐

