Hassan Ali
Hassan Ali

Reputation: 173

Flutter Flame collision detection sometimes skips the object

I was cloning the Google doodle jump game. Basically, the player jumps overs the platform and moves to the top. I am using the Flutter Flame engine to build on this game.

To detect the collisions, I used the onCollision method firstly, but it had an issue that sometimes player seems to jump into the platform rather than jump over. So, to solve this, I changed the logic to onCollision start, but now it sometimes misses the platform. Like the platform is there, but it doesn't detects the collusion and the player falls off from the screen. Is there a way to solve this?

I think the Flutter Flame engine has an issue and it doesn't detect the collusion between objects, or I am doing something wrong here?

Here is the code snippet. It works fine, but it frequently misses the platforms and the player falls of the screen.

// Callback for Character colliding with another component in the game
  @override
  void onCollisionStart(Set<Vector2> intersectionPoints, PositionComponent other) {
    super.onCollisionStart(intersectionPoints, other);
    if(other is EnemyPlatform && !isInvincible) {
      if(current == PlayerState.rocket)
        return;
      gameRef.onLose();
      return;
    }

    bool isCollidingVertically = (intersectionPoints.first.y - intersectionPoints.last.y).abs() <5;
    if(isMovingDown && isCollidingVertically) {
      current = PlayerState.center;
      if(other is NormalPlatform) {
        jump();
        return;
      }else if (other is SpringBoard) {
        jump(specialJumpSpeed: jumpSpeed *2);
        return;
      }else if(other is BrokenPlatform && other.current == BrokenPlatformState.cracked) {
        jump();
        other.breakPlatform();
      }
    }

    if(!hasPowerup && other is Rocket) {
      current = PlayerState.rocket;
      other.removeFromParent();
      jump(specialJumpSpeed: jumpSpeed * other.jumpSpeedMultiplier);

      return;
    }else if (!hasPowerup && other is NooglerHat) {
      if(current == PlayerState.center)
        current = PlayerState.nooglerCenter;
      if(current == PlayerState.left)
        current = PlayerState.nooglerLeft;
      if(current == PlayerState.right)
        current = PlayerState.nooglerRight;
      other.removeFromParent();
      _removePowerupAfterTime(other.activeLengthInMS);
      jump(specialJumpSpeed: jumpSpeed*other.jumpSpeedMultiplier);
      return;
    }
  }

Upvotes: 0

Views: 949

Answers (1)

Hassan Ali
Hassan Ali

Reputation: 173

Thanks, everyone for the suggestions through comments, I pinned point my problem and thus was able to resolve it. Actually, the calculation of isCollidingVertically variable was done wrong in the video tutorial I followed. The logic was not accurate, so I corrected its logic and now the issue is resolved. I am attaching the code snippet.

  @override
    void onCollisionStart(Set<Vector2> intersectionPoints, PositionComponent other) {
        super.onCollisionStart(intersectionPoints, other);
    if (other is EnemyPlatform && !isInvincible) {

      if (current == PlayerState.rocket) return;
      gameRef.onLose();
      return;
    }

    //Update calculation
    bool isCollidingVertically =  (intersectionPoints.first.y >other.absoluteTopLeftPosition.y-65);
    // bool isCollidingVerticallyPrevious = (intersectionPoints.first.y - intersectionPoints.last.y).abs() < 5;
    if (isMovingDown && isCollidingVertically) {
      current = PlayerState.center;
      if (other is NormalPlatform) {
        jump();
        return;
      } else if (other is SpringBoard) {
        jump(specialJumpSpeed: jumpSpeed * 2);
        return;
      } else if (other is BrokenPlatform &&
          other.current == BrokenPlatformState.cracked) {
        jump();
        other.breakPlatform();
      }
    }

    if (!hasPowerup && other is Rocket) {
      current = PlayerState.rocket;
      other.removeFromParent();
      jump(specialJumpSpeed: jumpSpeed * other.jumpSpeedMultiplier);

      return;
    } else if (!hasPowerup && other is NooglerHat) {
      if (current == PlayerState.center) current = PlayerState.nooglerCenter;
      if (current == PlayerState.left) current = PlayerState.nooglerLeft;
      if (current == PlayerState.right) current = PlayerState.nooglerRight;
      other.removeFromParent();
      _removePowerupAfterTime(other.activeLengthInMS);
      jump(specialJumpSpeed: jumpSpeed * other.jumpSpeedMultiplier);
      return;
    }
 }

Upvotes: 1

Related Questions