Playing Plinko on Flutter via Flame

237 Views Asked by At

I want to create a Plinko game using flutter through flames so that the end result looks like this:

enter image description here

But this is the only thing I can do:

enter image description here

Here's the code:

        class MyGame extends FlameGame with HasCollisionDetection {
      @override
      Color backgroundColor() => const Color.fromARGB(255, 35, 38, 51);

      List<RectangleCollidable> staticBalls = [];

      void createNewBall() {
        add(Ball(Vector2(230 /*Random().nextInt(31) + 230*/, 0)));
      }

      @override
      Future<void> onLoad() async {
        createNewBall();

        double ballSize = 50;
        int rowCount = 8;
        double gap = 4;
        int staticBallCount = 2;

        for (int row = 0; row < rowCount; row++) {
          double startX = (size.x - staticBallCount * (ballSize + gap)) / 2;
          double y = size.y - (rowCount - row) * (ballSize + gap);

          for (int col = 0; col < staticBallCount; col++) {
            double x = startX + col * (ballSize + gap);
            final staticBall = RectangleCollidable(Vector2(x, y));
            add(staticBall);
            staticBalls.add(staticBall);
          }

          staticBallCount++;
        }
      }
    }

    class Ball extends PositionComponent with CollisionCallbacks {
      double gravity = 200.0;
      double velocityX = 0;
      double velocityY = 0;
      double friction = 0.95;

      double accelerationX = 10.0;

      late ShapeHitbox hitbox;

      Ball(Vector2 position)
          : super(
              position: position,
              size: Vector2.all(20),
              anchor: Anchor.center,
            );

      @override
      FutureOr<void> onLoad() async {
        final defaultPaint = Paint()
          ..color = Colors.redAccent
          ..style = PaintingStyle.stroke;
        hitbox = CircleHitbox()
          ..paint = defaultPaint
          ..renderShape = true
          ..radius = 10;
        add(hitbox);
      }

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

        if (other is RectangleCollidable) {
          if (velocityY > 0) {
            velocityY = -velocityY / 5;
            velocityX = (other.position.x + other.size.x) / 3;
            position.y = other.position.y - size.y / 2 - other.size.y / 2 - 1;
          }
        }
      }

      @override
      void update(double dt) {
        velocityY += gravity * dt;
        velocityX *= friction;

        position.x += velocityX * dt;
        position.y += velocityY * dt;
      }
    }

    class RectangleCollidable extends PositionComponent with CollisionCallbacks {
      final _collisionStartColor = Colors.amber;
      final _defaultColor = Colors.cyan;
      late ShapeHitbox hitbox;

      RectangleCollidable(Vector2 position)
          : super(
              position: Vector2(position.x + 15, position.y),
              size: Vector2.all(25),
              anchor: Anchor.center,
            );

      @override
      Future<void> onLoad() async {
        final defaultPaint = Paint()
          ..color = _defaultColor
          ..style = PaintingStyle.stroke;
        hitbox = CircleHitbox()
          ..paint = defaultPaint
          ..renderShape = true
          ..radius = 12.5;
        add(hitbox);
      }

      @override
      void onCollisionStart(
        Set<Vector2> intersectionPoints,
        PositionComponent other,
      ) {
        super.onCollisionStart(intersectionPoints, other);
        hitbox.paint.color = _collisionStartColor;
      }

      @override
      void onCollisionEnd(PositionComponent other) {
        super.onCollisionEnd(other);
        if (!isColliding) {
          hitbox.paint.color = _defaultColor;
        }
      }
    }

Perhaps there should be a completely different code, but I don't know how to write it. Can anyone help?

0

There are 0 best solutions below