C# 自定义事件

C# Custom Event

我有两个图片框。一个是我用 WASD 键移动的移动 PictureBox,另一个是随机生成的位置(敌人)。当我按下空格键时,移动的 PicBox 会抛出一个球,然后我希望当球与敌人碰撞时,敌人的 PicBox 会移除。我想创建一个事件来执行此操作,但我不知道该怎么做。你能帮助我吗?这是我的全部代码:

namespace Gioco
{
    public partial class Form1 : Form
    {
        Image img;
        Image tmpSx;
        Image tmpDx;
        Image tmpUp;
        Image tmpDw;
        List<PictureBox> fireBox = new List<PictureBox>();

        int count = 0;    //COUNT GLOBALE

        Timer tm = new Timer();
        bool go = true;                                      
        EventHandler test;

        EventHandler enemy;
        Timer tmEnem = new Timer();

        public Form1()
        {
            InitializeComponent();
            panel1.Controls.Add(pictureBox1);
            pictureBox1.Parent = panel1;
            img = pictureBox1.Image;
            tmpSx = (Image)img.Clone();
            tmpSx.RotateFlip(RotateFlipType.RotateNoneFlipX);
            tmpDx = (Image)img.Clone();
            tmpDw = (Image)img.Clone();
            tmpDw.RotateFlip(RotateFlipType.Rotate90FlipNone);
            tmpUp = (Image)img.Clone();
            tmpUp.RotateFlip(RotateFlipType.Rotate270FlipNone);

            //COMPARSA NEMICO

            tmEnem.Interval = 5000;
            enemy = new EventHandler(Appear);
            tmEnem.Tick += enemy;
            tmEnem.Start();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.D)
            {
                pictureBox1.Image = tmpDx;
                pictureBox1.Location = new Point(pictureBox1.Location.X + 15, pictureBox1.Location.Y);
                pictureBox1.SendToBack();
            }
            else if (e.KeyCode == Keys.A)
            {
                pictureBox1.Image = tmpSx;
                pictureBox1.Location = new Point(pictureBox1.Location.X - 15, pictureBox1.Location.Y);
                pictureBox1.SendToBack();
            }
            else if (e.KeyCode == Keys.W)
            {
                pictureBox1.Image = tmpUp;
                pictureBox1.Location = new Point(pictureBox1.Location.X, pictureBox1.Location.Y - 15);
                pictureBox1.SendToBack();
            }
            else if (e.KeyCode == Keys.S)
            {
                pictureBox1.Image = tmpDw;
                pictureBox1.Location = new Point(pictureBox1.Location.X, pictureBox1.Location.Y + 15);
                pictureBox1.SendToBack();
            }
            else if (e.KeyCode == Keys.Space)
            {
                if (go)
                {
                    Image fire = Image.FromFile(@"c:\users\user\documents\visual studio 2015\Projects\Gioco\Gioco\Resources4979.gif");
                    PictureBox picFire = new PictureBox();
                    fireBox.Add(picFire);
                    count++;
                    picFire.Image = fire;
                    picFire.Visible = true;
                    picFire.BackColor = Color.Transparent;
                    picFire.BringToFront();
                    picFire.SizeMode = PictureBoxSizeMode.Zoom;

                    switch (Direction(pictureBox1))
                    {
                        case "dx":
                            picFire.Location = new Point(pictureBox1.Location.X + pictureBox1.Width, pictureBox1.Location.Y + pictureBox1.Height / 2);
                            panel1.Controls.Add(picFire);
                            tm.Interval = 35;
                            test = new EventHandler(tm_TickDx);
                            tm.Tick += test;
                            tm.Start();
                            break;
                        case "sx":
                            picFire.Location = new Point(pictureBox1.Location.X - picFire.Width, pictureBox1.Location.Y + pictureBox1.Height / 2);
                            panel1.Controls.Add(picFire);
                            tm.Interval = 35;
                            test = new EventHandler(tm_TickSx);
                            tm.Tick += test;
                            tm.Start();
                            break;
                        case "up":
                            picFire.Location = new Point(pictureBox1.Location.X + pictureBox1.Width / 2, pictureBox1.Location.Y - picFire.Height);
                            panel1.Controls.Add(picFire);
                            tm.Interval = 35;
                            test = new EventHandler(tm_TickUp);
                            tm.Tick += test;
                            tm.Start();
                            break;
                        case "dw":
                            picFire.Location = new Point(pictureBox1.Location.X, pictureBox1.Location.Y + pictureBox1.Height);
                            panel1.Controls.Add(picFire);
                            tm.Interval = 35;
                            test = new EventHandler(tm_TickDw);
                            tm.Tick += test;
                            tm.Start();
                            break;
                    }

                }

            }
        }

        void Appear(object sender, EventArgs e)
        {           
                Image imgEnemy = Properties.Resources.tengu_warrior_enemy_sprite_by_sanctumpolis_d6wsk6q;
                PictureBox picEnemy = new PictureBox();
                picEnemy.SizeMode = PictureBoxSizeMode.Zoom;
                picEnemy.Image = imgEnemy;
                Random rand = new Random(DateTime.Now.Millisecond);
                Point random = new Point(rand.Next(0, ClientSize.Width - picEnemy.Width), rand.Next(0, ClientSize.Height - picEnemy.Height));
                picEnemy.Location = random;
                panel1.Controls.Add(picEnemy);

        }

        void tm_TickDx(object sender, EventArgs e)
        {
            go = false;
            if (!go)
            {
                if(fireBox[count - 1].Location.X < panel1.Location.X + panel1.Width)
                {
                    fireBox[count - 1].Left = fireBox[count - 1].Left + 25;
                }
                else
                {
                    tm.Stop();
                    go = true;
                    tm.Tick -= test;
                }

            }

        }

        void tm_TickSx(object sender, EventArgs e)
        {
            go = false;
            if (!go)
            {
                if (fireBox[count - 1].Location.X > panel1.Location.X - fireBox[count - 1].Width)
                    fireBox[count - 1].Left = fireBox[count - 1].Left - 25;
                else
                {
                    tm.Stop();
                    go = true;
                    tm.Tick -= test;
                }

            }

        }

        void tm_TickUp(object sender, EventArgs e)
        {
            go = false;
            if (!go)
            {
                if (fireBox[count - 1].Location.Y > panel1.Location.Y - fireBox[count - 1].Height)
                   fireBox[count - 1].Top = fireBox[count - 1].Top - 25;
                else
                {
                    tm.Stop();
                    go = true;
                    tm.Tick -= test;
                }

            }

        }

        void tm_TickDw(object sender, EventArgs e)
        {
            go = false;
            if (!go)
            {
                if (fireBox[count - 1].Location.Y < panel1.Location.Y + panel1.Height)
                    fireBox[count - 1].Top = fireBox[count - 1].Top + 25;
                else
                {
                    tm.Stop();
                    go = true;
                    tm.Tick -= test;
                }

            }

        }

        string Direction(PictureBox p)
        {
            if (p.Image == tmpDx)
                return "dx";
            else if (p.Image == tmpSx)
                return "sx";
            else if (p.Image == tmpUp)
                return "up";
            else if (p.Image == tmpDw)
                return "dw";
            return "dx";
        }

    }
}

正如他们在评论中所说:检查移动事件中的碰撞。
我发表了一些评论来描述它的工作原理。

到位how-to形象化

// Place this code for all of your move-events.
void tm_TickDx(object sender, EventArgs e)
{
    go = false;
    if (!go)
    {
        // Foreach control inside your panel
        foreach (Control enemie in panel1.Controls)
        {
            // If control is a PictureBox - preventing future features
            if(enemie.GetType() == typeof(PictureBox))
            {
                // Foreach fireball thats moving - could get filtered better
                foreach(Control fireball in fireBox)
                {
                    // If there IS a collision between enemie and fireball
                    if (enemie.Bounds.IntersectsWith(fireball.Bounds))
                    {
                        panel1.Controls.Remove(enemie);
                    }
                }
            }
        }
        if (fireBox[count - 1].Location.X < panel1.Location.X + panel1.Width)
        {
            fireBox[count - 1].Left = fireBox[count - 1].Left + 25;
        }
        else
        {
            tm.Stop();
            go = true;
            tm.Tick -= test;
        }

    }

}

更优雅的 linq 方式

void CheckCollision()
{
    // Get all enemies from playground
    var enemies = panel1.Controls.Cast<Control>();
    // Compare bounds of all fireboxes to bounds of enemies
    var colidedEnemies = enemies.Where(en =>
                         fireBox.Any(fb => fb.Bounds.IntersectsWith(en.Bounds)));

    // Delete all collided enemies
    colidedEnemies.ToList().ForEach(en => panel1.Controls.Remove(en));
}

void tm_TickDx(object sender, EventArgs e)
{
    go = false;
    if (!go)
    {
        // Check collision
        CheckCollision();
        if (fireBox[count - 1].Location.X < panel1.Location.X + panel1.Width)
        {
            fireBox[count - 1].Left = fireBox[count - 1].Left + 25;
        }
        else
        {
            tm.Stop();
            go = true;
            tm.Tick -= test;
        }

    }

}

void tm_TickSx(object sender, EventArgs e)
{
    go = false;
    if (!go)
    {
        // Check collision
        CheckCollision();
        if (fireBox[count - 1].Location.X > panel1.Location.X - fireBox[count - 1].Width)
            fireBox[count - 1].Left = fireBox[count - 1].Left - 25;
        else
        {
            tm.Stop();
            go = true;
            tm.Tick -= test;
        }

    }

}

void tm_TickUp(object sender, EventArgs e)
{
    go = false;
    if (!go)
    {
        // Check collision
        CheckCollision();
        if (fireBox[count - 1].Location.Y > panel1.Location.Y - fireBox[count - 1].Height)
            fireBox[count - 1].Top = fireBox[count - 1].Top - 25;
        else
        {
            tm.Stop();
            go = true;
            tm.Tick -= test;
        }

    }

}

void tm_TickDw(object sender, EventArgs e)
{
    go = false;
    if (!go)
    {
        // Check collision
        CheckCollision();
        if (fireBox[count - 1].Location.Y < panel1.Location.Y + panel1.Height)
            fireBox[count - 1].Top = fireBox[count - 1].Top + 25;
        else
        {
            tm.Stop();
            go = true;
            tm.Tick -= test;
        }
    }
}

学分:
How to check if two controls are overlapping in Windows Forms
LINQ query to find if items in a list are contained in another list