mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-11-01 01:18:38 +08:00 
			
		
		
		
	Adding images on Game, auto clear on game detach, fixing some examples
This commit is contained in:
		| @ -5,14 +5,16 @@ import 'package:flame/components/sprite_component.dart'; | ||||
| import 'package:flame/components/mixins/resizable.dart'; | ||||
| import 'package:flame/text_config.dart'; | ||||
|  | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/material.dart' hide Image; | ||||
|  | ||||
| import 'dart:ui'; | ||||
|  | ||||
| void main() async { | ||||
|   Flame.initializeWidget(); | ||||
|   await Flame.util.initialDimensions(); | ||||
|  | ||||
|   final myGame = MyGame(); | ||||
|   runApp(myGame.widget); | ||||
|   myGame.start(); | ||||
| } | ||||
|  | ||||
| class AndroidComponent extends SpriteComponent with Resizable { | ||||
| @ -20,7 +22,7 @@ class AndroidComponent extends SpriteComponent with Resizable { | ||||
|   int xDirection = 1; | ||||
|   int yDirection = 1; | ||||
|  | ||||
|   AndroidComponent() : super.square(100, 'android.png'); | ||||
|   AndroidComponent(Image image) : super.square(100, image); | ||||
|  | ||||
|   @override | ||||
|   void update(double dt) { | ||||
| @ -56,17 +58,20 @@ class MyGame extends BaseGame { | ||||
|   @override | ||||
|   bool recordFps() => true; | ||||
|  | ||||
|   void start() { | ||||
|     final android = AndroidComponent(); | ||||
|   @override | ||||
|   Future<void> onLoad() async { | ||||
|     final androidImage = await images.load('android.png'); | ||||
|  | ||||
|     final android = AndroidComponent(androidImage); | ||||
|     android.x = 100; | ||||
|     android.y = 400; | ||||
|  | ||||
|     final android2 = AndroidComponent(); | ||||
|     final android2 = AndroidComponent(androidImage); | ||||
|     android2.x = 100; | ||||
|     android2.y = 400; | ||||
|     android2.yDirection = -1; | ||||
|  | ||||
|     final android3 = AndroidComponent(); | ||||
|     final android3 = AndroidComponent(androidImage); | ||||
|     android3.x = 100; | ||||
|     android3.y = 400; | ||||
|     android3.xDirection = -1; | ||||
|  | ||||
| @ -7,15 +7,11 @@ import 'package:flame/flame.dart'; | ||||
| import 'dart:ui'; | ||||
|  | ||||
| void main() async { | ||||
|   WidgetsFlutterBinding.ensureInitialized(); | ||||
|   Flame.initializeWidget(); | ||||
|  | ||||
|   await Flame.util.fullScreen(); | ||||
|  | ||||
|   final playerSprite = await Sprite.loadSprite('player.png'); | ||||
|   final enemySprite = await Sprite.loadSprite('enemy.png'); | ||||
|   final backgroundSprite = await Sprite.loadSprite('background.png'); | ||||
|  | ||||
|   runApp(LayerGame(playerSprite, enemySprite, backgroundSprite).widget); | ||||
|   runApp(LayerGame().widget); | ||||
| } | ||||
|  | ||||
| class GameLayer extends DynamicLayer { | ||||
| @ -56,14 +52,15 @@ class BackgroundLayer extends PreRenderedLayer { | ||||
| } | ||||
|  | ||||
| class LayerGame extends Game { | ||||
|   Sprite playerSprite; | ||||
|   Sprite enemySprite; | ||||
|   Sprite backgroundSprite; | ||||
|  | ||||
|   Layer gameLayer; | ||||
|   Layer backgroundLayer; | ||||
|  | ||||
|   LayerGame(this.playerSprite, this.enemySprite, this.backgroundSprite) { | ||||
|   @override | ||||
|   Future<void> onLoad() async { | ||||
|     final playerSprite = Sprite(await images.load('player.png')); | ||||
|     final enemySprite = Sprite(await images.load('enemy.png')); | ||||
|     final backgroundSprite = Sprite(await images.load('background.png')); | ||||
|  | ||||
|     gameLayer = GameLayer(playerSprite, enemySprite); | ||||
|     backgroundLayer = BackgroundLayer(backgroundSprite); | ||||
|   } | ||||
|  | ||||
| @ -17,8 +17,11 @@ class MyGame extends Game { | ||||
|   Size size; | ||||
|   NineTileBox nineTileBox; | ||||
|  | ||||
|   MyGame(this.size) { | ||||
|     final sprite = Sprite('nine-box.png'); | ||||
|   MyGame(this.size); | ||||
|  | ||||
|   @override | ||||
|   Future<void> onLoad() async { | ||||
|     final sprite = Sprite(await images.load('nine-box.png')); | ||||
|     nineTileBox = NineTileBox(sprite, tileSize: 8, destTileSize: 24); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -65,6 +65,12 @@ class MyGame extends BaseGame { | ||||
|     Timer.periodic(sceneDuration, (_) => spawnParticles()); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<void> onLoad() async { | ||||
|     await images.load('zap.png'); | ||||
|     await images.load('boom3.png'); | ||||
|   } | ||||
|  | ||||
|   /// Showcases various different uses of [Particle] | ||||
|   /// and its derivatives | ||||
|   void spawnParticles() { | ||||
| @ -295,7 +301,7 @@ class MyGame extends BaseGame { | ||||
|   Particle imageParticle() { | ||||
|     return ImageParticle( | ||||
|       size: const Size.square(24), | ||||
|       image: Flame.images.loadedFiles['zap.png'].loadedImage, | ||||
|       image: images.fromCache('zap.png'), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| @ -385,7 +391,7 @@ class MyGame extends BaseGame { | ||||
|   /// Flame's [Sprite] into the effect. | ||||
|   Particle spriteParticle() { | ||||
|     return SpriteParticle( | ||||
|       sprite: Sprite('zap.png'), | ||||
|       sprite: Sprite(images.fromCache('zap.png')), | ||||
|       size: Position.fromOffset(cellSize * .5), | ||||
|     ); | ||||
|   } | ||||
| @ -524,12 +530,11 @@ class MyGame extends BaseGame { | ||||
|     const columns = 8; | ||||
|     const rows = 8; | ||||
|     const frames = columns * rows; | ||||
|     const imagePath = 'boom3.png'; | ||||
|     final spriteImage = Flame.images.loadedFiles[imagePath].loadedImage; | ||||
|     final spriteImage = images.fromCache('boom3.png'); | ||||
|     final spritesheet = SpriteSheet( | ||||
|       rows: rows, | ||||
|       columns: columns, | ||||
|       imageName: imagePath, | ||||
|       image: spriteImage, | ||||
|       textureWidth: spriteImage.width ~/ columns, | ||||
|       textureHeight: spriteImage.height ~/ rows, | ||||
|     ); | ||||
| @ -543,19 +548,8 @@ class MyGame extends BaseGame { | ||||
| } | ||||
|  | ||||
| Future<BaseGame> loadGame() async { | ||||
|   Size gameSize; | ||||
|   WidgetsFlutterBinding.ensureInitialized(); | ||||
|  | ||||
|   await Future.wait([ | ||||
|     Flame.util.initialDimensions().then((size) => gameSize = size), | ||||
|     Flame.images.loadAll(const [ | ||||
|       'zap.png', | ||||
|  | ||||
|       /// Credits to Stumpy Strust from | ||||
|       /// https://opengameart.org/content/explosion-sheet | ||||
|       'boom3.png', | ||||
|     ]), | ||||
|   ]); | ||||
|   Flame.initializeWidget(); | ||||
|   final gameSize = await Flame.util.initialDimensions(); | ||||
|  | ||||
|   return MyGame(screenSize: gameSize); | ||||
| } | ||||
|  | ||||
| @ -6,14 +6,21 @@ import 'dart:convert' show base64; | ||||
| import 'package:flame/flame.dart'; | ||||
| 
 | ||||
| class Images { | ||||
|   Map<String, ImageAssetLoader> loadedFiles = {}; | ||||
|   final Map<String, _ImageAssetLoader> _loadedFiles = {}; | ||||
| 
 | ||||
|   void clear(String fileName) { | ||||
|     loadedFiles.remove(fileName); | ||||
|     _loadedFiles.remove(fileName); | ||||
|   } | ||||
| 
 | ||||
|   void clearCache() { | ||||
|     loadedFiles.clear(); | ||||
|     _loadedFiles.clear(); | ||||
|   } | ||||
| 
 | ||||
|   Image fromCache(String fileName) { | ||||
|     final image = _loadedFiles[fileName]; | ||||
|     assert(image?.loadedImage != null, | ||||
|         'Tried to access an inexistent entry on cache "$fileName"'); | ||||
|     return image.loadedImage; | ||||
|   } | ||||
| 
 | ||||
|   Future<List<Image>> loadAll(List<String> fileNames) async { | ||||
| @ -21,17 +28,17 @@ class Images { | ||||
|   } | ||||
| 
 | ||||
|   Future<Image> load(String fileName) async { | ||||
|     if (!loadedFiles.containsKey(fileName)) { | ||||
|       loadedFiles[fileName] = ImageAssetLoader(_fetchToMemory(fileName)); | ||||
|     if (!_loadedFiles.containsKey(fileName)) { | ||||
|       _loadedFiles[fileName] = _ImageAssetLoader(_fetchToMemory(fileName)); | ||||
|     } | ||||
|     return await loadedFiles[fileName].retreive(); | ||||
|     return await _loadedFiles[fileName].retreive(); | ||||
|   } | ||||
| 
 | ||||
|   Future<Image> fromBase64(String fileName, String base64) async { | ||||
|     if (!loadedFiles.containsKey(fileName)) { | ||||
|       loadedFiles[fileName] = ImageAssetLoader(_fetchFromBase64(base64)); | ||||
|     if (!_loadedFiles.containsKey(fileName)) { | ||||
|       _loadedFiles[fileName] = _ImageAssetLoader(_fetchFromBase64(base64)); | ||||
|     } | ||||
|     return await loadedFiles[fileName].retreive(); | ||||
|     return await _loadedFiles[fileName].retreive(); | ||||
|   } | ||||
| 
 | ||||
|   Future<Image> _fetchFromBase64(String base64Data) async { | ||||
| @ -53,8 +60,8 @@ class Images { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class ImageAssetLoader { | ||||
|   ImageAssetLoader(this.future); | ||||
| class _ImageAssetLoader { | ||||
|   _ImageAssetLoader(this.future); | ||||
| 
 | ||||
|   Image loadedImage; | ||||
|   Future<Image> future; | ||||
| @ -6,7 +6,7 @@ import 'package:flutter/widgets.dart'; | ||||
|  | ||||
| import 'flame_audio.dart'; | ||||
| import 'bgm.dart'; | ||||
| import 'images.dart'; | ||||
| import 'assets/images.dart'; | ||||
| import 'assets_cache.dart'; | ||||
| import 'util.dart'; | ||||
|  | ||||
|  | ||||
| @ -7,10 +7,11 @@ import 'package:flutter/widgets.dart' hide WidgetBuilder; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/services.dart'; | ||||
|  | ||||
| import '../keyboard.dart'; | ||||
|  | ||||
| import 'widget_builder.dart'; | ||||
|  | ||||
| import '../keyboard.dart'; | ||||
| import '../assets/images.dart'; | ||||
|  | ||||
| /// Represents a generic game. | ||||
| /// | ||||
| /// Subclass this to implement the [update] and [render] methods. | ||||
| @ -19,6 +20,8 @@ abstract class Game { | ||||
|   // Widget Builder for this Game | ||||
|   final builder = WidgetBuilder(); | ||||
|  | ||||
|   final images = Images(); | ||||
|  | ||||
|   /// Returns the game background color. | ||||
|   /// By default it will return a black color. | ||||
|   /// It cannot be changed at runtime, because the game widget does not get rebuild when this value changes. | ||||
| @ -78,6 +81,8 @@ abstract class Game { | ||||
|     if (this is KeyboardEvents) { | ||||
|       RawKeyboard.instance.removeListener(_handleKeyEvent); | ||||
|     } | ||||
|  | ||||
|     images.clearCache(); | ||||
|   } | ||||
|  | ||||
|   /// Flag to tell the game loop if it should start running upon creation | ||||
|  | ||||
| @ -14,38 +14,6 @@ class SpriteSheet { | ||||
|   List<List<Sprite>> _sprites; | ||||
|  | ||||
|   SpriteSheet({ | ||||
|     @required String imageName, | ||||
|     @required this.textureWidth, | ||||
|     @required this.textureHeight, | ||||
|     @required this.columns, | ||||
|     @required this.rows, | ||||
|   }) { | ||||
|     _sprites = List.generate( | ||||
|       rows, | ||||
|       (y) => List.generate( | ||||
|         columns, | ||||
|         (x) => _mapImagePath(imageName, textureWidth, textureHeight, x, y), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Sprite _mapImagePath( | ||||
|     String imageName, | ||||
|     int textureWidth, | ||||
|     int textureHeight, | ||||
|     int x, | ||||
|     int y, | ||||
|   ) { | ||||
|     return Sprite( | ||||
|       imageName, | ||||
|       x: (x * textureWidth).toDouble(), | ||||
|       y: (y * textureHeight).toDouble(), | ||||
|       width: textureWidth.toDouble(), | ||||
|       height: textureHeight.toDouble(), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   SpriteSheet.fromImage({ | ||||
|     @required Image image, | ||||
|     @required this.textureWidth, | ||||
|     @required this.textureHeight, | ||||
| @ -56,19 +24,19 @@ class SpriteSheet { | ||||
|       rows, | ||||
|       (y) => List.generate( | ||||
|         columns, | ||||
|         (x) => _mapImage(image, textureWidth, textureHeight, x, y), | ||||
|         (x) => _mapImagePath(image, textureWidth, textureHeight, x, y), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   Sprite _mapImage( | ||||
|   Sprite _mapImagePath( | ||||
|     Image image, | ||||
|     int textureWidth, | ||||
|     int textureHeight, | ||||
|     int x, | ||||
|     int y, | ||||
|   ) { | ||||
|     return Sprite.fromImage( | ||||
|     return Sprite( | ||||
|       image, | ||||
|       x: (x * textureWidth).toDouble(), | ||||
|       y: (y * textureHeight).toDouble(), | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Erick Zanardo
					Erick Zanardo