gpt4 book ai didi

c# - XNA 不跳平台

转载 作者:太空宇宙 更新时间:2023-11-03 13:19:14 26 4
gpt4 key购买 nike

我正在使用 XNA 开发我的游戏。我从YouTube上找到了Oyyou的一系列教程,目前已经转到碰撞教程了。我已经成功地处理了重力、运动和动画。但是我遇到了碰撞问题。我角色的重生点悬而未决。 enter image description here

第一个值是我的 bool hasJumped。第二个是 y 速度。它正在加速 0.25。角色正在缓慢加速下落。所有四个平台都是以相同的方式制作的。所有四个都在列表中,我没有做任何特别与他们中的任何一个一起工作的东西。

enter image description here

当我降落在最低点(地面)时,我得到了我需要的参数。 hasJumped 为 false,velocity.Y 为 0。

enter image description here

但是当我在三个非地面平台之一上时,结果并不如我所愿。速度是 0.25,即使我将它设为 0。并且 hasJumped 不会变为真,因为我的速度是一个非零变量。不幸的是我不能发布图片,所以我不能展示它。但我会发布我的代码:这是我添加玩家和平台的主游戏类。

 protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

player = new Animation(Content.Load<Texture2D>("player"), Content.Load<Texture2D>("rect"), new Vector2(300 + 28, graphics.PreferredBackBufferHeight - 500), 47, 44, graphics.PreferredBackBufferHeight, graphics.PreferredBackBufferWidth);
platformList.Add(new Platform(Content.Load<Texture2D>("Crate"), new Vector2(300,graphics.PreferredBackBufferHeight-100), 80,50));
platformList.Add(new Platform(Content.Load<Texture2D>("Crate"), new Vector2(500, graphics.PreferredBackBufferHeight - 50), 80, 50));
platformList.Add(new Platform(Content.Load<Texture2D>("Crate"), new Vector2(700, graphics.PreferredBackBufferHeight - 60),80,50));
platformList.Add(new Platform(Content.Load<Texture2D>("Crate"), new Vector2(0, graphics.PreferredBackBufferHeight - 10), graphics.PreferredBackBufferWidth, 10));
// TODO: use this.Content to load your game content here
}

这是我的动画类:

class Animation
{
Texture2D texture;
Texture2D rectText;
public Rectangle rectangle;
public Rectangle collisionRect;

public Vector2 position;
Vector2 origin;
public Vector2 velocity;

int currentFrame;
int frameHeight;
int frameWidth;
int screenHeight;
int screenWidth;

float timer;
float interval = 60;

bool movingRight;
public bool hasJumped;

public Animation(Texture2D newTexture, Texture2D newRectText, Vector2 newPosition, int newHeight, int newWidth, int screenH, int screenW)
{
rectText = newRectText;
texture = newTexture;
position = newPosition;
frameHeight = newHeight;
frameWidth = newWidth;
screenHeight = screenH;
screenWidth = screenW;
hasJumped = true;
}

public void Update(GameTime gameTime)
{
rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
collisionRect = new Rectangle((int)position.X-frameWidth/2, (int)position.Y - frameHeight/2, frameWidth, frameHeight);
origin = new Vector2(rectangle.Width / 2, rectangle.Height / 2);
position = position + velocity;


if (Keyboard.GetState().IsKeyDown(Keys.Right))
{
AnimateRight(gameTime);
velocity.X = 5;
movingRight = true;
}
else if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
AnimateLeft(gameTime);
velocity.X = -5;
movingRight = false;
}
else
{
velocity.X = 0f;
if (movingRight)
currentFrame = 0;
else currentFrame = 4;
}


if(Keyboard.GetState().IsKeyDown(Keys.Space) && !hasJumped)
{
position.Y -= 5f;
velocity.Y = -10;
hasJumped = true;
}

if(hasJumped)
{
velocity.Y += 0.25f;
}


if(position.X<0+frameWidth/2)
{
position.X = 0 + frameWidth / 2;
}
else if (position.X>screenWidth-frameWidth/2)
{
position.X = screenWidth - frameWidth / 2;
}
}

public void AnimateRight(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds/2;
if(timer>interval)
{
currentFrame++;
timer = 0;
if (currentFrame > 3)
{
currentFrame = 0;
}
}
}

public void AnimateLeft(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
if (timer > interval)
{
currentFrame++;
timer = 0;
if (currentFrame > 7 || currentFrame < 4)
{
currentFrame = 4;
}
}
}

public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture,position,rectangle,Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
// spriteBatch.Draw(rectText,collisionRect,Color.White);
}
}}

平台类非常简单:

class Platform
{
Texture2D texture;
Vector2 position;
public Rectangle rectangle;



public Platform(Texture2D newTexture, Vector2 newPosition, int platformWidth, int platformHeight)
{
texture = newTexture;
position = newPosition;

rectangle = new Rectangle((int)position.X, (int)position.Y, platformWidth, platformHeight);
}

public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, rectangle, Color.White);

}
}

和碰撞方法:

public static bool isOnTopOf(this Rectangle r1, Rectangle r2)
{
return (r1.Bottom >= r2.Top - 10 &&
r1.Bottom <= r2.Top + 10 &&
r1.Right >= r2.Left + 10 &&
r1.Left <= r2.Right - 10);
}

问题应该出在这里:

foreach (Platform a in platformList)
{
if (player.collisionRect.isOnTopOf(a.rectangle) && player.velocity.Y>=0)
{
player.hasJumped = false;
player.velocity.Y = 0f;

if(player.collisionRect.Bottom > a.rectangle.Top || player.collisionRect.Bottom - a.rectangle.Top <=10)
{
player.position.Y = a.rectangle.Y - 48 / 2;
player.hasJumped = false;

}
}

else
{
player.hasJumped = true;
}
}

但如果我排除最后一个 else,它就不会从平台上掉下来。

感谢您提出问题。我添加了图像。

最佳答案

您的问题是,当用户位于不是最低平台的平台之上时,在检查用户是否在平台上的 else 期间,您显式地将 hasJumped 设置为 true。

您必须做的是在您的 foreach 中检查您的平台,通过增加 Y 坐标(很大程度上取决于您的相机设置)对它们进行排序,并在将 hasJumped 设置为 false 后中断。这样你就可以避免你的问题:

foreach (Platform a in platformList.OrderByY())
{
if (player.collisionRect.isOnTopOf(a.rectangle) && player.velocity.Y>=0)
{
player.hasJumped = false;
player.velocity.Y = 0f;

if(player.collisionRect.Bottom > a.rectangle.Top || player.collisionRect.Bottom - a.rectangle.Top <=10)
{
player.position.Y = a.rectangle.Y - 48 / 2;
player.hasJumped = false;
}

break;
}
else
{
player.hasJumped = true;
}
}

不幸的是,在 3D 开发中,我们经常需要做一些 hack 才能使应用程序正确呈现。在使用高级透明度渲染复杂项目时尤其如此。但是,对于您的情况,我建议您重新想象您处理碰撞的方式。

游戏开发不是一件容易的事。从表面上看,您工作的约束强制实现了一个不太理想的架构。 XNA 游戏中的一切都围绕更新循环进行,控制哪个项目首先更新的能力是如此简单和诱人,以至于人们倾向于使用它。然而,通常以一种让您的模型以事件驱动的方式运行的方式来尝试和推断功能是一种更好的方法。实现这一目标的一种方法是将游戏的更新周期分为以下几个阶段:

  1. 输入阶段:检索用户的输入并将其作为事件处理(这些可以是对项目的简单方法调用,而不是更新或更复杂但更好的方法,如使用 Rx)
  2. 运动阶段:培养模型的一些物理特性(加速度、速度、重量等),让它们在运动阶段自行定位、旋转。这是他们在更新中唯一应该做的事情。
  3. 碰撞阶段:测试碰撞,然后在对象上触发事件以处理碰撞。
  4. 清理阶段:清理任何问题,例如在碰撞检测阶段在墙内移动。或逐步淘汰粒子等。当您需要绘制精确像素以避免模糊等时,这会变得很重要。

上述方法不一定是最好的方法,但它确实有效。如果你只依赖于更新周期,你很快就会达到模型之间的相互依赖性和按顺序触发一些事件的要求将成为支持的噩梦。实现事件驱动机制将使您免于大量废弃工作,而且初始开销非常小。

我建议使用 Rx 对于 XNA 游戏来说可能听起来有点奇怪,但请相信我,这是处理事件的绝佳方式。最后想提一下MonoGame ,一个出色的框架,可以为 Windows、Mac、Linux、Android、iPhone、Windows Phone、WinRT(甚至更多)开发游戏,如果您还不知道的话。

关于c# - XNA 不跳平台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24960150/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com