mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 19:12:31 +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