我的 2D 数组中的命中检测是取出随机的人而不是它命中的人

My Hit Detection in my 2D array is taking out random people instead of the ones it hits

嘿,所以我正在尝试在它们被击中后将初始生命值更改为 0。但是它改变了 2D 数组中的随机敌人并使它们消失而不是被击中的敌人。我已经评论了我的大部分代码,希望它能有所帮助:)
找不到具有相同问题的 post 抱歉,如果有...任何其他建议也很棒!谢谢

       public partial class Form1 : Form
    {
        //score & ammo
        int score = 0;
        int ammo = 5;

        //setting cannon
        int tank = 0;

        //mouse cords
        int mouseX = 0;
        int mouseY = 0;

        //Small boom 
        int Sboomx = -20;
        int Sboomy = -20;

        //random positions for enemys to spawn
        int MinX = 1020;
        int MaxX = 7020;
        int MinY = 350;
        int MaxY = 400;

        //speed of them
        int SpeedMinX = -7;
        int SpeedMaxX = -2;

        //array
        int[,] bads = new int[300, 5];
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //setting positions and loading in people
            Random randNum = new Random();

            for (int i = 0; i < 300; i++)
            {
                //where they go
                bads[i,0] = randNum.Next(MinX, MaxX);
                bads[i, 1] = randNum.Next(MinY, MaxY);
                //health
                bads[i, 2] = 1;

                //how they move
                //dx
                bads[i, 3] = randNum.Next(SpeedMinX, SpeedMaxX);
                //dy
                bads[i, 4] = 1;
            }         
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            //background
            e.Graphics.DrawImage(Properties.Resources.Background1, 0, 0, 1000, 500);

            //Aim
            e.Graphics.DrawImage(Properties.Resources.crosshair, mouseX - 10, mouseY - 10, 20, 20);

            //explotion
            e.Graphics.DrawImage(Properties.Resources.small, Sboomx - 285, Sboomy - 298, 600, 600);

            //Tank cannon        
            if (tank == 1)
            {
                e.Graphics.DrawImage(Properties.Resources.Tank__5__copy, 140, 335, 60, 60);
            }
            else if (tank == 2)
            {
                e.Graphics.DrawImage(Properties.Resources.Tank__10__copy, 140, 335, 60, 60);
            }
            else if (tank == 3)
            {
                e.Graphics.DrawImage(Properties.Resources.Tank__15__copy, 140, 335, 60, 60);
            }
            else if (tank == 4)
            {
                e.Graphics.DrawImage(Properties.Resources.Tank_0__copy, 140, 335, 60, 60);
            }

            //draw Bad guys
            for (int i = 0; i < 300; i++)
            {             
                    if (bads[i, 2] == 1)
                    {
                        e.Graphics.FillRectangle(Brushes.Black, bads[i, 0] , bads[i, 1], 10, 20);
                    }
            }
            //undrawthem
            for (int i = 0; i < 300; i++)
            {
                if (bads[i, 2] == 0)
                {
                    e.Graphics.FillRectangle(Brushes.Black, bads[i, 0], bads[i, 1], 0, 0);
                    Sboomx = -20;
                    Sboomy = -20;
                }
            }
        }

        //Timer
        private void timer1_Tick(object sender, EventArgs e)
        {
            //Collision 
            for (int i = 0; i < 300; i++)
            {
                if (Sboomx == bads[i, 0] || Sboomy == bads[i,1])
                {
                    bads[i, 2] = 0;
                    ammo++;
                    score = score + 5; ;
                }
            }

                //Score
            label2.Text = " " + score;

            //Ammo
            label1.Text = " " + ammo;

            //Moving enemys
            for (int i = 0; i < 300; i++)
            {
                bads[i, 0] = bads[i, 0] + bads[i, 3];
                bads[i, 1] = bads[i, 1] + bads[i, 4];
                if (bads[i, 0] > 2040 || bads[i, 0] < 140)
                {
                    bads[i, 3] = bads[i, 3] * -1;
                }
                if (bads[i, 1] > 335 || bads[i, 1] < 350)
                {
                    bads[i, 4] = bads[i, 4] * -1;
                }
            }
            this.Refresh();
        }

        private void label1_Click(object sender, EventArgs e)
        {
            //Ammo
        }

        private void label2_Click(object sender, EventArgs e)
        {
            //Customers served
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            //Control tank cannon
            mouseY = e.Y;
            mouseX = e.X;

            if (mouseY > 350 && mouseY < 375)
            {
                tank = 1;
            }
            else if (mouseY > 376 && mouseY < 390)
            {
                tank = 2;
            }
            else if (mouseY > 391)
            {
                tank = 3;
            }
            else if (mouseY <= 339)
            {
                tank = 4;
            }
        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {

        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            //creates explotion and takes away ammo
            Sboomx = e.X;
            Sboomy = e.Y;
            ammo--;
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            //moves explosion
            Sboomx = -20;
            Sboomy = -20;
        }

    }
}

如果我理解正确你想做什么,那么问题出在这一行:

if (Sboomx == bads[i, 0] || Sboomy == bads[i,1])

坏人是一个长方形,炸弹是一个点,你在这里做的是尝试将长方形的一个点与炸弹的 x 坐标相匹配 y坐标,也是错误的,你需要检查炸弹坐标是否那个矩形内。

此外,将“//Collision”循环移动到 Form1_MouseDown 事件以避免鼠标单击和计时器滴答之间的延迟是个好主意,尤其是因为您在 Form1_MouseUp事件。

另一件事,“//undrawthem”循环在这里没有逻辑,你正在绘制一个 0*0 尺寸的矩形(你认为它会调整现有矩形的大小吗?),当你调用 Refresh() , Invalidate() 被调用以使整个表面无效,然后 Update() 被调用以更新无效区域,所以当 Form1_Paint 事件被引发时整个表单图形被清除并重新绘制无论如何之前存在。

你可以考虑这个,不用Refresh(),用Invalidate(invalidate_area)Update(),这样就不会刷新整个surface:

Rectangle invalidate_area = new Rectangle(0, 0, 100, 50);
invalidate_area.Inflate(3, 3); //add extra bounds
Invalidate(invalidate_area);
Update();

但如果你这样做,你将需要处理死去的坏人,移动坏人(更新旧占领区和新占领区)等等。