好吧,所以我对XNA编程很新,我正在尝试编写平台游戏。我已经实现了像素完美的碰撞,但有时似乎没有明显的原因(我无法弄清楚模式)并且英雄精灵通过平台失败。
static bool IntersectsPixel(Rectangle rect1, Color[] data1, Rectangle rect2, Color[] data2)
{
int top = Math.Max (rect1.Top, rect2.Top);
int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
int left = Math.Max (rect1.Left,rect2.Left);
int right = Math.Min(rect1.Right,rect2.Right);
//Top
for(int y = top; y<bottom;y++)
for (int x = left; x < right; x++)
{
Color color1 = data1[x-rect1.Left + (y-rect1.Top) * rect1.Width];
Color color2 = data2[x - rect2.Left + (y - rect2.Top) * rect2.Width];
if (color1.A != 0 && color2.A != 0)
return true;
}
return false;
}
这是更新方法
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
foreach(Platform platform in platformList)
{
Rectangle check = new Rectangle(hero.GetRectangle().X - 300, hero.GetRectangle().Y - 300, 600, 600);
if(check.Intersects(platform.rectangle))
if (IntersectsPixel(hero.GetRectangle(), hero.textureData, platform.rectangle, platform.platformTextureData))
{
int direction = CheckDirection(platform,hero);
if (hero.hasJumped == true && direction == 3 && hero.velocity.Y <= 0 )
{
hero.velocity.Y = 0f;
hero.SetPosition(new Vector2((float)hero.GetPosition().X, (float)platform.rectangle.Bottom));
break;
}
else
if (direction == 4 && hero.velocity.X >= 0)
{
hero.velocity.X = 1;
hero.SetPosition(new Vector2((float)platform.rectangle.Left - (float)hero.GetRectangle().Width, (float)hero.GetPosition().Y));
break;
}
else
if (direction == 2 && hero.velocity.X <= 0)
{
hero.velocity.X = -1;
hero.SetPosition(new Vector2((float)platform.rectangle.Right - 1, (float)hero.GetPosition().Y));
break;
}
else
if (direction == 1 && hero.velocity.Y >= 0)
{
hero.velocity.Y = 0;
hero.hasJumped = false;
hero.SetPosition(new Vector2((float)hero.GetRectangle().X, (float)platform.rectangle.Y - (float)hero.GetRectangle().Height + 1));
hero.SetRectangle(new Rectangle((int)hero.GetPosition().X, (int)hero.GetPosition().Y, (int)hero.GetSize().X, (int)hero.GetSize().Y));
break;
}
}
}
hero.Update(gameTime);
camera.Update(gameTime, hero, screenBounds);
base.Update(gameTime);
}
这是方向检查:
private int CheckDirection(Platform platform,Hero hero)
{
int distance = Math.Abs(platform.rectangle.Top - hero.GetRectangle().Bottom);
int direction = 1; //Top
if (distance > Math.Abs(platform.rectangle.Right - hero.GetRectangle().Left))
{
distance = Math.Abs(platform.rectangle.Right - hero.GetRectangle().Left);
direction = 2;
}
if (distance > Math.Abs(platform.rectangle.Bottom - hero.GetRectangle().Top))
{
distance = Math.Abs(platform.rectangle.Bottom - hero.GetRectangle().Top);
direction = 3;
}
if (distance > Math.Abs(platform.rectangle.Left - hero.GetRectangle().Right))
{
direction = 4;
distance = Math.Abs(platform.rectangle.Left - hero.GetRectangle().Right);
}
return direction;
}
这些都是我与碰撞检测相关的功能。如果您碰巧有任何可能导致此问题的想法,请告诉我。
非常感谢!
答案 0 :(得分:0)
我看到的一件事可能是一个可能的原因,就是在开头围绕两个对象构建一个盒子:
int top = Math.Max (rect1.Top, rect2.Top);
int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
int left = Math.Max (rect1.Left,rect2.Left);
int right = Math.Min(rect1.Right,rect2.Right);
除非你翻转它,否则通常XNA的Y会随着你的下降(而不是上升)而变得正面。这意味着你实际上想要获取最大底部和最小顶部,因为Top总是小于底部。看起来你已经知道了这条线的外观:
for(int y = top; y<bottom;y++)
我会继续寻找(没有实际项目就很难测试)。我给你的另一个建议是做一些调试绘图。绘制交点函数认为像素正在触摸或未触摸的位置。
答案 1 :(得分:0)
由于滞后,你的角色移动的速度可能超过每帧的块高度,因此碰撞可能会认为它在块之间,并导致它飞过。
https://gamedev.stackexchange.com/questions/30458/platformer-starter-kit-collision-issues
检查出来,它解决了我的问题。
要么减慢移动速度,要么将位置变化固定到块的大小,应该可以解决这个问题。