c# - 基于恒定不一致的运动
问题描述
我创建了一个角色类,在更新方法中,我使用了尽可能多的物理特性以使其真实地工作,并编辑值以使运动感觉良好。
我最近注意到当我向左和向右移动时,它以不同的速度移动,并且不知道这已经持续了多久。我在开头声明了所有大写命名变量常量,并为运动使用相同的常量,所以我不知道是什么原因造成的。
我已尽力找出问题所在并加以解决,但我一无所获。
我设置常量的开始:
const float GRAVITY = 1f;
const float AIR_SPEED_COEFFICIENT = 0.4f;
const float TERMINAL_AIR_HORIZONTAL_VELOCITY = 10f;
const float AIR_RESISTANCE = 0.97f;
const float FRICTION = 0.64f;
更新功能:
public void Update(Rectangle floor, GameWindow Window)
{
jumpFrameCounter++;
if (Keyboard.GetState().IsKeyDown(Keys.Up) || Keyboard.GetState().IsKeyDown(Keys.W))
{
if (jumpFrameCounter > 11 && jumpsUsed < amountOfJumps)
{
velocity.Y = -GRAVITY * 16 * jumpHeight;
jumpsUsed++;
jumpFrameCounter = 0;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X -= RUN_SPEED / 4;
}
else
{
velocity.X -= airSpeed * AIR_SPEED_COEFFICIENT;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X += RUN_SPEED / 4;
}
else
{
velocity.X += airSpeed * AIR_SPEED_COEFFICIENT;
}
}
if (velocity.X > 0.00001f || velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D) || Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A)))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X *= FRICTION;
}
else
{
velocity.X *= AIR_RESISTANCE;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Down) || Keyboard.GetState().IsKeyDown(Keys.S))
{
fastFall = true;
}
velocity.Y += GRAVITY * unfloatyness;
if (fastFall)
{
velocity.Y += 6 * GRAVITY;
}
if (hitbox.Bottom >= floor.Top)
{
if (velocity.X > RUN_SPEED * groundSpeed)
{
velocity.X = RUN_SPEED * groundSpeed;
}
else if (velocity.X < -RUN_SPEED * groundSpeed)
{
velocity.X = -RUN_SPEED * groundSpeed;
}
}
else
{
if (velocity.X > TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed)
{
velocity.X = TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed;
}
else if (velocity.X < -TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed)
{
velocity.X = -TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed;
}
}
position += velocity;
hitbox = new Rectangle((int)position.X, (int)position.Y, fighterTexture.Width, fighterTexture.Height);
if (hitbox.Bottom > floor.Top && velocity.Y > 0)
{
position.Y = floor.Top - fighterTexture.Height;
jumpsUsed = 0;
fastFall = false;
velocity.Y = -1f;
}
if (hitbox.Left < 0)
{
position.X = 0;
}
else if (hitbox.Right > Window.ClientBounds.Width)
{
position.X = Window.ClientBounds.Width - fighterTexture.Width;
}
if (hitbox.Top < 0)
{
position.Y = 0;
}
else if (hitbox.Bottom > Window.ClientBounds.Height)
{
position.Y = Window.ClientBounds.Bottom - fighterTexture.Height;
}
}
解决方案
这条线令人困惑。
因为 AND&&
的优先级高于 OR||
if (velocity.X > 0.00001f || velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D) || Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A)))
该声明将成为。
if (velocity.X > 0.00001f
||
(velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) )
|| Keyboard.GetState().IsKeyDown(Keys.D)
|| Keyboard.GetState().IsKeyDown(Keys.Left)
|| Keyboard.GetState().IsKeyDown(Keys.A)))
我假设您实际上想要:
if ( ( velocity.X > 0.00001f || (velocity.X < -0.00001f )
&&
(
! (Keyboard.GetState().IsKeyDown(Keys.Right)
|| Keyboard.GetState().IsKeyDown(Keys.D)
|| Keyboard.GetState().IsKeyDown(Keys.Left)
|| Keyboard.GetState().IsKeyDown(Keys.A)))
)
但是您没有对此发表任何评论,我不知道如何解释。这条线看起来像“如果 x 的速度几乎为零并且Left
, D
, 或被A
按下或Right
未被按下”然后将 X 设置为更大的值。
但是这条线与你描述的有冲突。
我最近注意到当我向左和向右移动时,它以不同的速度移动,并且不知道这已经持续了多久。
您希望 Left 和 Right 做同样的事情,但不是在代码中。
我的建议是“使用括号提高可读性”和“如果有超过 3 个条件要在一行中检查,请使用 bool”。
推荐阅读
- c# - 如何获取绑定到数据网格的列表的值
- javascript - Angular 6 - jsPDF -autotable - PDF 无法正确生成
- php - WP Job Manager 获得工作列表?
- ruby-on-rails - Uglifier:在 Heroku 上推送失败 - Rails 5.2.3
- angular - 使用自定义类中的 Angular MatDialog(不包含在 app.module.ts 中)
- react-native-android - REACT-NATİVE - jarsigner 错误:java.lang.RuntimeException:密钥库加载:密钥库被篡改,或密码不正确
- php - 如何在 STRIPE API 中获取客户的失败发票列表?
- java - 在这种情况下使用泛型时如何让spring注入正确的bean?
- git - 如果源(功能)分支在不久之后被删除,那么 --squash 合并和 --no-ff 合并之间有区别吗?
- node.js - 在 Node.js 项目中解析 OpenXML Office 文档