C#开发吃豆人游戏:硬币收集功能失效问题求助
C#吃豆人游戏硬币收集逻辑失效排查
我在C# WinForms开发吃豆人游戏时,尝试了两种硬币收集实现方法,但均未生效,不清楚问题出在哪里。以下是两种实现方法及部分项目源码,求排查是否存在遗漏步骤或需要提前完成的配置?
方法1
//collecting coins foreach(Control x in this.Controls) { if (x is PictureBox && x.Tag == "coin") { if (((PictureBox)x).Bounds.IntersectsWith(pacman.Bounds)) { this.Controls.Remove(x); //remove that point score++; // add to the score } } }
方法2
//collecting coins foreach(Control x in this.Controls) { if (x is PictureBox) { if ((string)x.Tag == "coin" && x.Visible == true) { if (pacman.Bounds.IntersectsWith(x.Bounds)) { score += 1; x.Visible = false; } } } }
部分项目源码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Pac_Man_Game_Clone { public partial class Form1 : Form { bool goup, godown, goright, goleft, isGameOver; int score, playerSpeed, redGhostSpeed, yellowGhostSpeed, pinkGhostX, pinkGhostY; public Form1() { InitializeComponent(); restGame(); } private void Form1_Load(object sender, EventArgs e) { } private void keyisdown(object sender, KeyEventArgs e) { if(e.KeyCode == Keys.Up) { goup= true; } if(e.KeyCode == Keys.Down) { godown= true; } if(e.KeyCode == Keys.Left) { goleft= true; } if(e.KeyCode == Keys.Right) { goright= true; } } private void keyisup(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Up) { goup = false; } if (e.KeyCode == Keys.Down) { godown = false; } if (e.KeyCode == Keys.Left) { goleft = false; } if (e.KeyCode == Keys.Right) { goright = false; } } private void mainGameTimer(object sender, EventArgs e) { txtScore.Text = "Score: " + score; //moving pacman if(goleft == true) { pacman.Left -= playerSpeed; pacman.Image = Properties.Resources.left; } if(goright == true) { pacman.Left += playerSpeed; pacman.Image = Properties.Resources.right; } if(godown == true) { pacman.Top += playerSpeed; pacman.Image = Properties.Resources.down; } if(goup == true) { pacman.Top -= playerSpeed; pacman.Image = Properties.Resources.Up; } //leaving the parameters //left and right if (pacman.Left < -10) { pacman.Left = 680; } if (pacman.Left > 680) { pacman.Left = -10; } //up and down if (pacman.Top < -10) { pacman.Top = 550; } if (pacman.Top > 550) { pacman.Top = -10; } //collecting coins foreach(Control x in this.Controls) { if (x is PictureBox) { if ((string)x.Tag == "coin" && x.Visible == true) { if (pacman.Bounds.IntersectsWith(x.Bounds)) { score += 1; x.Visible = false; } } } //runs through wall if ((string)x.Tag == "wall") { if (pacman.Bounds.IntersectsWith(x.Bounds)) { // run game over } } //bumps to ghost if ((string)x.Tag == "ghost") { if (pacman.Bounds.IntersectsWith(x.Bounds)) { // run game over } } } //moving ghosts redGhost.Left += redGhostSpeed; if (redGhost.Bounds.IntersectsWith(pictureBox1.Bounds) || redGhost.Bounds.IntersectsWith(pictureBox2.Bounds)) { redGhost.Left += redGhostSpeed; } if (score == int.MaxValue) { //run game over } } private void restGame() { txtScore.Text = "Score: 0"; score= 0; redGhostSpeed = 5; yellowGhostSpeed = 5; pinkGhostX = 5; pinkGhostY = 5; playerSpeed = 8; isGameOver= false; pacman.Left = 7; pacman.Top= 35; redGhost.Left = 219; redGhost.Top = 56; yellowGhost.Left = 450; yellowGhost.Top = 447; pinkGhost.Left = 521; pinkGhost.Top = 227; foreach(Control x in this.Controls) { if(x is PictureBox) { x.Visible= true; } } gameTimer.Start(); } private void gameOver(string message) { } }
可能的问题点排查
- 硬币Tag属性未正确配置:检查所有硬币PictureBox的Tag属性是否准确设置为
"coin",注意大小写完全匹配,代码中是严格字符串相等判断。 - 方法1的集合修改异常:方法1中在
foreach循环里直接调用this.Controls.Remove(x),会触发集合修改异常,导致代码中断执行,这是方法1失效的直接原因。 - 碰撞检测精度问题:
Bounds.IntersectsWith基于控件的矩形边界检测,如果Pacman或硬币有大量透明区域,可能视觉上接触但矩形未重叠。可以尝试缩小碰撞区域,比如取控件中心的小矩形进行检测:Rectangle pacmanHitbox = new Rectangle(pacman.Left + pacman.Width/4, pacman.Top + pacman.Height/4, pacman.Width/2, pacman.Height/2); Rectangle coinHitbox = new Rectangle(x.Left + x.Width/4, x.Top + x.Height/4, x.Width/2, x.Height/2); if(pacmanHitbox.IntersectsWith(coinHitbox)) - Timer事件未绑定:确认
gameTimer控件的Tick事件是否正确绑定到mainGameTimer方法,否则硬币收集逻辑不会被执行。 - 硬币控件的容器问题:如果硬币PictureBox不是直接放在Form的Controls集合中(比如放在Panel、GroupBox里),遍历
this.Controls会找不到这些硬币,需要遍历对应容器的Controls。 - Visible属性初始状态:方法2中判断了
x.Visible == true,确保硬币初始状态为可见,restGame方法中虽然重置了所有PictureBox可见,但要检查设计时硬币的Visible属性是否为true。
内容的提问来源于stack exchange,提问作者angelelham
相关产品推荐
相关产品推荐

