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/components/mixins/resizable.dart'; | ||||||
| import 'package:flame/text_config.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 { | void main() async { | ||||||
|  |   Flame.initializeWidget(); | ||||||
|   await Flame.util.initialDimensions(); |   await Flame.util.initialDimensions(); | ||||||
|  |  | ||||||
|   final myGame = MyGame(); |   final myGame = MyGame(); | ||||||
|   runApp(myGame.widget); |   runApp(myGame.widget); | ||||||
|   myGame.start(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class AndroidComponent extends SpriteComponent with Resizable { | class AndroidComponent extends SpriteComponent with Resizable { | ||||||
| @ -20,7 +22,7 @@ class AndroidComponent extends SpriteComponent with Resizable { | |||||||
|   int xDirection = 1; |   int xDirection = 1; | ||||||
|   int yDirection = 1; |   int yDirection = 1; | ||||||
|  |  | ||||||
|   AndroidComponent() : super.square(100, 'android.png'); |   AndroidComponent(Image image) : super.square(100, image); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   void update(double dt) { |   void update(double dt) { | ||||||
| @ -56,17 +58,20 @@ class MyGame extends BaseGame { | |||||||
|   @override |   @override | ||||||
|   bool recordFps() => true; |   bool recordFps() => true; | ||||||
|  |  | ||||||
|   void start() { |   @override | ||||||
|     final android = AndroidComponent(); |   Future<void> onLoad() async { | ||||||
|  |     final androidImage = await images.load('android.png'); | ||||||
|  |  | ||||||
|  |     final android = AndroidComponent(androidImage); | ||||||
|     android.x = 100; |     android.x = 100; | ||||||
|     android.y = 400; |     android.y = 400; | ||||||
|  |  | ||||||
|     final android2 = AndroidComponent(); |     final android2 = AndroidComponent(androidImage); | ||||||
|     android2.x = 100; |     android2.x = 100; | ||||||
|     android2.y = 400; |     android2.y = 400; | ||||||
|     android2.yDirection = -1; |     android2.yDirection = -1; | ||||||
|  |  | ||||||
|     final android3 = AndroidComponent(); |     final android3 = AndroidComponent(androidImage); | ||||||
|     android3.x = 100; |     android3.x = 100; | ||||||
|     android3.y = 400; |     android3.y = 400; | ||||||
|     android3.xDirection = -1; |     android3.xDirection = -1; | ||||||
|  | |||||||
| @ -7,15 +7,11 @@ import 'package:flame/flame.dart'; | |||||||
| import 'dart:ui'; | import 'dart:ui'; | ||||||
|  |  | ||||||
| void main() async { | void main() async { | ||||||
|   WidgetsFlutterBinding.ensureInitialized(); |   Flame.initializeWidget(); | ||||||
|  |  | ||||||
|   await Flame.util.fullScreen(); |   await Flame.util.fullScreen(); | ||||||
|  |  | ||||||
|   final playerSprite = await Sprite.loadSprite('player.png'); |   runApp(LayerGame().widget); | ||||||
|   final enemySprite = await Sprite.loadSprite('enemy.png'); |  | ||||||
|   final backgroundSprite = await Sprite.loadSprite('background.png'); |  | ||||||
|  |  | ||||||
|   runApp(LayerGame(playerSprite, enemySprite, backgroundSprite).widget); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class GameLayer extends DynamicLayer { | class GameLayer extends DynamicLayer { | ||||||
| @ -56,14 +52,15 @@ class BackgroundLayer extends PreRenderedLayer { | |||||||
| } | } | ||||||
|  |  | ||||||
| class LayerGame extends Game { | class LayerGame extends Game { | ||||||
|   Sprite playerSprite; |  | ||||||
|   Sprite enemySprite; |  | ||||||
|   Sprite backgroundSprite; |  | ||||||
|  |  | ||||||
|   Layer gameLayer; |   Layer gameLayer; | ||||||
|   Layer backgroundLayer; |   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); |     gameLayer = GameLayer(playerSprite, enemySprite); | ||||||
|     backgroundLayer = BackgroundLayer(backgroundSprite); |     backgroundLayer = BackgroundLayer(backgroundSprite); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -17,8 +17,11 @@ class MyGame extends Game { | |||||||
|   Size size; |   Size size; | ||||||
|   NineTileBox nineTileBox; |   NineTileBox nineTileBox; | ||||||
|  |  | ||||||
|   MyGame(this.size) { |   MyGame(this.size); | ||||||
|     final sprite = Sprite('nine-box.png'); |  | ||||||
|  |   @override | ||||||
|  |   Future<void> onLoad() async { | ||||||
|  |     final sprite = Sprite(await images.load('nine-box.png')); | ||||||
|     nineTileBox = NineTileBox(sprite, tileSize: 8, destTileSize: 24); |     nineTileBox = NineTileBox(sprite, tileSize: 8, destTileSize: 24); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | |||||||
| @ -65,6 +65,12 @@ class MyGame extends BaseGame { | |||||||
|     Timer.periodic(sceneDuration, (_) => spawnParticles()); |     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] |   /// Showcases various different uses of [Particle] | ||||||
|   /// and its derivatives |   /// and its derivatives | ||||||
|   void spawnParticles() { |   void spawnParticles() { | ||||||
| @ -295,7 +301,7 @@ class MyGame extends BaseGame { | |||||||
|   Particle imageParticle() { |   Particle imageParticle() { | ||||||
|     return ImageParticle( |     return ImageParticle( | ||||||
|       size: const Size.square(24), |       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. |   /// Flame's [Sprite] into the effect. | ||||||
|   Particle spriteParticle() { |   Particle spriteParticle() { | ||||||
|     return SpriteParticle( |     return SpriteParticle( | ||||||
|       sprite: Sprite('zap.png'), |       sprite: Sprite(images.fromCache('zap.png')), | ||||||
|       size: Position.fromOffset(cellSize * .5), |       size: Position.fromOffset(cellSize * .5), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| @ -524,12 +530,11 @@ class MyGame extends BaseGame { | |||||||
|     const columns = 8; |     const columns = 8; | ||||||
|     const rows = 8; |     const rows = 8; | ||||||
|     const frames = columns * rows; |     const frames = columns * rows; | ||||||
|     const imagePath = 'boom3.png'; |     final spriteImage = images.fromCache('boom3.png'); | ||||||
|     final spriteImage = Flame.images.loadedFiles[imagePath].loadedImage; |  | ||||||
|     final spritesheet = SpriteSheet( |     final spritesheet = SpriteSheet( | ||||||
|       rows: rows, |       rows: rows, | ||||||
|       columns: columns, |       columns: columns, | ||||||
|       imageName: imagePath, |       image: spriteImage, | ||||||
|       textureWidth: spriteImage.width ~/ columns, |       textureWidth: spriteImage.width ~/ columns, | ||||||
|       textureHeight: spriteImage.height ~/ rows, |       textureHeight: spriteImage.height ~/ rows, | ||||||
|     ); |     ); | ||||||
| @ -543,19 +548,8 @@ class MyGame extends BaseGame { | |||||||
| } | } | ||||||
|  |  | ||||||
| Future<BaseGame> loadGame() async { | Future<BaseGame> loadGame() async { | ||||||
|   Size gameSize; |   Flame.initializeWidget(); | ||||||
|   WidgetsFlutterBinding.ensureInitialized(); |   final gameSize = await Flame.util.initialDimensions(); | ||||||
|  |  | ||||||
|   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', |  | ||||||
|     ]), |  | ||||||
|   ]); |  | ||||||
|  |  | ||||||
|   return MyGame(screenSize: gameSize); |   return MyGame(screenSize: gameSize); | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,14 +6,21 @@ import 'dart:convert' show base64; | |||||||
| import 'package:flame/flame.dart'; | import 'package:flame/flame.dart'; | ||||||
| 
 | 
 | ||||||
| class Images { | class Images { | ||||||
|   Map<String, ImageAssetLoader> loadedFiles = {}; |   final Map<String, _ImageAssetLoader> _loadedFiles = {}; | ||||||
| 
 | 
 | ||||||
|   void clear(String fileName) { |   void clear(String fileName) { | ||||||
|     loadedFiles.remove(fileName); |     _loadedFiles.remove(fileName); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   void clearCache() { |   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 { |   Future<List<Image>> loadAll(List<String> fileNames) async { | ||||||
| @ -21,17 +28,17 @@ class Images { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<Image> load(String fileName) async { |   Future<Image> load(String fileName) async { | ||||||
|     if (!loadedFiles.containsKey(fileName)) { |     if (!_loadedFiles.containsKey(fileName)) { | ||||||
|       loadedFiles[fileName] = ImageAssetLoader(_fetchToMemory(fileName)); |       _loadedFiles[fileName] = _ImageAssetLoader(_fetchToMemory(fileName)); | ||||||
|     } |     } | ||||||
|     return await loadedFiles[fileName].retreive(); |     return await _loadedFiles[fileName].retreive(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<Image> fromBase64(String fileName, String base64) async { |   Future<Image> fromBase64(String fileName, String base64) async { | ||||||
|     if (!loadedFiles.containsKey(fileName)) { |     if (!_loadedFiles.containsKey(fileName)) { | ||||||
|       loadedFiles[fileName] = ImageAssetLoader(_fetchFromBase64(base64)); |       _loadedFiles[fileName] = _ImageAssetLoader(_fetchFromBase64(base64)); | ||||||
|     } |     } | ||||||
|     return await loadedFiles[fileName].retreive(); |     return await _loadedFiles[fileName].retreive(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<Image> _fetchFromBase64(String base64Data) async { |   Future<Image> _fetchFromBase64(String base64Data) async { | ||||||
| @ -53,8 +60,8 @@ class Images { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class ImageAssetLoader { | class _ImageAssetLoader { | ||||||
|   ImageAssetLoader(this.future); |   _ImageAssetLoader(this.future); | ||||||
| 
 | 
 | ||||||
|   Image loadedImage; |   Image loadedImage; | ||||||
|   Future<Image> future; |   Future<Image> future; | ||||||
| @ -6,7 +6,7 @@ import 'package:flutter/widgets.dart'; | |||||||
|  |  | ||||||
| import 'flame_audio.dart'; | import 'flame_audio.dart'; | ||||||
| import 'bgm.dart'; | import 'bgm.dart'; | ||||||
| import 'images.dart'; | import 'assets/images.dart'; | ||||||
| import 'assets_cache.dart'; | import 'assets_cache.dart'; | ||||||
| import 'util.dart'; | import 'util.dart'; | ||||||
|  |  | ||||||
|  | |||||||
| @ -7,10 +7,11 @@ import 'package:flutter/widgets.dart' hide WidgetBuilder; | |||||||
| import 'package:flutter/foundation.dart'; | import 'package:flutter/foundation.dart'; | ||||||
| import 'package:flutter/services.dart'; | import 'package:flutter/services.dart'; | ||||||
|  |  | ||||||
| import '../keyboard.dart'; |  | ||||||
|  |  | ||||||
| import 'widget_builder.dart'; | import 'widget_builder.dart'; | ||||||
|  |  | ||||||
|  | import '../keyboard.dart'; | ||||||
|  | import '../assets/images.dart'; | ||||||
|  |  | ||||||
| /// Represents a generic game. | /// Represents a generic game. | ||||||
| /// | /// | ||||||
| /// Subclass this to implement the [update] and [render] methods. | /// Subclass this to implement the [update] and [render] methods. | ||||||
| @ -19,6 +20,8 @@ abstract class Game { | |||||||
|   // Widget Builder for this Game |   // Widget Builder for this Game | ||||||
|   final builder = WidgetBuilder(); |   final builder = WidgetBuilder(); | ||||||
|  |  | ||||||
|  |   final images = Images(); | ||||||
|  |  | ||||||
|   /// Returns the game background color. |   /// Returns the game background color. | ||||||
|   /// By default it will return a black 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. |   /// 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) { |     if (this is KeyboardEvents) { | ||||||
|       RawKeyboard.instance.removeListener(_handleKeyEvent); |       RawKeyboard.instance.removeListener(_handleKeyEvent); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     images.clearCache(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// Flag to tell the game loop if it should start running upon creation |   /// Flag to tell the game loop if it should start running upon creation | ||||||
|  | |||||||
| @ -14,38 +14,6 @@ class SpriteSheet { | |||||||
|   List<List<Sprite>> _sprites; |   List<List<Sprite>> _sprites; | ||||||
|  |  | ||||||
|   SpriteSheet({ |   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 Image image, | ||||||
|     @required this.textureWidth, |     @required this.textureWidth, | ||||||
|     @required this.textureHeight, |     @required this.textureHeight, | ||||||
| @ -56,19 +24,19 @@ class SpriteSheet { | |||||||
|       rows, |       rows, | ||||||
|       (y) => List.generate( |       (y) => List.generate( | ||||||
|         columns, |         columns, | ||||||
|         (x) => _mapImage(image, textureWidth, textureHeight, x, y), |         (x) => _mapImagePath(image, textureWidth, textureHeight, x, y), | ||||||
|       ), |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Sprite _mapImage( |   Sprite _mapImagePath( | ||||||
|     Image image, |     Image image, | ||||||
|     int textureWidth, |     int textureWidth, | ||||||
|     int textureHeight, |     int textureHeight, | ||||||
|     int x, |     int x, | ||||||
|     int y, |     int y, | ||||||
|   ) { |   ) { | ||||||
|     return Sprite.fromImage( |     return Sprite( | ||||||
|       image, |       image, | ||||||
|       x: (x * textureWidth).toDouble(), |       x: (x * textureWidth).toDouble(), | ||||||
|       y: (y * textureHeight).toDouble(), |       y: (y * textureHeight).toDouble(), | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Erick Zanardo
					Erick Zanardo