2016-11-10 1 views
0

Ich benutze JSTileMap, um eine Ebene zu zeichnen. Ich habe es ein wenig geändert, um SKPhysicsBody zu jedem Plättchen hinzuzufügen, aber manchmal, wenn ich dem Hauptcharakter einen Impuls gebe und er die Wand/den Boden/die Decke trifft, verhält er sich merkwürdig. Er reflektiert von Oberflächen mit dem Weg, der den Prinzipien der Physik widerspricht. Ich denke, dass es passiert, weil der Spieler den Punkt erreicht, an dem sich zwei Physikkörper (zum Beispiel zwei Physikkörper des Bodens) verbinden. SKPhysicsBody-Klasse bietet eine Methode zum Erstellen eines Physikkörpers aus verschiedenen Physikkörpern. + (SKPhysicsBody *) bodyWithBodies: (NSArray *) bodies; Kann ich diese Methode verwenden, um einen Physikkörper aus den Fliesen-Physikkörpern zu erstellen?Wie fügt man physicsBody zu den von JSTileMap erzeugten Kacheln hinzu und ändert sie in einen physicsBody

Hier ist eine Methode aus JSTileMap wo ich Physik Körper hinzufügen: zu jeder Fliese

+(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; 
} 

Nach der Zugabe von Physik Körper und das Hinzufügen dieser Physik Körper zu NSMutableArray ich eine Kopie dieses NSMutableArray zum NSArray zuweisen und versuchen, zu erstellen eine Physik Körper aus es wie folgt:

//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]; 
     //-----||------ 

In Folge ein physikalischer Körper mit der Höhe und die Breite einer Fliese wird hinzugefügt.

Antwort

1

Wenn Sie [SKPhysicsBody bodyWithBodies: array] verwenden möchten, müssen Sie sicherstellen, dass alle Körper im Array relativ zum übergeordneten Knoten sind.

sprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:sprite.frame.size]; bedeutet, dass Ihre physikalische Körperposition relativ zum Sprite-Knoten ist. Sie benötigen den Körper relativ zum übergeordneten Knoten.

Der einzige Weg, ich weiß, wie das mit dem Zentrum ist zu tun:

sprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:sprite.frame.size center:sprite.position];

Das die SKPhysicsBody an der Stelle des Sprites setzen sollte, wenn es um den übergeordneten Knoten hinzugefügt wird.

+0

Danke, ich kann einen Physikkörper aus allen Kacheln erstellen, aber das seltsame Verhalten verschwand nicht. Ich dachte, dass die bodyWithBodies-Methode irgendwie alle Körper verbinden und die Verbindungen zwischen ihnen entfernen würde, aber es hilft nur dir, alle Körper als einen zu behandeln (wie Bewegen, Positionieren usw.), mein Schlechter. – mfker

+0

Was für ein seltsames Verhalten – Knight0fDragon

+0

Wenn ich dem Hauptcharakter einen Impuls gebe und er die Wand/den Boden/die Decke trifft, verhält er sich komisch. Er reflektiert von Oberflächen mit dem Weg, der den Prinzipien der Physik widerspricht. Wenn er sich zum Beispiel nach rechts bewegt (je nach dem angewendeten Impuls) und manchmal von der Decke reflektiert, beginnt er sich rückwärts zu bewegen (links). – mfker

Verwandte Themen