检测滚动游戏中的碰撞

时间:2011-02-03 00:04:48

标签: cocos2d-iphone collision-detection

如何拥有滚动地图并检测其上的碰撞?

我尝试了一个瓷砖地图,但不想使用这种技术。

我想了解如何滚动游戏背景以及检测碰撞对象。

一个例子是this game

如果没有使用tilemaps,那么世界如何滚动以及物理对象检测到与角色精灵的碰撞?

请指出我在这个主题上的正确方向。

2 个答案:

答案 0 :(得分:2)

通过检查边界框(或有时是边界圆)是否重叠来完成简单碰撞检测。也就是说,给定对象A和对象B,如果它们的边界框重叠,则发生了碰撞。

如果您想获得幻想,可以为对象创建多边形并确定边界多边形是否重叠。这更复杂,更难以正确,而且涉及更多的处理。

与使用tilemap没有太大区别。使用tilemap,您正在对tile进行碰撞检测。如果没有tilemap,您就会对单个对象的边界框进行碰撞检测。逻辑几乎相同。

其他信息:

我认为你正在努力解决的问题是你在考虑屏幕问题。在编写游戏时,将游戏世界(模型)的概念与演示(屏幕)分开是很重要的。

例如,简单的侧卷轴游戏可能包含许多充满信息的“屏幕”。虽然屏幕可能是1000个单位宽,但游戏的世界可能是10,000或100,000单位宽。请注意,我说“单位”而不是“像素”。游戏的度量单位可以是英寸,厘米,英里等等。您的所有游戏逻辑都应该按照世界坐标工作。如何将其投影到视图(屏幕)上与世界上发生的事情无关。

世界上的每个对象都在世界坐标中分配了位置。这包括玩家精灵,它正在世界各地移动。世界上所有物体的碰撞检测和其他相互作用都是按照世界坐标进行的。

为简化起见,假设世界单位和屏幕单位之间存在一对一的映射。也就是说,您的世界宽度为10,000像素,屏幕宽度为1,000像素。那么世界就是“十大屏幕”。更准确地说,屏幕可以查看1/10的世界。如果是这种情况,那么您的视图可以通过可见的最左侧世界坐标来定义。因此,如果世界坐标2,000位于屏幕的左侧,则屏幕上最右边的像素列将是世界坐标2,999。

这意味着您需要从世界到屏幕和从屏幕到世界的转换功能。对于这种情况,这些功能非常简单。如果我们假设没有垂直滚动,那么只需要通过从视图x坐标减去世界x坐标来转换x坐标。也就是world.x - viewOrigin.x。因此,在上面的情况中,在世界x坐标2,315处的对象的屏幕坐标将是(2,315-2,000)或315.这是对象在屏幕上的位置的x坐标。在当前视图中。

屏幕对世界恰恰相反:将对象的屏幕坐标添加到视图的原点:315 + 2,000 = 2,315。

我无法强调在世界和视图坐标之间保持这种分离是多么重要。您的所有游戏逻辑都应按世界坐标运行。您更新视图以向您显示世界上正在发生的事情。在侧卷轴中,您通常会根据玩家的动作左右移动视图。如果玩家向左移动,则向左移动视图原点。如果玩家向右移动,则将视图原点移动到右侧。

一旦你将这个想法内化,事情变得更加简单。游戏世界中所做的一切都发生在世界中。你确保世界状态是一致的,然后你担心显示世界观。

建立一个比屏幕更大的游戏并没有更简单的方法(我知道)。无论你如何构建它,你都必须有一些概念,只在视图中显示世界的一部分。通过形式化,将表现与游戏逻辑分开,事情变得更加简单。

答案 1 :(得分:1)

您可能希望将相机尺寸设置为要渲染的关卡尺寸。你可以根据你的相机固定的任何东西来获得关卡坐标,比如说你的英雄。

精灵碰撞相对容易。使用你正在测试的两个精灵的高度/宽度(IDK关于cocos2d,但大多数api的精灵位置都在sprite的左上角):

if(player.Pos.x <= (object.Pos.x + object.width) || (player.Pos.x + player.width) >= object.Pos.x)
{
    if(player.Pos.y >= (object.Pos.y - object.height) || (player.Pos.y - player.height) <= object.Pos.y)
        //collision detected
}