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
我有两个图片框。一个是我用 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