Reputation: 59
I am a beginner with the use of Flame, and I have a small problem.
My game has 3 states:
During each state, there should be different buttons displayed. I use SpriteComponent to display my buttons, but I can't make elements "disappear" and reappear in the following functions:
// For example, I use this button
// need to be displayed only during the pause state
PauseMenuButton pauseMenuButton = PauseMenuButton();
@override
Future<void>? onLoad() async {
pauseMenuButton
..sprite = await loadSprite("btnFastForward.png")
..size = pauseButtonSize
..position = Vector2(size[0] * 0.3, size[1]*0.3);
add(pauseMenuButton);
if(gamePaused) {
renderGamePause(canvas);
} else if(gameOver) {
renderGameOver(canvas);
} else {
renderGamePlay(canvas);
}
}
renderGamePlay(Canvas canvas) {
// hide pauseMenuButton
}
renderGamePause(Canvas canvas) {
// show pauseMenuButton
}
Here is my SpriteComponent class :
class PauseMenuButton extends SpriteComponent with Tappable {
@override
bool onTapDown(TapDownInfo event) {
try {
print("back to menu");
return true;
} catch(error) {
print(error);
return false;
}
}
}
Thank you !
Upvotes: 0
Views: 1707
Reputation: 2817
This is not a direct answer, but since this question appears at the top of Google search results for "hide flutter flame," I will document this here. With the introduction of the HasVisibility mixin, you can now achieve simple hiding functionality by using it.
Here is a simple sample code for hiding (the object moves to the right edge of the screen, hides for a while, and then reappears from the left edge):
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const FooApp());
}
class FooApp extends StatelessWidget {
const FooApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: GameWidget.controlled(gameFactory: FooFlameGame.new),
);
}
}
class BallCircleComponent extends CircleComponent with HasGameReference<FooFlameGame>, HasVisibility {
BallCircleComponent({
super.position,
super.radius,
super.anchor,
}) : super();
var _speed = 200.0;
@override
void update(double dt) {
super.update(dt);
final x = position.x + _speed * dt;
if (x < radius || x > game.size.x - radius) {
_speed *= -1;
}
position.x = x.clamp(radius, game.size.x - radius);
if(_speed < 0) {
isVisible = false;
} else {
isVisible = true;
}
}
}
class FooFlameGame extends FlameGame {
late final BallCircleComponent ballCircleComponent;
@override
Future<void> onLoad() async {
super.onLoad();
ballCircleComponent = BallCircleComponent(
position: Vector2(size.x * 0.5, size.y * 0.5),
radius: size.x * 0.1,
anchor: Anchor.center,
);
await add(ballCircleComponent);
}
}
References:
Upvotes: 0
Reputation: 11562
onLoad
will only be called once when the game is loaded, so you don't want to have logic like this in there. Usually you want to have logic when an event happens or in the update
method. In this case you probably want to do it when the buttons are pressed.
For hiding the Component
s the easiest way is to simply remove them from the game.
You could create a world component that you add everything that is related to the actual gameplay in and then you can add the other screens, or buttons in this case directly in your game class.
So your game could look something like this:
class World extends Component with HasGameRef<MyGame> {
@override
void updateTree(double dt) {
if(gameRef.isPaused) return;
super.updateTree(dt);
}
}
class MyGame extends FlameGame {
PauseMenuButton pauseMenuButton = PauseMenuButton();
late final World world;
bool isPaused = false;
bool gameOver = false;
@override
Future<void>? onLoad() async {
pauseMenuButton
..sprite = await loadSprite("btnFastForward.png")
..size = pauseButtonSize
..position = Vector2(size[0] * 0.3, size[1]*0.3);
add(world = World());
world.add(Your game components);
}
}
And then add HasGameRef<MyGame>
to your PauseMenuButton
, and when the button is clicked you just set gameRef.isPaused = true
and remove any unwanted components from the game with gameRef.remove(...)
.
There is a SpriteButtonComponent
that you might want to extend for your button instead of SpriteComponent
.
Upvotes: 2