碰撞检测和停止运动
Collision detection and stop movement
我正在制作一个简单的游戏。我设法用箭头键和开火让我的角色移动。我在地图上添加了一些墙,它们是图片框。我设法检测到这样的碰撞:
private void timer6_Tick(object sender, EventArgs e){
foreach (PictureBox pic in brick){
if (pic.Bounds.IntersectsWith(pb_sprite.Bounds)){
Console.WriteLine("Colision!");
switch (rotation){
case "up":
canup = false;
candown = true;
canleft = true;
canright = true;
break;
case "down":
canup = true;
candown = false;
canleft = true;
canright = true;
break;
case "left":
candown = true;
canup = true;
canleft = false;
canright = true;
break;
case "right":
candown = true;
canup = true;
canleft = true;
canright = false;
break;
}
}
else
{
Console.WriteLine("No colision?!");
}
}
}
它按预期工作,但是当我撞到物体(墙)时,我得到 "Colision!" 回声,没关系,这也停止了在碰撞发生时角色所面对的方向的移动。问题是当我退出碰撞时,其中一个布尔值保持为假,这会阻止我的角色再次向同一方向移动。我尝试在 else 分支中将所有这些 bools 设置为 true 但是因为即使有碰撞也有五堵墙 else 分支执行了 5 次中的 4 次。我需要某种 "any" 函数来检查是否没有或任何墙壁正在被击中。
我不是 100% 确定您的意思,但我认为这可能会有所帮助:
canup = true;
candown = true;
canleft = true;
canright = true;
foreach (PictureBox pic in brick)
{
if (pic.Bounds.IntersectsWith(pb_sprite.Bounds))
{
Console.WriteLine("Colision!");
switch (rotation)
{
case "up":
canup = false;
break;
case "down":
candown = false;
break;
case "left":
canleft = false;
break;
case "right":
canright = false;
break;
}
}
else
{
Console.WriteLine("No colision?!");
}
...
这会在开始时将所有布尔值设置为真,并且仅在循环内将单个布尔值设置为假。
有没有可能,你只是停止你的角色,而不是解决碰撞?砖块和角色在彼此内部,毕竟要触发碰撞。它们需要移到彼此之外才能再次无碰撞。
常用的方法是把角色的位置往后拉一帧,或者如果你想更精确的话,找出角色在砖块里钻了多深(͡° ͜ʖ ͡°)然后沿着它来自那个数量的方向。
嗯,实际上有一个 Any
函数 (https://msdn.microsoft.com/en-us/library/bb534972(v=vs.110).aspx)。
你可以像这样使用它:
bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
case "up":
canup = !collision;
break;
...
}
我正在制作一个简单的游戏。我设法用箭头键和开火让我的角色移动。我在地图上添加了一些墙,它们是图片框。我设法检测到这样的碰撞:
private void timer6_Tick(object sender, EventArgs e){
foreach (PictureBox pic in brick){
if (pic.Bounds.IntersectsWith(pb_sprite.Bounds)){
Console.WriteLine("Colision!");
switch (rotation){
case "up":
canup = false;
candown = true;
canleft = true;
canright = true;
break;
case "down":
canup = true;
candown = false;
canleft = true;
canright = true;
break;
case "left":
candown = true;
canup = true;
canleft = false;
canright = true;
break;
case "right":
candown = true;
canup = true;
canleft = true;
canright = false;
break;
}
}
else
{
Console.WriteLine("No colision?!");
}
}
}
它按预期工作,但是当我撞到物体(墙)时,我得到 "Colision!" 回声,没关系,这也停止了在碰撞发生时角色所面对的方向的移动。问题是当我退出碰撞时,其中一个布尔值保持为假,这会阻止我的角色再次向同一方向移动。我尝试在 else 分支中将所有这些 bools 设置为 true 但是因为即使有碰撞也有五堵墙 else 分支执行了 5 次中的 4 次。我需要某种 "any" 函数来检查是否没有或任何墙壁正在被击中。
我不是 100% 确定您的意思,但我认为这可能会有所帮助:
canup = true;
candown = true;
canleft = true;
canright = true;
foreach (PictureBox pic in brick)
{
if (pic.Bounds.IntersectsWith(pb_sprite.Bounds))
{
Console.WriteLine("Colision!");
switch (rotation)
{
case "up":
canup = false;
break;
case "down":
candown = false;
break;
case "left":
canleft = false;
break;
case "right":
canright = false;
break;
}
}
else
{
Console.WriteLine("No colision?!");
}
...
这会在开始时将所有布尔值设置为真,并且仅在循环内将单个布尔值设置为假。
有没有可能,你只是停止你的角色,而不是解决碰撞?砖块和角色在彼此内部,毕竟要触发碰撞。它们需要移到彼此之外才能再次无碰撞。
常用的方法是把角色的位置往后拉一帧,或者如果你想更精确的话,找出角色在砖块里钻了多深(͡° ͜ʖ ͡°)然后沿着它来自那个数量的方向。
嗯,实际上有一个 Any
函数 (https://msdn.microsoft.com/en-us/library/bb534972(v=vs.110).aspx)。
你可以像这样使用它:
bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
case "up":
canup = !collision;
break;
...
}