如何检测两个有向物体之间的碰撞?

我目前正在写一个类似Battle City游戏的游戏。 但是现在我面临着检查两个物体之间碰撞的麻烦。 这是我写的代码:

//------------------------------------------------------------------------------------------- // check collision between a tank and another object // bool GameController::checkTankMeetsObject(Tank tank, GameObject ob) { int obX = ob.getCoord().getX(); int obY = ob.getCoord().getY(); // calculate area of obstacle: bottom left (X1, Y1), top right (X2, Y2) int obX1 = obX - SQUARESIZE / 2; int obX2 = obX + SQUARESIZE / 2; int obY1 = obY - SQUARESIZE / 2; int obY2 = obY + SQUARESIZE / 2; int tankX = tank.getCoord().getX(); int tankY = tank.getCoord().getY(); switch (tank.getDir()) { case UP: if ((tankX < obX2 + SQUARESIZE / 2 && tankX > obX1 - SQUARESIZE / 2) && (tankY + SQUARESIZE / 2 > obY1 && tankY + SQUARESIZE / 2 < obY2)) return true; break; case DOWN: if ((tankX < obX2 + SQUARESIZE / 2 && tankX > obX1 - SQUARESIZE / 2) && (tankY - SQUARESIZE / 2 > obY1 && tankY - SQUARESIZE / 2 < obY2)) return true; break; case LEFT: if ((tankX - SQUARESIZE / 2 < obX2 && tankX - SQUARESIZE / 2 > obX1) && (tankY > obY1 - SQUARESIZE / 2 && tankY < obY2 + SQUARESIZE / 2)) return true; break; case RIGHT: if ((tankX + SQUARESIZE / 2 < obX2 && tankX + SQUARESIZE / 2 > obX1) && (tankY > obY1 - SQUARESIZE / 2 && tankY < obY2 + SQUARESIZE / 2)) return true; break; } return false; } 

这个代码在正常情况下performance良好,但是在下面描述的特殊情况下,它并不起作用。

在这里输入图像说明

白色方块是障碍物,灰色方块是坦克。 坦克的当前方向是正确的。 在这种情况下,我不能移动坦克右或左,只有我可以去的方向是向下。 有没有解决scheme来优化我的代码?

给你的坦克一个财产,其轨迹在哪里。 给所有其他对象一个界限。 检查两个矩形,看它们是否有约束力。

 Rectangle rect1 = new Rectangle(x,y,width,height); Rectangle rect2 = new Rectangle(x,y,width,height); 

x和y将是你在世界上的精灵位置(Vector2.X和Vector2.Y)宽度和高度将是精灵矩形的宽度和高度

 //Trap movement before you allow them to bind GameTime gameTime = this.GameTime; //Set a velocity based on gametime passed Vector2 velocity = (150,0); Vector2 velocityup = (0,150); //lets say rect1 is your tank //lets also assume for now that we are moving up x=x y-- //rect1.x += (float)(gameTime.EllapsedGameTime.MilleSeconds * velocity); rect1.y -= (float)(gameTime.EllapsedGameTime.MilleSeconds * velocityup); //rect1 now is the position at which our tank would be in a non collision scenario //so we will check to see if that position would indeed collide with something if (rect1.Intersects(rect2){ //we collide //dont allow the tank to move in this direction } 

我认为你遇到的问题是你的运动测量不够好,你首先允许运动,然后检查以防止它,而这样你首先检查,然后移动。

通过使用向量2和游戏时间,我们确切地知道我们的对象在哪里,并可以捕捉最好的动作。 让我知道如果你还有一些问题,我知道这个解释不是最好的,但是我也是新的,所以提前道歉的人。

您对碰撞问题的答案是真/假。 相反,你可以区分没有碰撞,物体的渗透和接触物体。 那么只有在渗透的情况下才允许移动,但是允许触摸。

我还建议你将碰撞代码从坦克和GameObject中移出。 坦克和GameObjects都只是包含一系列碰撞形状。 你的碰撞代码不关心任何东西,但形状(也许也是他们的旧位置,旋转,运动方向和速度)。

每当你添加一个新的演员,你不想写新的碰撞代码。 这基本上是组成与工作中的inheritance。