1

所以我试图在 C#.NET 中制作一个 Tron LightBike 游戏,但是当两个玩家同时互相碰撞(或正面碰撞)时我遇到了一个问题。

这是我初始化播放器的方法...

bikes = new ArrayList();
bikes.Add(new LightBike(new Point(500, 10), Color.Blue, "left", new DirectionKeys(Keys.Left, Keys.Down, Keys.Up, Keys.Right))); //blue player facing right
bikes.Add(new LightBike(new Point(10, 10), Color.Red, "right", new DirectionKeys(Keys.A, Keys.S, Keys.W, Keys.D))); //red player facing left
grid = new int[this.Size.Width, this.Size.Height]; //create the grid map
drawThread = new Thread(drawBikes);

当正面碰撞时,似乎第一个添加的玩家总是获胜。当我更改将自行车添加到 ArrayList 的顺序(第二个添加蓝色)时,红色获胜。我相信这与我检查碰撞的方式有关。我认为这与我在drawBikes中的foreach循环特别有关......

这是 drawBikes 方法:

while (true)
{

    ArrayList deleteBikes = new ArrayList();
    foreach (LightBike b in bikes)
    {
        if (isValidLocation(b.getNextLocation()))
        {
            canvas.DrawLine(new Pen(b.color, BIKE_SIZE), b.location, b.getNextLocation());
            b.location = b.getNextLocation();
            grid[b.location.X, b.location.Y] = bikes.IndexOf(b)+1;
        }
        else
        {
            deleteBikes.Add(b);
        }

为什么只有红色玩家被移除而不是蓝色玩家(因为他们本质上应该同时击中对方)?我应该创建更多线程吗?我觉得没必要……

这是我的 isValidLocation() 代码:

public Boolean isValidLocation(Point x)
{
        if (x.X < this.Size.Width && x.X > 0)
            if (x.Y < this.Size.Height && x.Y > 0)
                if (grid[x.X, x.Y] == 0)
                    return true;

    return false;
}
4

1 回答 1

2

我相信您的问题是您getNextLocation()直接调用,然后在每个循环中进行碰撞检查。如果自行车 A 是第一个在循环中被处理的,它的位置被更新,发现与自行车 B 发生碰撞,并且可能被删除(我不知道你deleteBikes在 else 语句之后对你的列表做了什么)。当环移动到自行车 B 上时,不再有另一辆自行车可以碰撞。

您的代码应该:

  1. 循环遍历自行车并更新它们在网格上的位置。
  2. 循环遍历自行车,检查每辆自行车是否发生碰撞,并执行碰撞逻辑。
  3. 在新位置画出每辆自行车。

如果自行车在步骤 2 中发生碰撞,则将其从自行车列表中删除(或以某种方式标记),并且不会在步骤 3 中绘制。这里的关键是在检查之前完全完成更新自行车的位置碰撞,并且绘图被推迟到处理完所有碰撞逻辑。

于 2012-04-07T06:24:51.327 回答