I want to create a Plinko game using flutter through flames so that the end result looks like this:
But this is the only thing I can do:
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?

