我的 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();
但如果你这样做,你将需要处理死去的坏人,移动坏人(更新旧占领区和新占领区)等等。
嘿,所以我正在尝试在它们被击中后将初始生命值更改为 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();
但如果你这样做,你将需要处理死去的坏人,移动坏人(更新旧占领区和新占领区)等等。