3

我正在计划一个使用 SpriteKit 和 Swift 的 iOS 平台游戏。我对如何处理玩家精灵的碰撞进行了一些研究,并偶然发现了这篇文章。

http://www.learn-cocos2d.com/2013/08/physics-engine-platformer-terrible-idea/

那篇文章建议你不要使用 SpriteKit 的内置物理引擎,而是自己实现移动、跳跃和碰撞处理等功能。Ray Wenderlichs 网站上的平台教程提出了类似的方法。

到目前为止一切都很好,但让我们谈谈玩家可以站在上面的地砖。只要瓦片是矩形且具有平坦表面(如 Ray Wenderlich 的教程中所示),自定义物理实现将很容易,因为您将使用 CGRectIntersectsRect 来检测碰撞。但是你如何检查弯曲或倾斜瓷砖上的玩家碰撞?根据我的阅读,CGRectIntersectsRect 不考虑精灵矩形内的透明像素。

http://i.stack.imgur.com/lRP2Q.png

例如看上面的图块。白色区域(左上角)将是透明的。现在,如果玩家精灵掉落在该图块上,则会在图块矩形的上边界检测到碰撞,尽管那里没有地面像素(蓝色区域,右下角)。所以最终玩家会在这个图块上方的半空中盘旋。我可以将播放器精灵向下推几个像素,但如果弯曲的地砖具有不同的坡度角度,这有点笨拙并且变得更难。

所以问题是,我如何单独使用 SpriteKit 处理这些类型的碰撞(没有额外的框架,如 Cocos2D、Kobold Kit ......)?或者这种方法完全错误,平台游戏与 SpriteKit 的碰撞应该完全不同?

很感谢任何形式的帮助!

4

2 回答 2

4

我不同意不使用物理学来处理碰撞和接触。您实际上只是想通过不使用物理学并实现自己的自定义代码来重新发明轮子。

如果您使用的是 Tiled 应用程序,那么分配物理体是一项简单的任务。使用平铺中的对象来分配各种身体类型。然后,您可以在您的代码中为每种对象类型创建一个特定的主体。

例如:

在此处输入图像描述

在上图中,我创建了一个 45 度右侧倾斜的地板。我添加的对象称为 floor45R。

下一步是解析您的地图对象。在 45floorR 的情况下,您可以创建一个像这样的物理体:

NSArray *arrayObjects = [group objectsNamed:@"floor45R"];
    for (NSDictionary *dicObj in arrayObjects) {
        CGFloat x = [dicObj[@"x"] floatValue];
        CGFloat y = [dicObj[@"y"] floatValue];
        CGFloat w = [dicObj[@"width"] floatValue];
        CGFloat h = [dicObj[@"height"] floatValue];

        SKSpriteNode *myNode = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(w, h)];
        myNode.position = CGPointMake(x, y);
        myNode.zPosition = 100;
        CGMutablePathRef trianglePath = CGPathCreateMutable();
        CGPathMoveToPoint(trianglePath, nil, -myNode.size.width/2, myNode.size.height/2);
        CGPathAddLineToPoint(trianglePath, nil, myNode.size.width/2, -myNode.size.height/2);
        CGPathAddLineToPoint(trianglePath, nil, -myNode.size.width/2, -myNode.size.height/2);
        CGPathAddLineToPoint(trianglePath, nil, -myNode.size.width/2, myNode.size.height/2);
        myNode.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:trianglePath];
        myNode.physicsBody.dynamic = NO;
        myNode.physicsBody.restitution = 0;
        myNode.physicsBody.friction = 0.0;
        myNode.physicsBody.categoryBitMask = CategoryFloor45;
        myNode.physicsBody.collisionBitMask = 0x00000000;
        CGPathRelease(trianglePath);

        [worldNode addChild:myNode];
    }

这适用于任何程度的地板坡度。请记住将您的播放器和任何其他节点的碰撞位掩码设置为与地板碰撞。

为了让你的玩家在倾斜的地板上平稳移动,我建议将玩家的物理身体分成两部分。底部是一个圆形,顶部是一个矩形。圆圈将防止卡在由 2 个连接物理体引起的任何潜在裂缝中。

SKPhysicsBody *firstBody = [SKPhysicsBody bodyWithCircleOfRadius:10 center:CGPointMake(0, 0)];
SKPhysicsBody *secondBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(5, 50) center:CGPointMake(0, 10)];
self.physicsBody = [SKPhysicsBody bodyWithBodies:@[firstBody, secondBody]];

您必须调整位置和中心坐标以匹配您的精灵图像。

于 2015-05-13T12:48:57.370 回答
1

您可以使用关卡编辑器Tiled来处理弯曲和倾斜的地砖以及处理 TMX 地图的 JSTileMap。

它将能够处理与弯曲和倾斜的地砖的接触,但至于调整站在这些地砖顶部的物体的角度,您将不得不利用一些数学函数,一个很好的例子是在这里找到

您仍然可以使用 SpriteKit 的碰撞检测,这将为您简化事情,但创建您自己的跳跃或运动引擎。

于 2015-05-13T10:59:24.577 回答