Wil*_*ich 5 game-physics ios sprite-kit skphysicsbody skspritenode
我创建了一个SKSpriteNode名为let的说Map,它具有我定义的边缘路径(一些简单的多边形形状).
我想弄清楚的是如何添加几个其他边缘路径作为Map的内部边缘.好像整个"地图"确实有漏洞.某种内部边界形状可以与Map作为一个整体起作用:一条边缘路径(如下所示)
我知道有一种方法可以创建一个SKPhysicsBodywith body(一些NSArray),就像这样
Map.physicsBody = [SKPhysicsBody bodyWithBodies:bodiesArray];
Run Code Online (Sandbox Code Playgroud)
这种方法实际上是否产生了我在图像中显示的内容?假设bodiesArray包含3 SKSpriteNode的每个都有一个使用这种方法的定义路径:
+ (SKPhysicsBody *)bodyWithEdgeChainFromPath:(CGPathRef)path
Run Code Online (Sandbox Code Playgroud)
,创造这样的道路
SKSpriteNode *innerNode1 = [SKSpriteNode spriteNodeWithImageNamed:@"map"];
CGMutablePathRef innerNode1Path = CGPathCreateMutable();
CGPathMoveToPoint(mapPath, NULL, 1110, 1110);
CGPathAddLineToPoint(mapPath, NULL, <some x1>, <some y1>);
CGPathAddLineToPoint(mapPath, NULL, <some x2>, <some y2>);
CGPathAddLineToPoint(mapPath, NULL, <some x3>, <some y3>);
.
.
.
CGPathCloseSubpath(mapPath);
innerNode1.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:innerNode1Path];
[bodiesArray addObject:innerNode1];
// Repeat for other 2 nodes
Run Code Online (Sandbox Code Playgroud)
我知道另一种方法是创建3个单独的节点,其中包含预期"洞"的位置和形状,但我想要避免创建比我需要的节点更多的节点.如果有人能够确认我想要做的是正确的,或者可能提出一个我不知道的替代方案.
注意:如果我正在做的是正确的,但我错过了一些东西,如果有人能告诉我正确的方法来做我想做的事情,我将不胜感激(即使是一个内部较小正方形的正方形的简单例子也是大).谢谢!
编辑1:下面是我用来创建"内部边界"的代码片段.这里的问题是,当绘制和显示外部和内部矩形时,当我将内部矩形添加到Map时bodyWithBodies,它完全控制碰撞检测,从外部rect shell移除所有接触控制.当我移除bodyWithBodies它恢复正常显示两个rects时,外部有碰撞检测(不允许我通过),而内部没有任何东西......如此接近
// 1 Create large outer shell Map
CGRect mapWithRect = CGRectMake(map.frame.origin.x + offsetX, map.frame.origin.y + offsetY, map.frame.size.width * shrinkage, map.frame.size.height * shrinkage);
self.physicsWorld.gravity = CGVectorMake(0.0, 0.0);
self.physicsWorld.contactDelegate = self;
// 2 Create smaller inner boundary
CGRect innerRect = CGRectMake(100, 100, 300, 300);
SKPhysicsBody *body = [SKPhysicsBody bodyWithEdgeLoopFromRect:innerRect];
body.categoryBitMask = wallCategory;
NSArray *bodyArray = [NSArray arrayWithObject:body];
// 3 Add bodies to main Map body
myWorld.physicsBody = [SKPhysicsBody bodyWithBodies:bodyArray];
myWorld.physicsBody.categoryBitMask = wallCategory;
if ( [[levelDict objectForKey:@"DebugBorder"] boolValue] == YES) {
// This will draw the boundaries for visual reference during testing
[self debugPath:mapWithRect];
[self debugPath:innerRect];
}
Run Code Online (Sandbox Code Playgroud)
编辑2 这种方法有效..只需添加一个与外部矩形具有相同属性的新节点:
SKPhysicsBody *innerRectBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:innerRect];
innerRectBody.collisionBitMask = playerCategory;
innerRectBody.categoryBitMask = wallCategory;
SKNode *innerBoundary = [SKNode node];
innerBoundary.physicsBody = innerRectBody;
[myWorld addChild: innerBoundary];
Run Code Online (Sandbox Code Playgroud)
...但我非常希望一个更清洁的解决方案,不需要额外的节点...虽然?
你在这里没有做错什么,我举了一个例子,我用两个物理体创建了两个边缘矩形体
//使用gcd一段时间后添加主体
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self addBodyA];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self addBodyB];
});
-(void)addBodyB
{
SKSpriteNode *node=[SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(20, 20)];
node.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:node.frame.size];
node.position=CGPointMake(550, 420);
node.physicsBody.restitution=1;
[self addChild:node];
}
-(void)addBodyA
{
SKSpriteNode *node=[SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(20, 20)];
node.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:node.frame.size];
node.position=CGPointMake(400, 420);
node.physicsBody.restitution=1;
[self addChild:node];
}
-(void)addEdgesBodies
{
SKAction *r=[SKAction rotateByAngle:1.0/60 duration:1.0/60];
SKSpriteNode *rect=[SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(300,300)];
rect.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromRect:rect.frame];
rect.position=CGPointMake(500, 400);
[self addChild:rect];
//
SKSpriteNode *rect1=[SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(100,100)];
rect1.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromRect:rect1.frame];
rect1.position=CGPointMake(550, 450);
[self addChild:rect1];
[rect1 runAction:[SKAction repeatActionForever:r]];
}
[self addEdgesBodies];
Run Code Online (Sandbox Code Playgroud)
请记住,边体的 CPU 开销较低,因此不必担心性能,直到您的多边形没有那么多边。
| 归档时间: |
|
| 查看次数: |
518 次 |
| 最近记录: |