From eef51968e7d45a484d4bf61db2dabb5e31616161 Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Fri, 8 Dec 2023 20:19:09 +0100 Subject: [PATCH] docs: Update platformer tutorial to latest Flame (#2904) Updates the platformer tutorial to Flame v1.11.0 --- .github/.cspell/gamedev_dictionary.txt | 1 - .github/.cspell/words_dictionary.txt | 2 -- doc/tutorials/platformer/step_1.md | 22 ++++++------ doc/tutorials/platformer/step_2.md | 26 ++++---------- doc/tutorials/platformer/step_3.md | 27 +++++++------- doc/tutorials/platformer/step_4.md | 50 +++++++++++++------------- doc/tutorials/platformer/step_5.md | 8 ++--- doc/tutorials/platformer/step_6.md | 6 ++-- doc/tutorials/platformer/step_7.md | 6 ++-- 9 files changed, 62 insertions(+), 86 deletions(-) diff --git a/.github/.cspell/gamedev_dictionary.txt b/.github/.cspell/gamedev_dictionary.txt index 72bb9927a..91316a644 100644 --- a/.github/.cspell/gamedev_dictionary.txt +++ b/.github/.cspell/gamedev_dictionary.txt @@ -45,7 +45,6 @@ raycasts # plural of raycast raytrace # act of raytracing raytracing # rendering techniques that calculates light rays as straight lines rects # plural of rect -refactorings # plural of refactoring respawned # past tense of respawn respawn # when the player character dies and is brought back after some time and penalties RGBA # red green blue alpha diff --git a/.github/.cspell/words_dictionary.txt b/.github/.cspell/words_dictionary.txt index 7c9bfd6cb..090f8afe6 100644 --- a/.github/.cspell/words_dictionary.txt +++ b/.github/.cspell/words_dictionary.txt @@ -2,8 +2,6 @@ bloodlust collidable collidables -composability -discoverability draggables focusable gamepad diff --git a/doc/tutorials/platformer/step_1.md b/doc/tutorials/platformer/step_1.md index a8afc90ce..10eee6161 100644 --- a/doc/tutorials/platformer/step_1.md +++ b/doc/tutorials/platformer/step_1.md @@ -23,7 +23,7 @@ void main() { Like in the [klondike](../klondike/klondike.md) tutorial, starting a new game can feel overwhelming. I like to first decide what platform I am trying to target. Will this be a mobile game, a desktop -game, or maybe a web game, with Flutter and Flame, these are all possible. For this game though, I +game, or maybe a web game, with Flutter and Flame, these are all possible. For this game though, I am going to focus on a web game. This means my users will interact with the game using their keyboards. @@ -45,16 +45,16 @@ All of these will be brought together in `EmberQuestGame` derived from `FlameGam ## Assets -Every game needs assets. Assets are images, sprites, animations, sounds, etc. Now, I am not an +Every game needs assets. Assets are images, sprites, animations, sounds, etc. Now, I am not an artist, but because I am basing this game on Ember, the flame mascot, and Ember is already designed, -it sets the tone that this will be a pixel art game. There are numerous sites available that +it sets the tone that this will be a pixel art game. There are numerous sites available that provide free pixel art that can be used in games, but please check and comply with the licensing and -always provide valid creator attribution. For this game though, I am going to take a chance and -make my artwork using an online pixel art tool. If you decide to use this tool, multiple online -tutorials will assist you with the basic operations as well as exporting the assets. Now normally, -most games will utilize sprite sheets. These combine many images into one larger image that can be -sectioned and used as individual images. For this tutorial though, I specifically will save the -images individually as I want to demonstrate the Flame engine's caching abilities. Ember and the +always provide valid creator attribution. For this game though, I am going to take a chance and +make my artwork using an online pixel art tool. If you decide to use this tool, multiple online +tutorials will assist you with the basic operations as well as exporting the assets. Now normally, +most games will utilize sprite sheets. These combine many images into one larger image that can be +sectioned and used as individual images. For this tutorial though, I specifically will save the +images individually as I want to demonstrate the Flame engine's caching abilities. Ember and the water enemy are sprite sheets though as they contain multiple images to create animations. Right-click the images below, choose "Save as...", and store them in the `assets/images` folder of the @@ -88,8 +88,8 @@ emberquest/ You may ask, why are the images different sizes? As I was using the online tool to make the assets, I had trouble getting the -detail I desired for the game in a 16x16 block. The heart worked out in 32x32 -and the ground as well as the star were 64x64. Regardless, the asset size does +detail I desired for the game in a 16x16 block. The heart worked out in 32x32 +and the ground as well as the star were 64x64. Regardless, the asset size does not matter for the game as we will resize as needed. ``` diff --git a/doc/tutorials/platformer/step_2.md b/doc/tutorials/platformer/step_2.md index 772eb79f9..14a57d62d 100644 --- a/doc/tutorials/platformer/step_2.md +++ b/doc/tutorials/platformer/step_2.md @@ -91,20 +91,15 @@ You can run this file and you should just have a blank screen now. Let's get Emb ## CameraComponent and World -Since `FlameGame.camera` is deprecated, we want to add a `CameraComponent` that we can move around, -and a world that we can add all our components to and move around our player in. -(The `CameraComponent` will be built-in in Flame v2). +To move around in the world we are going the use the built-in `CameraComponent` and `World` that +exists on the `FlameGame` class. +We are going to add all our components to the `world` and follow the player with the `camera`. ```dart import 'package:flame/components.dart'; import 'package:flame/game.dart'; class EmberQuestGame extends FlameGame { - EmberQuestGame(); - - final world = World(); - late final CameraComponent cameraComponent; - @override Future onLoad() async { await images.loadAll([ @@ -117,12 +112,10 @@ class EmberQuestGame extends FlameGame { 'water_enemy.png', ]); - cameraComponent = CameraComponent(world: world); // Everything in this tutorial assumes that the position // of the `CameraComponent`s viewfinder (where the camera is looking) // is in the top left corner, that's why we set the anchor here. - cameraComponent.viewfinder.anchor = Anchor.topLeft; - addAll([cameraComponent, world]); + camera.viewfinder.anchor = Anchor.topLeft; } } ``` @@ -140,7 +133,7 @@ import 'package:flame/components.dart'; import '../ember_quest.dart'; class EmberPlayer extends SpriteAnimationComponent - with HasGameRef { + with HasGameReference { EmberPlayer({ required super.position, }) : super(size: Vector2.all(64), anchor: Anchor.center); @@ -181,13 +174,8 @@ import 'package:flame/game.dart'; import 'actors/ember.dart'; class EmberQuestGame extends FlameGame { - EmberQuestGame(); - late EmberPlayer _ember; - final world = World(); - late final CameraComponent cameraComponent; - @override Future onLoad() async { await images.loadAll([ @@ -200,9 +188,7 @@ class EmberQuestGame extends FlameGame { 'water_enemy.png', ]); - cameraComponent = CameraComponent(world: world); - cameraComponent.viewfinder.anchor = Anchor.topLeft; - addAll([cameraComponent, world]); + camera.viewfinder.anchor = Anchor.topLeft; _ember = EmberPlayer( position: Vector2(128, canvasSize.y - 70), diff --git a/doc/tutorials/platformer/step_3.md b/doc/tutorials/platformer/step_3.md index 2e4b131a4..e97fa65e3 100644 --- a/doc/tutorials/platformer/step_3.md +++ b/doc/tutorials/platformer/step_3.md @@ -26,17 +26,17 @@ so first create a new folder called `lib/objects`. In that folder, create 3 file boilerplate code for the class, so create the following in their respective files: ```dart -class GroundBlock{} +class GroundBlock {} -class PlatformBlock{} +class PlatformBlock {} -class Star{} +class Star {} ``` Also, create `water_enemy.dart` in the `lib/actors` folder using this boilerplate code: ```dart -class WaterEnemy{} +class WaterEnemy {} ``` Now we can create a file called `segment_manager.dart` which will be placed in a new folder called @@ -300,10 +300,7 @@ as: 'water_enemy.png', ]); - cameraComponent = CameraComponent(world: world); - cameraComponent.viewfinder.anchor = Anchor.topLeft; - addAll([cameraComponent, world]); - + camera.viewfinder.anchor = Anchor.topLeft; initializeGame(); } ``` @@ -329,7 +326,7 @@ import 'package:flame/components.dart'; import '../ember_quest.dart'; class PlatformBlock extends SpriteComponent - with HasGameRef { + with HasGameReference { final Vector2 gridPosition; double xOffset; @@ -433,11 +430,11 @@ the block in a `Vector2`. So add the following to your `loadGameSegments` method ```dart case PlatformBlock: - add(PlatformBlock( - gridPosition: block.gridPosition, - xOffset: xPositionOffset, - )); - break; + add(PlatformBlock( + gridPosition: block.gridPosition, + xOffset: xPositionOffset, + )); + break; ``` If you run your code, you should now see: @@ -453,7 +450,7 @@ import 'package:flutter/material.dart'; @override Color backgroundColor() { - return const Color.fromARGB(255, 173, 223, 247); + return const Color.fromARGB(255, 173, 223, 247); } ``` diff --git a/doc/tutorials/platformer/step_4.md b/doc/tutorials/platformer/step_4.md index 766bfd7dd..03414ca07 100644 --- a/doc/tutorials/platformer/step_4.md +++ b/doc/tutorials/platformer/step_4.md @@ -17,7 +17,7 @@ import 'package:flutter/material.dart'; import '../ember_quest.dart'; class Star extends SpriteComponent - with HasGameRef { + with HasGameReference { final Vector2 gridPosition; double xOffset; @@ -65,7 +65,7 @@ So the only change between the Star and the Platform beyond the anchor is simply ```dart add( SizeEffect.by( - Vector2(-24, -24), + Vector2(-24, -24), EffectController( duration: .75, reverseDuration: .5, @@ -76,24 +76,24 @@ add( ); ``` -The `SizeEffect` is best explained by going to their [help -docs](../../flame/effects.md#sizeeffectby). In short, we simply reduce the size of the star +The `SizeEffect` is best explained by going to their +[docs](../../flame/effects.md#sizeeffectby). In short, we simply reduce the size of the star by -24 pixels in both directions and we make it pulse infinitely using the `EffectController`. Don't forget to add the star to your `lib/ember_quest.dart` file by doing: ```dart case Star: - add( - Star( - gridPosition: block.gridPosition, - xOffset: xPositionOffset, - ), - ); - break; + world.add( + Star( + gridPosition: block.gridPosition, + xOffset: xPositionOffset, + ), + ); + break; ``` -If you run your game, you should now see pulsing stars! +If you run your game, you should now see pulsating stars! ## Water Enemy @@ -109,7 +109,7 @@ import 'package:flame/effects.dart'; import '../ember_quest.dart'; class WaterEnemy extends SpriteAnimationComponent - with HasGameRef { + with HasGameReference { final Vector2 gridPosition; double xOffset; @@ -171,7 +171,7 @@ Don't forget to add the water enemy to your `lib/ember_quest.dart` file by doing ```dart case WaterEnemy: - add( + world.add( WaterEnemy( gridPosition: block.gridPosition, xOffset: xPositionOffset, @@ -204,7 +204,7 @@ import 'package:flutter/material.dart'; import '../ember_quest.dart'; -class GroundBlock extends SpriteComponent with HasGameRef { +class GroundBlock extends SpriteComponent with HasGameReference { final Vector2 gridPosition; double xOffset; @@ -253,8 +253,8 @@ Now in your Ground Block's `onLoad` method, add the following at the end of the ```dart if (gridPosition.x == 9 && position.x > game.lastBlockXPosition) { - game.lastBlockKey = _blockKey; - game.lastBlockXPosition = position.x + size.x; + game.lastBlockKey = _blockKey; + game.lastBlockXPosition = position.x + size.x; } ``` @@ -334,7 +334,7 @@ import 'package:flutter/material.dart'; import '../ember_quest.dart'; import '../managers/segment_manager.dart'; -class GroundBlock extends SpriteComponent with HasGameRef { +class GroundBlock extends SpriteComponent with HasGameReference { final Vector2 gridPosition; double xOffset; @@ -391,13 +391,13 @@ Finally, don't forget to add your Ground Block to `lib/ember_quest.dart` by addi ```dart case GroundBlock: - add( - GroundBlock( - gridPosition: block.gridPosition, - xOffset: xPositionOffset, - ), - ); - break; + world.add( + GroundBlock( + gridPosition: block.gridPosition, + xOffset: xPositionOffset, + ), + ); + break; ``` If you run your code, your game should now look like this: diff --git a/doc/tutorials/platformer/step_5.md b/doc/tutorials/platformer/step_5.md index 5c7d25793..90c6980ba 100644 --- a/doc/tutorials/platformer/step_5.md +++ b/doc/tutorials/platformer/step_5.md @@ -20,7 +20,7 @@ class EmberQuestGame extends FlameGame with HasKeyboardHandlerComponents { ```dart class EmberPlayer extends SpriteAnimationComponent - with KeyboardHandler, HasGameRef { + with KeyboardHandler, HasGameReference { ``` Now we can add a new method: @@ -118,7 +118,7 @@ Next, add the `CollisionCallbacks` mixin to `lib/actors/ember.dart` like: ```dart class EmberPlayer extends SpriteAnimationComponent - with KeyboardHandler, CollisionCallbacks, HasGameRef { + with KeyboardHandler, CollisionCallbacks, HasGameReference { ``` If it did not auto-import, you will need the following: @@ -176,9 +176,7 @@ For the collisions to be activated for Ember, we need to add a `CircleHitbox`, s method, add the following: ```dart -add( - CircleHitbox(), -); +add(CircleHitbox()); ``` Now that we have the basic collisions created, we can add gravity so Ember exists in a game world diff --git a/doc/tutorials/platformer/step_6.md b/doc/tutorials/platformer/step_6.md index 37a7629f8..80619051e 100644 --- a/doc/tutorials/platformer/step_6.md +++ b/doc/tutorials/platformer/step_6.md @@ -26,7 +26,7 @@ enum HeartState { } class HeartHealthComponent extends SpriteGroupComponent - with HasGameRef { + with HasGameReference { final int heartNumber; HeartHealthComponent({ @@ -88,7 +88,7 @@ import 'package:flutter/material.dart'; import '../ember_quest.dart'; import 'heart.dart'; -class Hud extends PositionComponent with HasGameRef { +class Hud extends PositionComponent with HasGameReference { Hud({ super.position, super.size, @@ -152,7 +152,7 @@ the number of hearts necessary. The last step is to add the hud to the game. Go to `lib/ember_quest.dart` and add the following code in the `initializeGame` method: ```dart -cameraComponent.viewport.add(Hud()); +camera.viewport.add(Hud()); ``` If the auto-import did not occur, you will need to add: diff --git a/doc/tutorials/platformer/step_7.md b/doc/tutorials/platformer/step_7.md index 30c17867c..05299395b 100644 --- a/doc/tutorials/platformer/step_7.md +++ b/doc/tutorials/platformer/step_7.md @@ -185,10 +185,8 @@ Future onLoad() async { 'star.png', 'water_enemy.png', ]); - cameraComponent = CameraComponent(world: world); - cameraComponent.viewfinder.anchor = Anchor.topLeft; - addAll([cameraComponent, world]); - + + camera.viewfinder.anchor = Anchor.topLeft; initializeGame(true); }