flutterdartflame

Flutter Flame Game how to add projectile?


I've added bullets that my character can shoot but despite making their starting position the same as my character they seem to be rendered to the bottom left/right underneath my level. The bullets also exhibit unexpected behavior like changing position when my character does(note I purposefully slowed speed of bullets but they are moving horizontally as expected.), see Gif:enter image description here

To create the bullet I made a simple class that extends SpriteAnimationComponent (Maybe this is not ideal way to create the Bullet class, please advise me if I'm mistaken):

import 'dart:async';
import 'dart:io';

import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:marvington_game/game.dart';

class Bullet extends SpriteAnimationComponent with HasGameRef<Gain>, CollisionCallbacks {
  double xdir;
  Bullet({super.position, super.size, required this.xdir});
  final double _speed = 20;
  final Vector2 velocity = Vector2.zero();

  FutureOr<void> onLoad() {
    debugMode = true;

    animation = _createSpriteAnimation();
    add(CircleHitbox(position: position, collisionType: CollisionType.active));
    return super.onLoad();
  }

  void update(double dt) {
    velocity.x = xdir * _speed;
    position.x += velocity.x * dt;
    super.update(dt);
  }

  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    removeFromParent();
    super.onCollision(intersectionPoints, other);
  }

  SpriteAnimation _createSpriteAnimation() {
    return SpriteAnimation.fromFrameData(
      game.images.fromCache("Marvington/Marv Bullet.png"),
      SpriteAnimationData.sequenced(
        amount: 1,
        stepTime: 0.11,
        textureSize: Vector2.all(16),
      ),
    );
  }
}

Then I add it to the game in my player class when a certain key is pressed calling this function:

  void _shoot() {
    Vector2 pos = Vector2(position.x, position.y);
    Bullet b = Bullet(xdir: scale.x, position: pos);
    add(b);
  }

Solution

  • When you add a component as a child to another component it is rendered in relation to that component. So what you want to do here is add the projectiles to the world (or whatever parent your player has) and with the same starting position as the player.

      void _shoot() {
        Bullet b = Bullet(xdir: scale.x, position: position);
        parent?.add(b);
      }