You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:20:21