ios - How to add physicsBody to tiles generated by JSTileMap and change them into one physicsBody -


i use jstilemap draw level. changed little bit add skphysicsbody every tile when apply impulse main character , hits wall/ground/ceiling acting weird. reflects surfaces way contrary principles of physics. think happens because player hits point 2 physics bodies (for example 2 physics bodies of ground) connects. skphysicsbody class provides method create 1 physics body different physics bodies + (skphysicsbody *)bodywithbodies:(nsarray *)bodies; can use method create 1 physics body ale tiles physics bodies?

here's method jstilemap add physics bodies:

+(id) layerwithtilesetinfo:(nsarray*)tilesets layerinfo:(tmxlayerinfo*)layerinfo mapinfo:(jstilemap*)mapinfo {     tmxlayer* layer = [tmxlayer node];   layer.map = mapinfo;      layer.tilesbycolumnrow = [nsmutabledictionary dictionary];     // basic properties layerinfo     layer.layerinfo = layerinfo;     layer.layerinfo.layer = layer;     layer.maptilesize = mapinfo.tilesize;     layer.alpha = layerinfo.opacity;     layer.position = layerinfo.offset;      // recalc offset if 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 tiles     (nsinteger col = 0; col < layerinfo.layergridsize.width; col++)     {         (nsinteger row = 0; row < layerinfo.layergridsize.height; row++)         {             // gid             nsinteger gid = layerinfo.tiles[col + (nsinteger)(row * layerinfo.layergridsize.width)];              // mask off flip bits , remember 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;              // tileset passed gid.  allow support multiple tilesets!             tmxtilesetinfo* tilesetinfo = [mapinfo tilesetinfoforgid:gid];             [layer.tileinfo addobject:tilesetinfo];              if (tilesetinfo)    // should never 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 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 correct node tileset                 sknode* layernode = layernodes[tilesetinfo.name];                 if (!layernode) {                     layernode = [[sknode alloc] init];                     layernodes[tilesetinfo.name] = layernode;                 }                  //adding physicsbody 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 tilesets used in layer     (sknode* layernode in layernodes.allvalues) {         if (layernode.children.count > 0) {             [layer addchild:layernode];         }     }      [layer calculateaccumulatedframe];      return layer; } 

after adding physics bodies every tile , adding physics bodies nsmutablearray assign copy of nsmutablearray nsarray , try create 1 physics body out of this:

//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 result, 1 physics body height , width of 1 tile added.

if want use [skphysicsbody bodywithbodies:array], need make sure bodies in array relative parent node.

sprite.physicsbody = [skphysicsbody bodywithrectangleofsize:sprite.frame.size]; means physics body position relative sprite node. need body relative parent node.

the way know how center:

sprite.physicsbody = [skphysicsbody bodywithrectangleofsize:sprite.frame.size center:sprite.position];

this should place skphysicsbody @ location of sprite when added parent node.


Comments

Popular posts from this blog

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -