我一直在研究C#& SFML翻拍了我的一个LWJGL引擎。到目前为止,它很棒,但是,当我尝试复制/转换我的碰撞代码时,事情并没有那么顺利。
这是我的播放器/实体类,边界框和游戏代码的代码。
实体:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Graphics;
using SFML.System;
using SFML.Window;
namespace FastSrc_CS.Core
{
public class FSEntity
{
public Vector2f Position, Size;
public Color EColor;
public RectangleShape sprite;
public BoundingBox Bounds;
public bool canMove;
public float VelX, VelY;
public FSEntity()
{
}
public virtual void Init(Vector2f pos, Vector2f size, Color color)
{
Position = pos;
Size = size;
EColor = color;
sprite = new RectangleShape();
sprite.FillColor = EColor;
sprite.Position = Position;
sprite.Size = Size;
//sprite.Origin = new Vector2f(size.X / 2, size.Y / 2);
Bounds = new BoundingBox(Position, Size);
}
public void SetVelX(float x)
{
VelX = x;
}
public void SetVelY(float x)
{
VelY = x;
}
public Vector2f GetOrigin()
{
return new Vector2f(Size.X / 2, Size.Y / 2);
}
public virtual void Update()
{
}
public void UpdatePos()
{
Position.X += VelX;
Position.Y += VelY;
sprite.Position = Position;
Bounds.UpdateBounds(Position, Size);
}
public virtual void Render(RenderWindow w)
{
w.Draw(sprite);
}
}
}
播放器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Graphics;
using SFML.System;
using SFML.Window;
namespace FastSrc_CS
{
class Player : Core.FSEntity
{
public float speed = 6f;
public override void Init(Vector2f pos, Vector2f size, Color color)
{
canMove = true;
base.Init(pos, size, color);
}
public override void Update()
{
base.Update();
Movement();
Position.X += VelX;
Position.Y += VelY;
sprite.Position = Position;
Bounds.UpdateBounds(Position, Size);
}
public void Movement()
{
if (Keyboard.IsKeyPressed(Keyboard.Key.A) && canMove == true)
{
SetVelX(-speed);
SetVelY(0);
}
else if (Keyboard.IsKeyPressed(Keyboard.Key.D) && canMove == true)
{
SetVelX(speed);
SetVelY(0);
}
else if (Keyboard.IsKeyPressed(Keyboard.Key.W) && canMove == true)
{
SetVelY(-speed);
SetVelX(0);
}
else if (Keyboard.IsKeyPressed(Keyboard.Key.S) && canMove == true)
{
SetVelY(speed);
SetVelX(0);
}
else
{
SetVelX(0);
SetVelY(0);
}
}
public override void Render(RenderWindow w)
{
base.Render(w);
}
}
}
边界框:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Graphics;
using SFML.System;
using SFML.Window;
namespace FastSrc_CS.Core
{
public class BoundingBox
{
public FloatRect Rectangle;
public BoundingBox(Vector2f pos, Vector2f size)
{
Rectangle = new FloatRect(pos, size);
}
public bool Collide(BoundingBox b)
{
bool col = false;
if (this.Rectangle.Intersects(b.Rectangle))
{
col = true;
}
else
{
col = false;
}
return col;
}
public void UpdateBounds(Vector2f pos, Vector2f size)
{
Rectangle.Width = size.X;
Rectangle.Height = size.Y;
Rectangle.Left = pos.X;
Rectangle.Top = pos.Y;
}
}
}
游戏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FastSrc_CS.Core;
using SFML.Graphics;
using SFML.System;
using SFML.Window;
namespace FastSrc_CS
{
public class Game : FSGame
{
Player p = new Player();
Wall w = new Wall();
public override void Init()
{
p.Init(new Vector2f(400, 300), new Vector2f(32, 32), Color.Red);
w.Init(new Vector2f(100, 100), new Vector2f(32, 32), Color.Blue);
Entities.Add(p);
Entities.Add(w);
}
public override void Update()
{
Console.WriteLine(p.Position.X);
//COLLISION CODE FOR WALLS
if (p.Bounds.Collide(w.Bounds))
{
//Right Collision
if (p.VelX > 0)
{
Console.WriteLine("Right Collision");
p.canMove = false;
p.Position.X = w.Position.X - 32;
p.SetVelX(0);
}
else if (p.VelX < 0)
{
Console.WriteLine("Left Collision");
p.canMove = false;
p.Position.X = w.Position.X + 32;
p.SetVelX(0);
}
if (p.VelX == 0)
{
p.canMove = true;
}
}
Entities.ForEach(k => k.Update());
}
public override void Render(RenderWindow w)
{
Entities.ForEach(k => k.Render(w));
}
}
}
问题在于游戏&#34;该地区的班级:
//COLLISION CODE FOR WALLS
if (p.Bounds.Collide(w.Bounds))
{
//Right Collision
if (p.VelX > 0)
{
Console.WriteLine("Right Collision");
p.canMove = false;
p.Position.X = w.Position.X - 32;
p.SetVelX(0);
}
else if (p.VelX < 0)
{
Console.WriteLine("Left Collision");
p.canMove = false;
p.Position.X = w.Position.X + 32;
p.SetVelX(0);
}
if (p.VelX == 0)
{
p.canMove = true;
}
}
当我跑步时,玩家将停止移动,但他将被轻微植入墙内。我知道你在想什么,&#34;移动使p.canMove = true
超出碰撞的if语句的if语句。&#34;我尝试了这个,它导致玩家与立方体来回反复。我尝试过不同的方法,以至于我想把这个代码留下来。我决定回到Stack Overflow,看看是否有人可以帮助我。提前谢谢。
答案 0 :(得分:1)
我认为您的代码问题根本不是您的引擎 - 考虑到结果,并且在扫描代码后,似乎没问题。由于您的播放器剪辑到墙上,因此您的播放器和墙壁的硬编码值为32,可能不正确。试试这个:
if (p.VelX > 0)
{
Console.WriteLine("Right Collision");
p.canMove = false;
//move the right of our player to the left of the wall by setting
//his x to the wall's x minus his width.
p.Position.X = w.Position.X - p.Size.Width;
p.SetVelX(0);
}
else if (p.VelX < 0)
{
Console.WriteLine("Left Collision");
p.canMove = false;
//Move the left of our player to the right of the wall, or
//the wall's x plus the wall's width
p.Position.X = w.Position.X + w.Size.Width;
p.SetVelX(0);
}
我希望这会有所帮助。
修改强>
实际上,我认为我发现了另一个问题。在碰撞检测后移动X后更改玩家位置时,您忘记调用UpdatePos()
方法。因此,您正在移动他的位置而不是他的实际矩形,这可能会导致错误。相反,在你移动他的x后,立即拨打UpdatePos()