我正在尝试创建一种好方法来处理两个对象之间所有可能的碰撞。通常一个人会移动并撞击另一个人,然后应该“弹开”。
到目前为止我所做的(我正在创建一个典型的游戏,你有一个棋盘并在砖 block 上弹球)是检查矩形是否相交,如果相交,则反转 Y 速度。
这是一个非常丑陋的临时解决方案,不会长期有效,因为这种处理在游戏中很常见,我真的很想为 future 的项目找到一个很好的方法。感谢任何链接或有用的信息。
下面是我的碰撞处理函数现在的样子。
protected void collision()
{
#region Boundaries
if (bal.position.X + bal.velocity.X >= viewportRect.Width ||
bal.position.X + bal.velocity.X <= 0)
{
bal.velocity.X *= -1;
}
if (bal.position.Y + bal.velocity.Y <= 0)
{
bal.velocity.Y *= -1;
}
#endregion
bal.rect = new Rectangle((int)bal.position.X+(int)bal.velocity.X-bal.sprite.Width/2, (int)bal.position.Y-bal.sprite.Height/2+(int)bal.velocity.Y, bal.sprite.Width, bal.sprite.Height);
player.rect = new Rectangle((int)player.position.X-player.sprite.Width/2, (int)player.position.Y-player.sprite.Height/2, player.sprite.Width, player.sprite.Height);
if (bal.rect.Intersects(player.rect))
{
bal.position.Y = player.position.Y - player.sprite.Height / 2 - bal.sprite.Height / 2;
if (player.position.X != player.prevPos.X)
{
bal.velocity.X -= (player.prevPos.X - player.position.X) / 2;
}
bal.velocity.Y *= -1;
}
foreach (Brick b in brickArray.list)
{
b.rect.X = Convert.ToInt32(b.position.X-b.sprite.Width/2);
b.rect.Y = Convert.ToInt32(b.position.Y-b.sprite.Height/2);
if (bal.rect.Intersects(b.rect))
{
b.recieveHit();
bal.velocity.Y *= -1;
}
}
brickArray.removeDead();
}
最佳答案
这里有一些可能有用的建议。
首先,您所有的对象,例如 Player
、Bal
(不确定那是什么)和 Brick
都有一些相似的接口(interface) -它们都有sprite
(定义对象的大小)、rect
(对象的边界框)、position
(当前位置)、velocity
(当前速度)。这表明您可以创建一个公共(public)基类来封装此功能。
另请注意,您始终会根据当前位置
和sprite
重新计算rect
。这表明 rect
实际上应该是一个隐藏重新计算的属性(它总是相同的!)
因此,您可以像这样定义一个公共(public)基类(我将遵循 .NET 标准编码风格并使用属性和 CamelCase
名称):
class GameObject {
Point Position { get; set; }
Vector Velocity { get; set; }
Sprite Sprite { get; set; }
Rectangle Rect {
get {
// Ecnapsulated calculation of the bounding rectangle
return new Rectangle
( (int)Position.X + (int)Velocity.X - Sprite.Width/2,
(int)Position.Y + (int)Velocity.Y - Sprite.Height/2,
Sprite.Width, Sprite.Height);
}
}
如果您现在将此类型用作所有游戏对象的基类,您应该可以这样写:
protected void Collision() {
#region Boundaries
if (bal.Position.X + bal.Velocity.X >= viewportRect.Width ||
bal.Position.X + bal.Velocity.X <= 0)
bal.Velocity.X *= -1;
if (bal.Position.Y + bal.Velocity.Y <= 0)
bal.Velocity.Y *= -1;
#endregion
if (bal.Rect.Intersects(player.Rect)) {
bal.Position.Y = player.Position.Y - player.Sprite.Height/2
- bal.Sprite.Height/2;
if (player.Position.X != player.PrevPos.X)
bal.Velocity.X -= (player.PrevPos.X - player.Position.X) / 2;
bal.Velocity.Y *= -1;
}
foreach (Brick b in brickArray.list) {
if (bal.Rect.Intersects(b.Rect)) {
b.RecieveHit();
bal.Velocity.Y *= -1;
}
}
brickArray.RemoveDead();
}
将函数分成两部分听起来也是个好主意 - 一个检查 bal
和 player
,另一个检查积木。
关于c# - 尽可能整齐地处理碰撞过程中的速度矢量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2569409/