preface
I say that the cross-endpoint consistency of Flutter is not new
If you’ve ever used a game engine like Unity3D, Unreal, etc., you’ll see that these are cross-terminal, right? Don’t you just start with a canvas and finish the rest?
Now compare that to a game engine
So let's really play a game with Flutter
FLAME engine
Here I used a Game engine based on Flutter calledFLAME
. Using it to develop games, you don’t really need the ones in FlutterWidget
So there’s the question in the title
A Flutter application that does not use a FlutterWidget
Is that a Flutter?
Anyway, finish writing this article and redo the game with the widget sometime
Fundamentals of Game Engines
The introduction of Flame library
dependencies:
flame: ^1.0. 0-rc5
Copy the code
Developing a game is based on these three things
- Update mechanism
- Renderer
- Input events
In Flame, a basic game framework code is shown below
class MyGameSubClass extends Game {
@override
void render(Canvas canvas) {
// TODO: implement render
}
@override
void update(double t) {
// TODO: implement update
}
}
main() {
runApp(
GameWidget(
game: MyGameSubClass(),
)
);
}
Copy the code
Refresh, render all have, events, in this game we add drag events
class MyGameSubClass extends BaseGame with PanDetector
Copy the code
Render graphic elements
- The plane
The graphic material of the plane is a Sprite map, in which the first two frames are the flying state, and the last three are the explosion state
playerSpriteSheet = SpriteSheet(
image: await images.load('player.png'),
srcSize: playerSize,
);
// Animation of Sprite map in running state
player = SpriteAnimationComponent(
size: playerSize,
animation: playerSpriteSheet.createAnimation(row: 0, stepTime: 1., to: 2));Copy the code
We then use the Add method to display the graphic elements to the screen
add(player);
// Put it in x:100,y:100 to give you a sense of the coordinate system
player.x=player.y=100;
Copy the code
- The bullet
bulletImage = await images.load('bullet.png');
Copy the code
The logic and life cycle of a bullet goes like this
- Generated from off-screen
- Move in the direction of the current coordinates of the aircraft
- Remove the screen to destroy
// Add a bullet
void addBullet() {
final bullet = SpriteComponent.fromImage(bulletImage, size: bulletSize);
double bulletX;
double bulletY;
// Randomly generate the rectangle around the display area
if (Random().nextBool()) {
bulletX = Random().nextDouble() * (screenSize.width + bulletSize.x) -
bulletSize.x;
bulletY = Random().nextBool() ? -bulletSize.y : screenSize.height;
} else {
bulletX = Random().nextBool() ? -bulletSize.x : screenSize.width;
bulletY = Random().nextDouble() * (screenSize.height + bulletSize.y) -
bulletSize.y;
}
// Give the bullet its initial coordinates
bullet.x = bulletX;
bullet.y = bulletY;
// Add to the scene
add(bullet);
// Add bullet management array to update bullet flight coordinates and collision detection later
bullets.add({
"component": bullet,// Bullet control instance
"speed": (1+gameTime/10) + Random().nextDouble()*3.// Flight speed
"angle": atan2(((bulletY + bulletSize.y/2) - (player.y + playerSize.y / 2)),
((bulletX + bulletSize.x) - (player.x + playerSize.x / 2)))});// Vector Angle
}
Copy the code
By calling the addBullet method, we can fire a bullet at the location of the plane on the screen
To fire multiple bullets, let’s create a new function, addGroupBullet
// Add a set of bullets
void addGroupBullet() {
int groupCount = 10+Random().nextInt(gameTime+1);
for (int i = 0; i < groupCount; i++) { addBullet(); }}Copy the code
The refresh mechanism
In the Update method provided by Flame we need to update the positions of all bullets because bullets are not static, they need to be constantly moving.
@override
void update(double dt) {
super.update(dt);
// Iterate through the bullet array to update all bullets
for (int i = bullets.length - 1; i >= 0; i--) {
var bulletItem = bullets[i];
// Get the bullet instance
SpriteComponent bullet = bulletItem["component"] as SpriteComponent;
double angle = bulletItem["angle"];
double speed = bulletItem["speed"];
// Let the bullet move according to the vector Angle at which it is fired
bullet.x -= cos(angle) * speed;
bullet.y -= sin(angle) * speed;
// Destroy the bullet when it moves off-screen
if (isNotInScreen(bullet.x, bullet.y)) {
print("bullet removed");
remove(bullet);
bullets.removeAt(i);
continue; }}}Copy the code
Are you starting to feel a little hot?
Movement of aircraft
void onPanUpdate(DragUpdateDetails details) {
super.onPanUpdate(details);
if(! isGameStart)return;
// Since the coordinate of the airplane object is in the upper left corner, the movement should be offset
player.x = details.globalPosition.dx - playerSize.x / 2;
player.y = details.globalPosition.dy - playerSize.y / 2;
}
Copy the code
Collision detection
Every time you refresh the bullet coordinates, check to see if they coincide with the current plane coordinates, and the game is over
if (isHitPlayer(bullet.x, bullet.y)) {
gameOver();
}
Copy the code
A simple judgment mechanism is used here, which is not accurate to the outline of the plane. First, the accuracy to the outer contour will bring more computation, but also more complex. The second is that the game experience is not good, after all, when you play on your phone, your fingers have to block most of the airplane graphics
// Aircraft and bullet collision judgment
bool isHitPlayer(double x, double y) {
double _x = (x + bulletSize.x / 2 - (player.x + playerSize.x / 2)).abs();
double _y = (y + bulletSize.y / 2 - (player.y + playerSize.y / 2)).abs();
// Find the distance between the bullet and the plane
double distance = sqrt(_x * _x + _y * _y);
// Return true/false if the linear distance is less than the distance judged to be a collision
if (distance <= hitDistance) return true;
return false;
}
Copy the code
Game over
void gameOver() {
isGameStart = false;
// Cancel the timer
if(timer! =null)timer.cancel();
// Play plane explosion animation
player.animation = playerSpriteSheet.createAnimation(
row: 0, stepTime: 1., loop: false, from: 2, to: 6);
print("game over");
}
Copy the code
Code warehouse
Github.com/ezshine/flu…
The latter
So written, from the code level, and not too much Flutter, but use of Flutter ability across the end, we can easily develop a across the Mac, Linux, Windows, Web, iOS, Android the little game. The Flutter is also a good choice if you don’t use an IDE for game development, such as Unity3D.
Pay attention to a guard
An old programmer who was a designer and wanted to write code until he was 70
Recent articles (thanks for your encouragement and support 🌹🌹🌹)
- 🔥 made a night of animation, just to give you a better understanding of Vue3 Composition Api 940 likes
- 🔥 update 2020, Vue simulates the effects of dragging and dropping cards for 1,114 likes
- 🔥 super detailed, practical experience of Flutter2.0 building Web applications | technical review 14 upvotes
- The use of 🔥 Webview | VSCode plug-in development tutorial 19 praise
- 🔥 launched nuggets statistics dashboard function [I love Nuggets] 0.0.15 | bold New Year essay 7 likes
This article is participating in the “Nuggets 2021 Spring Recruitment Campaign”, click to see the details of the campaign