Sprite Sheet Jump/fall Animation sync with gravity and jump speed code

Viewed 20

First and foremost thanks to anyone that can help me out here but Im having trouble getting my jump sprite animation to fit with the game jump speed and gravity. The animation appears to be choppy, and when i execute the animation again, it seems to start from the last frame it left off, im guessing. I want the jump/fall animation to fit perfectly with the code gravity and jump speed logic. hoping some one can help.

this is how it looks

enter image description here

this is how it should look

enter image description here

// Represents a player in the game world.
class Player extends SpriteAnimationComponent with CollisionCallbacks, KeyboardHandler{

  //late ThePixelDead gameRef = GlobalGameReference.instance.gameReference;

  int _hAxisInput = 0;
  bool _jumpInput = false;
  bool _isOnGround = false;


  final double _gravity = 20;
  final double _jumpSpeed = 400;
  final double _moveSpeed = 64;

  final Vector2 _up = Vector2(0, -1);
  final Vector2 _velocity = Vector2.zero();

  // Limits for clamping player.
  late Vector2 _minClamp;
  late Vector2 _maxClamp;

  Player(
    SpriteAnimation spriteAnimation, {
    required Rect levelBounds,
    Vector2? position,
    Vector2? size,
    Vector2? scale,
    double? angle,
    Anchor? anchor,
    int? priority,
  }) : super(
          animation: spriteAnimation,
          position: position,
          size: size,
          scale: scale,
          angle: angle,
          anchor: anchor,
          priority: priority,
        ) {
    // Since anchor point for player is at the center,
    // min and max clamp limits will have to be adjusted by
    // half-size of player.
    final halfSize = size! / 2;
    _minClamp = levelBounds.topLeft.toVector2() + halfSize;
    _maxClamp = levelBounds.bottomRight.toVector2() - halfSize;
  }

  @override
  Future<void>? onLoad() {
    add(CircleHitbox());
    return super.onLoad();
  }

  @override
  void update(double dt) {


   // animationLogic();

    // Modify components of velocity based on
    // inputs and gravity.
    _velocity.x = _hAxisInput * _moveSpeed;
    _velocity.y += _gravity;

    // Allow jump only if jump input is pressed
    // and player is already on ground.
    if (_jumpInput) {
      if (_isOnGround) {
        AudioManager.playSfx('Jump_15.wav');
        _velocity.y = -_jumpSpeed;
        _isOnGround = false;
        animation = gameRef.jump;
      }
      _jumpInput = false;
    }

    // Clamp velocity along y to avoid player tunneling
    // through platforms at very high velocities.
    _velocity.y = _velocity.y.clamp(-_jumpSpeed, 150);

    // delta movement = velocity * time
    position += _velocity * dt;

    // Keeps player within level bounds.
    position.clamp(_minClamp, _maxClamp);

    // Flip player if needed.
    if (_hAxisInput < 0 && scale.x > 0) {
      flipHorizontallyAroundCenter();

    } else if (_hAxisInput > 0 && scale.x < 0) {
      flipHorizontallyAroundCenter();
    }


    super.update(dt);
  }

  @override
  bool onKeyEvent(RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
    _hAxisInput = 0;
    _hAxisInput += keysPressed.contains(LogicalKeyboardKey.keyA) ? -1 : 0;
    _hAxisInput += keysPressed.contains(LogicalKeyboardKey.keyD) ? 1 : 0;
    _jumpInput = keysPressed.contains(LogicalKeyboardKey.space);

    return true;
  }

  @override
  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    if (other is Platform) {
      if (intersectionPoints.length == 2) {
        // Calculate the collision normal and separation distance.
        final mid = (intersectionPoints.elementAt(0) +
                intersectionPoints.elementAt(1)) /
            2;

        final collisionNormal = absoluteCenter - mid;
        final separationDistance = (size.x / 2) - collisionNormal.length;
        collisionNormal.normalize();

        // If collision normal is almost upwards,
        // player must be on ground.
        if (_up.dot(collisionNormal) > 0.9) {
          _isOnGround = true;
          animation = gameRef.idle;
        }

        // Resolve collision by moving player along
        // collision normal by separation distance.
        position += collisionNormal.scaled(separationDistance);
      }
    }
    super.onCollision(intersectionPoints, other);
  }


  // This method runs an opacity effect on player
  // to make it blink.
  void hit() {
    add(
      OpacityEffect.fadeOut(
        EffectController(
          alternate: true,
          duration: 0.1,
          repeatCount: 5,
        ),
      ),
    );
  }

  // Makes the player jump forcefully.
  void jump() {
    _jumpInput = true;
    _isOnGround = true;
  }


}






//-------------------



// Represents the game world
class ThePixelDead extends FlameGame with HasCollisionDetection, HasKeyboardHandlerComponents, HasTappables {

  final WorldData worldData;


  ThePixelDead({required this.worldData}) {
    globalGameReference.gameReference = this;
  }

  GlobalGameReference globalGameReference = Get.put(GlobalGameReference());


  // Reference to common spritesheet
  late Image spriteSheet;


  final double stepTime = 0.2;

  late SpriteSheet walkSS;
  late SpriteSheet runSS;
  late SpriteSheet jumpSS;
  late SpriteSheet idleSS;

  late SpriteAnimation walk = walkSS.createAnimation(row: 0, stepTime: stepTime, to: 7);
  late SpriteAnimation run = runSS.createAnimation(row: 0, stepTime: stepTime, to: 7);
  late SpriteAnimation jump = jumpSS.createAnimation(row: 0, stepTime: stepTime, to: 7, loop: false);
  late SpriteAnimation idle = idleSS.createAnimation(row: 0, stepTime: stepTime, to: 7);


  final playerData = PlayerDataOrig();
  final textureSize = Vector2(32,32);

  Size getScreenSize() {
    return mat.MediaQueryData.fromWindow(mat.WidgetsBinding.instance.window).size;
  }

  @override
  Future<void>? onLoad() async {
    // Device setup
    await Flame.device.fullScreen();
    await Flame.device.setLandscape();

    // Loads all the audio assets
    await AudioManager.init();

    spriteSheet = await images.load('Spritesheet.png');

    idleSS = SpriteSheet(
      image: Flame.images.fromCache('player/idle.png'),
      srcSize: textureSize,
    );

    walkSS = SpriteSheet(
      image: Flame.images.fromCache('player/walk.png'),
      srcSize: textureSize,
    );

    runSS = SpriteSheet(
      image: Flame.images.fromCache('player/run.png'),
      srcSize: textureSize,
    );

    jumpSS = SpriteSheet(
      image: Flame.images.fromCache('player/jump.png'),
      srcSize: textureSize,
    );



    camera.zoom =  1.4;

    //camera.viewport = FixedResolutionViewport(Vector2(640, 230),);

    //    camera.viewport = FixedResolutionViewport(Vector2(getScreenSize().width / 2.5, getScreenSize().height / 2.5),);


    return super.onLoad();
  }
}

0 Answers
Related