我正在努力制作一款简单的平台游戏。玩家是一个正方形,所有平台都是正方形。我是XNA的初学者,但我有适度的C#4.0体验。
我的代码存在的问题是,当我的角色穿过平台的底部时,即使我将其设置为不应该这样,他仍会继续经历。
事先我想问一下是否有人可以帮助我,因为我无法解决这个问题。
以下是不同的代码片段如何协同工作:
以下是碰撞的代码:
public bool[] environmentCollisionDetect(Charachter thing, ScreenObjects sreenobjectlist, bool[] platformstatus)
{
//Defaults the collision to false
platformstatus[0] = false; //Above platform
platformstatus[1] = false; //Below Platform
platformstatus[2] = false; //Left
platformstatus[3] = false; //Right
//Store the player in boxA
boxA.Height = thing.image.Height;
boxA.Width = thing.image.Width;
boxA.X = (int)thing.position.X;
boxA.Y = (int)thing.position.Y;
//Find a collision
foreach (Platform platform in screenobjectlist)
{
//Makes sure the platform cannot be passed through
if (platform.platformCollisionProperty != platformCollision.passable)
{
//Store the platform's rectangle
boxB = platform.destinationrectangle;
boxB.Height = platform.image.Height;
boxB.Width = platform.image.Width;
boxB.X = (int)platform.destinationrectangle.X;
boxB.Y = (int)platform.destinationrectangle.Y;
//Collision Check
if (boxA.Intersects(boxB))
{
switch (platform.platformCollisionProperty)
{
//Platform is Solid
case platformCollision.impassible:
//Player is below it
if (boxA.Top > boxB.Bottom)
{
platformstatus[1] = true;
}
//Player is above it
if (boxA.Bottom > boxB.Top)
{
platformstatus[0] = true;
}
break;
//Platform can be passed through bottom
case platformCollision.platform:
if (boxA.Bottom > boxB.Top)
{
platformstatus[0] = true;
}
break;
}
break;
}
}
}
return platformstatus;
}
这是垂直运动代码:
最后我被用作计数器,因为我无法使用计时器
public void verticalMotionI(GameTime gametime)
{
//Resets the bools if not standing on platform
if ((this.isJumping == true) && (this.platformstatus[0] == false))
{
this.i = 0;
this.isJumping = false;
this.isinair = false;
}
//Jumps if A button is activated and standing on a platform
else if ((this.isJumping == true) && (this.platformstatus[0] == true))
{
//Set up bools to jump
this.isJumping = false;
this.isinair = true;
//Overwrites the start time
this.starttime = currentime;
//Move up
this.position.Y -= this.playermovementspeed * 1.5f;
//Increase counter
this.i++;
}
//Pulls stops moving player if jumptimer had elapsed
else if ((this.isinair == true) && (i == this.jumptime))
{
this.isinair = false;
//Apply gravity
Gravity.forceofGravity(this);
}
//Stops the jump if bottom of a platform is hit
else if ((this.isinair == true) && (this.platformstatus[1] == true))
{
//Reset bools
this.isinair = false;
//reset I
this.i = 0;
//Apply gravity
Gravity.forceofGravity(this);
}
//Continues the jump if in air
else if ((this.isinair == true) && (this.platformstatus[1] == false))
{
//Move up
this.position.Y -= this.playermovementspeed * 1.5f;
//Increase counter
this.i++;
}
//Apply Gravity
else if ((this.isinair == false) && (this.platformstatus[0] == false))
{
//reset I
this.i = 0;
Gravity.forceofGravity(this);
}
}
答案 0 :(得分:0)
如果Gravity做了我的假设,看起来你没有明确设置玩家在撞击平台时的位置,我看到的是你的切换你的isInAir标志,并应用重力...出于测试目的和解决你的问题,试试像这样的伪代码:
if(dude is jumping & dude collides with platform){
set the top of dudes head to be at position under the platform;
}
希望这可以提供帮助。 :)
不要击败死马或屁股,但你正在重新发明轮子。看看那里的一些物理引擎。我一直在玩Farseer 3+,这太棒了。在第一次弄清楚World Body Fixture模式时会有一个轻微的学习曲线,但是一旦你有了顿悟,那么在你的身体/固定装置上设置一些属性并启动OnCollision方法将是蛋糕。
Farseer是一个面向.NET的Box2D物理引擎端口,它是开源的,一旦你完成学习曲线,它就太棒了。
快速查看this farseer doc,你可能会喜欢你所看到的。 :) 即使你不爱它,它也是开源的,可以给你一些关于如何*咳嗽*复制*实现一些功能的想法。
如果你想要的只是一个简单的跳跃,对象状态和交互功能,你就不需要实现引擎的所有有趣的复杂性,这些功能都很好地包含在Farseer中。
答案 1 :(得分:0)
if (boxA.Top > boxB.Bottom)
- 如果boxA.Intersects(boxB)
,这种情况永远不会成立。您的意思是if (boxA.Top < boxB.Bottom && boxA.Top > boxB.Center.Y)
吗?
将我的评论探索重新发布作为未来参考的答案。由于我有答案的空间而不是评论,我也可以解释一些事情。
显然,Rectangle.Intersects(Rectangle)
只有在某种程度上重叠时才会成立。诀窍在于,在解释时,我们需要记住屏幕上的Y坐标实际上是从上到下移动。 Y = 0位于屏幕顶部,Y =位于屏幕顶部。如果您不熟悉2D游戏编程,这可能看起来倒退,但这只是图形适配器的工作方式。
因此,通过说boxA的顶部是&gt;在boxB的底部,你真正说的是boxA的顶部位于屏幕上boxB的底部之下,由于我们已经知道它们重叠,因此永远不会是真的。我转过条件并添加了一个额外的逻辑点,以提供所需的功能。 boxA.Top > boxB.Center.Y
表示您的boxA特别与位于框B之间相交。如果我把它保留为boxA.Top < boxB.Bottom
,如果boxA从上面 boxB掉落,则条件也是如此,我认为你不认为我们必须区分平台和实体涉及到磁贴下方的播放器的逻辑块,因此我们必须在代码中进行区分。当然,您的评论也是//player is below it
。
最后,一句调试建议:如果您发现某些行为未发生,请在指示该行为的行(在本例中为platformstatus[1] = true
)放置一个断点。如果你从未打过那个断点,你就知道为什么它没有发生。现在只需在封闭的条件上放置一个断点。当它到达该断点时,手动查看值,将它们与预期值进行比较,并查看是否使用了适当的逻辑。每个人有时会在条件错误中出错,这是我个人的第一个弱点之一。