レベルを描画するのにJSTileMapを使用します。私はSKPhysicsBodyをすべてのタイルに追加するためにそれを少し変更しましたが、時には主人公にいくつかの衝動を適用し、壁/地面/天井にぶつかり、彼が変な動作をしています。彼は物理学の原理に反する方法で表面から反射する。私は、プレイヤーが2つの物理機関(地上の2つの物理機関など)が接続するポイントにヒットするために起こると思います。 SKPhysicsBodyクラスは、異なる物理ボディから1つの物理ボディを作成するメソッドを提供します。+(SKPhysicsBody *)bodyWithBodies:(NSArray *)bodies;このメソッドを使って、タイルの物理学のボディから1つの物理ボディを作成できますか?ここでJSTileMapで生成されたタイルにphysicsBodyを追加して1つのphysicsBodyに変更する方法
は、私は物理学の遺体を追加JSTileMapからの方法です:
+(id) layerWithTilesetInfo:(NSArray*)tilesets layerInfo:(TMXLayerInfo*)layerInfo mapInfo:(JSTileMap*)mapInfo
{
TMXLayer* layer = [TMXLayer node];
layer.map = mapInfo;
layer.tilesByColumnRow = [NSMutableDictionary dictionary];
// basic properties from layerInfo
layer.layerInfo = layerInfo;
layer.layerInfo.layer = layer;
layer.mapTileSize = mapInfo.tileSize;
layer.alpha = layerInfo.opacity;
layer.position = layerInfo.offset;
// recalc the offset if we are isometriic
if (mapInfo.orientation == OrientationStyle_Isometric)
{
layer.position = CGPointMake((layer.mapTileSize.width/2.0) * (layer.position.x - layer.position.y),
(layer.mapTileSize.height/2.0) * (-layer.position.x - layer.position.y));
}
NSMutableDictionary* layerNodes = [NSMutableDictionary dictionaryWithCapacity:tilesets.count];
//MY CODE
NSMutableArray *arrayOfSprites = [[NSMutableArray alloc] init];
SKNode *theSprite;
//----||----
// loop through the tiles
for (NSInteger col = 0; col < layerInfo.layerGridSize.width; col++)
{
for (NSInteger row = 0; row < layerInfo.layerGridSize.height; row++)
{
// get the gID
NSInteger gID = layerInfo.tiles[col + (NSInteger)(row * layerInfo.layerGridSize.width)];
// mask off the flip bits and remember their result.
bool flipX = (gID & kTileHorizontalFlag) != 0;
bool flipY = (gID & kTileVerticalFlag) != 0;
bool flipDiag = (gID & kTileDiagonalFlag) != 0;
gID = gID & kFlippedMask;
// skip 0 GIDs
if (!gID)
continue;
// get the tileset for the passed gID. This will allow us to support multiple tilesets!
TMXTilesetInfo* tilesetInfo = [mapInfo tilesetInfoForGid:gID];
[layer.tileInfo addObject:tilesetInfo];
if (tilesetInfo) // should never be nil?
{
SKTexture* texture = [tilesetInfo textureForGid:gID];
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:texture];
sprite.name = [NSString stringWithFormat:@"%ld",(long)(col + row * layerInfo.layerGridSize.width)];
// make sure it's in the right position.
if (mapInfo.orientation == OrientationStyle_Isometric)
{
sprite.position = CGPointMake((layer.mapTileSize.width/2.0) * (layerInfo.layerGridSize.width + col - row - 1),
(layer.mapTileSize.height/2.0) * ((layerInfo.layerGridSize.height * 2 - col - row) - 2));
}
else
{
sprite.position = CGPointMake(col * layer.mapTileSize.width + layer.mapTileSize.width/2.0,
(mapInfo.mapSize.height * (tilesetInfo.tileSize.height)) - ((row + 1) * layer.mapTileSize.height) + layer.mapTileSize.height/2.0);
}
// flip sprites if necessary
if(flipDiag)
{
if(flipX)
sprite.zRotation = -M_PI_2;
else if(flipY)
sprite.zRotation = M_PI_2;
}
else
{
if(flipY)
sprite.yScale *= -1;
if(flipX)
sprite.xScale *= -1;
}
// add sprite to correct node for this tileset
SKNode* layerNode = layerNodes[tilesetInfo.name];
if (!layerNode) {
layerNode = [[SKNode alloc] init];
layerNodes[tilesetInfo.name] = layerNode;
}
//adding physicsbody to every tile
//sprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(sprite.frame.size.width, sprite.frame.size.height)];
//sprite.physicsBody.dynamic = NO;
//sprite.physicsBody.categoryBitMask = mapCategory;
//[arrayOfSprites addObject:sprite.physicsBody];
[layerNode addChild:sprite];
NSUInteger indexes[] = {col, row};
NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexes length:2];
[layer.tilesByColumnRow setObject:sprite forKey:indexPath];
//MY CODE
sprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:sprite.frame.size];
sprite.physicsBody.dynamic = NO;
[arrayOfSprites addObject:sprite.physicsBody];
//-----||------
#ifdef DEBUG
// CGRect textRect = [texture textureRect];
// NSLog(@"atlasNum %2d (%2d,%2d), gid (%d,%d), rect (%f, %f, %f, %f) sprite.pos (%3.2f,%3.2f) flipx%2d flipy%2d flipDiag%2d", gID+1, row, col, [tilesetInfo rowFromGid:gID], [tilesetInfo colFromGid:gID], textRect.origin.x, textRect.origin.y, textRect.size.width, textRect.size.height, sprite.position.x, sprite.position.y, flipX, flipY, flipDiag);
#endif
}
}
}
//MY CODE
NSArray *array = [arrayOfSprites copy];
theSprite = [SKNode node];
theSprite.physicsBody = [SKPhysicsBody bodyWithBodies:array];
theSprite.physicsBody.dynamic = NO;
theSprite.position = CGPointMake(layer.position.x+16, layer.position.y+16);
[layer addChild:theSprite];
//-----||------
// add nodes for any tilesets that were used in this layer
for (SKNode* layerNode in layerNodes.allValues) {
if (layerNode.children.count > 0) {
[layer addChild:layerNode];
}
}
[layer calculateAccumulatedFrame];
return layer;
}
すべてのタイルに物理学のボディを追加し、NSMutableArrayのにそれらの物理体を追加した後、私はNSArrayのこのNSMutableArrayののコピーを割り当て、作成しよう
//MY CODE
NSArray *array = [arrayOfSprites copy];
theSprite = [SKNode node];
theSprite.physicsBody = [SKPhysicsBody bodyWithBodies:array];
theSprite.physicsBody.dynamic = NO;
theSprite.position = CGPointMake(layer.position.x+16, layer.position.y+16);
[layer addChild:theSprite];
//-----||------
結果として、1つのタイルの高さと幅を持つ物理的ボディが1つ追加されます。
ありがとう、私はすべてのタイルから作られた1つの物理学のボディを作成することができますが、奇妙な動作は消えませんでした。私はbodyWithBodiesメソッドがどうにかしてすべてのボディを接続し、それらの間の接続を削除すると思ったが、それはあなたがすべてのボディを1つ(移動、配置など)として扱うのに役立ちます。 – mfker
奇妙な行動 – Knight0fDragon
私は主人公にいくつかの衝動を適用し、彼は壁/地面/天井にぶつかり、彼は奇妙な行動をしています。彼は物理学の原理に反する方法で表面から反射する。例えば、彼が右に動いたとき(インパルスが加えられたとき)、彼は時々天井から反射して、時には後ろに移動し始める(左)。 – mfker