2D Platformer切片碰撞算法(JSTileMap)

时间:2018-08-19 02:08:46

标签: ios objective-c algorithm sprite-kit

前言:尽管我不得不回答所有问题,但我已经问过这个问题。我仍然很困惑,会珍惜任何投入。

我一直在使用Sprite Kit开发一款平台游戏,但是在尝试更改玩家Spritenode的大小以更好地适应艺术时遇到了一个问题。我正在将Ray Weinderlich教程中的这种算法与JSTileMap结合使用。

 - (void)checkForAndResolveCollisionsForPlayer:(Player *)player forLayer:(TMXLayer *)layer
{
  NSInteger indices[8] = {7, 1, 3, 5, 0, 2, 6, 8};
  player.onGround = NO;  ////Here
  for (NSUInteger i = 0; i < 8; i++) {
    NSInteger tileIndex = indices[i];

    CGRect playerRect = [player collisionBoundingBox];
    CGPoint playerCoord = [layer coordForPoint:player.desiredPosition];

    NSInteger tileColumn = tileIndex % 3;
    NSInteger tileRow = tileIndex / 3;
    CGPoint tileCoord = CGPointMake(playerCoord.x + (tileColumn - 1), playerCoord.y + (tileRow - 1));

    NSInteger gid = [self tileGIDAtTileCoord:tileCoord forLayer:layer];
    if (gid != 0) {
      CGRect tileRect = [self tileRectFromTileCoords:tileCoord];
      //NSLog(@"GID %ld, Tile Coord %@, Tile Rect %@, player rect %@", (long)gid, NSStringFromCGPoint(tileCoord), NSStringFromCGRect(tileRect), NSStringFromCGRect(playerRect));
      //1
      if (CGRectIntersectsRect(playerRect, tileRect)) {
        CGRect intersection = CGRectIntersection(playerRect, tileRect);
        //2
        if (tileIndex == 7) {
          //tile is directly below Koala
          player.desiredPosition = CGPointMake(player.desiredPosition.x, player.desiredPosition.y + intersection.size.height);
          player.velocity = CGPointMake(player.velocity.x, 0.0); ////Here
          player.onGround = YES; ////Here
        } else if (tileIndex == 1) {
          //tile is directly above Koala
          player.desiredPosition = CGPointMake(player.desiredPosition.x, player.desiredPosition.y - intersection.size.height);
        } else if (tileIndex == 3) {
          //tile is left of Koala
          player.desiredPosition = CGPointMake(player.desiredPosition.x + intersection.size.width, player.desiredPosition.y);
        } else if (tileIndex == 5) {
          //tile is right of Koala
          player.desiredPosition = CGPointMake(player.desiredPosition.x - intersection.size.width, player.desiredPosition.y);
          //3
        } else {
          if (intersection.size.width > intersection.size.height) {
            //tile is diagonal, but resolving collision vertically
            //4
            player.velocity = CGPointMake(player.velocity.x, 0.0); ////Here
            float intersectionHeight;
            if (tileIndex > 4) {
              intersectionHeight = intersection.size.height;
              player.onGround = YES; ////Here
            } else {
              intersectionHeight = -intersection.size.height;
            }
            player.desiredPosition = CGPointMake(player.desiredPosition.x, player.desiredPosition.y + intersection.size.height );
          } else {
            //tile is diagonal, but resolving horizontally
            float intersectionWidth;
            if (tileIndex == 6 || tileIndex == 0) {
              intersectionWidth = intersection.size.width;
            } else {
              intersectionWidth = -intersection.size.width;
            }
            //5
            player.desiredPosition = CGPointMake(player.desiredPosition.x  + intersectionWidth, player.desiredPosition.y);
          }
        }
      }
    }
  }
  //6
  player.position = player.desiredPosition;
}

我只是想知道是否有一种更有效的方法,或者是一种不同的算法来处理这种性质的瓷砖碰撞(与玩家周围的瓷砖接触),如果将我的玩家的精灵尺寸调整为更大的尺寸,这会考虑在内。照原样,如果我将精灵的大小调整为高于两个图块高度或两个图块宽度,则由于图块的大小为16px x 16px,由于使用3 x 3网格处理图块,它会导致整个图块碰撞分解碰撞。

我的目标是能够处理瓷砖碰撞,而不必在每个“墙”瓷砖上添加物理物体,并且使算法功能与玩家人数无关。或者至少能够选择性能开销最小的选项。

我一直在思考和研究瓷砖碰撞几周了,这是我看到的仅有的两个选择。谢谢大家的提前输入,如果需要更多信息,请告诉我。

0 个答案:

没有答案