如何改进我的碰撞逻辑
How to improve my collision logic
我正在开发一款游戏,我想为其创建一个简单的碰撞引擎。该游戏是 2D 的,基于图块的,并且其中只有一个玩家角色。我正在使用 Monogame (C#) 创建它。
这是我的代码:
static class character
{
public static Rectangle currentCharacterRectangle = new Rectangle(0, 0, Game1.human.Width, Game1.human.Height);
public static Rectangle futureCharacterRectangle = currentCharacterRectangle;
public static Vector2 currentRespawnPos;
public static Vector2 currentCharacterVelocity;
public static Vector2 currentCharacterAcceleration;
public static int walkingSpeed = 1;
public static int runningSpeed = 3;
static int jumpSpeed = -14;
static bool isJumping = false;
static bool willBeColliding = false;
static void getFutureRectangle()
{
if (Game1.currentKeyboardState.IsKeyDown(Keys.D))
{
futureCharacterRectangle.X += walkingSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.D) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
futureCharacterRectangle.X += runningSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q))
{
futureCharacterRectangle.X -= walkingSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
futureCharacterRectangle.X -= runningSpeed;
}
if(Game1.currentKeyboardState.IsKeyDown(Keys.Space) && Game1.previousKeyboardState.IsKeyUp(Keys.Space))
{
isJumping = true;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.S))
{
futureCharacterRectangle.Y++;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Z))
{
futureCharacterRectangle.Y--;
}
}
public static void jump()
{
if (jumpSpeed <= 14 && isJumping)
{
futureCharacterRectangle.Y += jumpSpeed;
jumpSpeed++;
}
else if (jumpSpeed > 14)
{
isJumping = false;
jumpSpeed = -14;
}
}
public static void Update()
{
jump();
getFutureRectangle();
foreach(earthTile Tile in gameWorld.tileArray)
{
if(futureCharacterRectangle.Intersects(Tile.currentRectangle))
{
willBeColliding = true;
}
}
if(!willBeColliding)
{
currentCharacterRectangle = futureCharacterRectangle;
}
futureCharacterRectangle = currentCharacterRectangle;
willBeColliding = false;
}
public static void Draw()
{
Game1.spriteBatch.Draw(Game1.human, currentCharacterRectangle, Color.White);
}
}
我想知道是否有更好的方法(可能更简单,或更快,或两者兼而有之)。
非常感谢!
没关系,已找到解决方案:
static void move()
{
if (Game1.currentKeyboardState.IsKeyDown(Keys.D))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Right >= Tile.currentRectangle.Left && currentCharacterRectangle.Left < Tile.currentRectangle.Right && currentCharacterRectangle.Top < Tile.currentRectangle.Bottom && currentCharacterRectangle.Bottom > Tile.currentRectangle.Top && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.X += walkingSpeed;
}
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.D) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
currentCharacterRectangle.X += runningSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Left <= Tile.currentRectangle.Right && currentCharacterRectangle.Right > Tile.currentRectangle.Left && currentCharacterRectangle.Top < Tile.currentRectangle.Bottom && currentCharacterRectangle.Bottom > Tile.currentRectangle.Top && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.X -= walkingSpeed;
}
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
currentCharacterRectangle.X -= runningSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.S))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Bottom >= Tile.currentRectangle.Top && currentCharacterRectangle.Top < Tile.currentRectangle.Bottom && currentCharacterRectangle.Right > Tile.currentRectangle.Left && currentCharacterRectangle.Left < Tile.currentRectangle.Right && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.Y++;
}
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Z))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Top <= Tile.currentRectangle.Bottom && currentCharacterRectangle.Top > Tile.currentRectangle.Top && currentCharacterRectangle.Right > Tile.currentRectangle.Left && currentCharacterRectangle.Left < Tile.currentRectangle.Right && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.Y--;
}
}
}
我正在开发一款游戏,我想为其创建一个简单的碰撞引擎。该游戏是 2D 的,基于图块的,并且其中只有一个玩家角色。我正在使用 Monogame (C#) 创建它。
这是我的代码:
static class character
{
public static Rectangle currentCharacterRectangle = new Rectangle(0, 0, Game1.human.Width, Game1.human.Height);
public static Rectangle futureCharacterRectangle = currentCharacterRectangle;
public static Vector2 currentRespawnPos;
public static Vector2 currentCharacterVelocity;
public static Vector2 currentCharacterAcceleration;
public static int walkingSpeed = 1;
public static int runningSpeed = 3;
static int jumpSpeed = -14;
static bool isJumping = false;
static bool willBeColliding = false;
static void getFutureRectangle()
{
if (Game1.currentKeyboardState.IsKeyDown(Keys.D))
{
futureCharacterRectangle.X += walkingSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.D) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
futureCharacterRectangle.X += runningSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q))
{
futureCharacterRectangle.X -= walkingSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
futureCharacterRectangle.X -= runningSpeed;
}
if(Game1.currentKeyboardState.IsKeyDown(Keys.Space) && Game1.previousKeyboardState.IsKeyUp(Keys.Space))
{
isJumping = true;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.S))
{
futureCharacterRectangle.Y++;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Z))
{
futureCharacterRectangle.Y--;
}
}
public static void jump()
{
if (jumpSpeed <= 14 && isJumping)
{
futureCharacterRectangle.Y += jumpSpeed;
jumpSpeed++;
}
else if (jumpSpeed > 14)
{
isJumping = false;
jumpSpeed = -14;
}
}
public static void Update()
{
jump();
getFutureRectangle();
foreach(earthTile Tile in gameWorld.tileArray)
{
if(futureCharacterRectangle.Intersects(Tile.currentRectangle))
{
willBeColliding = true;
}
}
if(!willBeColliding)
{
currentCharacterRectangle = futureCharacterRectangle;
}
futureCharacterRectangle = currentCharacterRectangle;
willBeColliding = false;
}
public static void Draw()
{
Game1.spriteBatch.Draw(Game1.human, currentCharacterRectangle, Color.White);
}
}
我想知道是否有更好的方法(可能更简单,或更快,或两者兼而有之)。
非常感谢!
没关系,已找到解决方案:
static void move()
{
if (Game1.currentKeyboardState.IsKeyDown(Keys.D))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Right >= Tile.currentRectangle.Left && currentCharacterRectangle.Left < Tile.currentRectangle.Right && currentCharacterRectangle.Top < Tile.currentRectangle.Bottom && currentCharacterRectangle.Bottom > Tile.currentRectangle.Top && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.X += walkingSpeed;
}
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.D) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
currentCharacterRectangle.X += runningSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Left <= Tile.currentRectangle.Right && currentCharacterRectangle.Right > Tile.currentRectangle.Left && currentCharacterRectangle.Top < Tile.currentRectangle.Bottom && currentCharacterRectangle.Bottom > Tile.currentRectangle.Top && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.X -= walkingSpeed;
}
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Q) && Game1.currentKeyboardState.IsKeyDown(Keys.LeftShift))
{
currentCharacterRectangle.X -= runningSpeed;
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.S))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Bottom >= Tile.currentRectangle.Top && currentCharacterRectangle.Top < Tile.currentRectangle.Bottom && currentCharacterRectangle.Right > Tile.currentRectangle.Left && currentCharacterRectangle.Left < Tile.currentRectangle.Right && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.Y++;
}
}
if (Game1.currentKeyboardState.IsKeyDown(Keys.Z))
{
bool isColliding = false;
foreach (tile Tile in gameWorld.tileArray)
{
if (currentCharacterRectangle.Top <= Tile.currentRectangle.Bottom && currentCharacterRectangle.Top > Tile.currentRectangle.Top && currentCharacterRectangle.Right > Tile.currentRectangle.Left && currentCharacterRectangle.Left < Tile.currentRectangle.Right && Tile.isSolid)
{
isColliding = true;
}
}
if (!isColliding)
{
currentCharacterRectangle.Y--;
}
}
}