From 2fa22f2f7c5fd0094fb6f8bb17ec8a6aeafdc09a Mon Sep 17 00:00:00 2001 From: Luan Nico Date: Sat, 2 Dec 2017 11:17:35 -0200 Subject: [PATCH] Start v1.0 apis (sprite, animation, box2d, etc) --- lib/audio.dart | 8 ++ lib/box2d/box2d_component.dart | 2 +- lib/components/animation_component.dart | 42 ++++++++++ lib/components/component.dart | 69 +++++++++++++++ .../parallax_component.dart} | 84 ++++--------------- lib/images.dart | 19 ++++- lib/sprite.dart | 35 ++++++++ 7 files changed, 187 insertions(+), 72 deletions(-) create mode 100644 lib/components/animation_component.dart create mode 100644 lib/components/component.dart rename lib/{component.dart => components/parallax_component.dart} (54%) create mode 100644 lib/sprite.dart diff --git a/lib/audio.dart b/lib/audio.dart index 656ee689d..da795eff2 100644 --- a/lib/audio.dart +++ b/lib/audio.dart @@ -10,6 +10,14 @@ import 'package:path_provider/path_provider.dart'; class Audio { Map loadedFiles = new Map(); + void clear(String fileName) { + loadedFiles.remove(fileName); + } + + void clearCache() { + loadedFiles.clear(); + } + void disableLog() { AudioPlayer.logEnabled = false; } diff --git a/lib/box2d/box2d_component.dart b/lib/box2d/box2d_component.dart index 5d504b7bc..c1ed988e0 100644 --- a/lib/box2d/box2d_component.dart +++ b/lib/box2d/box2d_component.dart @@ -2,7 +2,7 @@ import 'dart:ui'; import 'package:box2d/box2d.dart' hide Timer; import 'package:flame/box2d/viewport.dart'; -import 'package:flame/component.dart'; +import 'package:flame/components/component.dart'; abstract class Box2DComponent extends Component { static const int DEFAULT_WORLD_POOL_SIZE = 100; diff --git a/lib/components/animation_component.dart b/lib/components/animation_component.dart new file mode 100644 index 000000000..9958659cd --- /dev/null +++ b/lib/components/animation_component.dart @@ -0,0 +1,42 @@ +import 'dart:ui'; + +import 'component.dart'; +import '../sprite.dart'; + +class AnimationComponent extends PositionComponent { + + double width, height; + + List sprites; + double stepTime = 0.1; + double lifeTime = 0.0; + + AnimationComponent.spriteList(this.width, this.height, this.sprites, { this.stepTime, this.lifeTime }); + + AnimationComponent.sequenced(this.width, this.height, String imagePath, int amount, { double textureX = 0.0, double textureY = 0.0, double textureWidth = -1.0, double textureHeight = -1.0}) { + angle = 0.0; + if (textureWidth == -1) { + textureWidth = this.width; + } + if (textureHeight == -1) { + textureHeight = this.height; + } + sprites = new List(amount); + for (var i = 0; i < amount; i++) { + sprites[i] = new Sprite(imagePath, x: textureX + i*textureWidth, y: textureY, width: textureWidth, height: textureHeight); + } + } + + @override + void render(Canvas canvas) { + prepareCanvas(canvas); + + int i = (lifeTime / stepTime).round(); + sprites[i % sprites.length].render(canvas, width, height); + } + + @override + void update(double t) { + this.lifeTime += t; + } +} \ No newline at end of file diff --git a/lib/components/component.dart b/lib/components/component.dart new file mode 100644 index 000000000..ab091081c --- /dev/null +++ b/lib/components/component.dart @@ -0,0 +1,69 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:flame/sprite.dart'; +import 'package:flutter/painting.dart'; + +abstract class Component { + void update(double t); + + void render(Canvas c); + + bool loaded() { + return true; + } + + bool destroy() { + return false; + } +} + +abstract class PositionComponent extends Component { + double x = 0.0, y = 0.0, angle = 0.0; + + double angleBetween(PositionComponent c) { + return (atan2(c.x - this.x, this.y - c.y) - PI / 2) % (2 * PI); + } + + double distance(PositionComponent c) { + return sqrt(pow(this.y - c.y, 2) + pow(this.x - c.x, 2)); + } + + void prepareCanvas(Canvas canvas) { + canvas.translate(x, y); + canvas.rotate(angle); // TODO: rotate around center + } +} + +class SpriteComponent extends PositionComponent { + double width, height; + Sprite sprite; + + final Paint paint = new Paint()..color = new Color(0xffffffff); + + SpriteComponent.square(double size, String imagePath) : this.rectangle(size, size, imagePath); + + SpriteComponent.rectangle(this.width, this.height, String imagePath) { + this.sprite = new Sprite(imagePath); + } + + SpriteComponent.fromSprite(this.width, this.height, this.sprite); + + @override + render(Canvas canvas) { + if (sprite.loaded()) { + prepareCanvas(canvas); + sprite.render(canvas, width, height); + } + } + + @override + bool loaded() { + return this.sprite.loaded(); + } + + @override + void update(double t) { + } +} + diff --git a/lib/component.dart b/lib/components/parallax_component.dart similarity index 54% rename from lib/component.dart rename to lib/components/parallax_component.dart index 95cdfc0d0..05282596c 100644 --- a/lib/component.dart +++ b/lib/components/parallax_component.dart @@ -1,71 +1,10 @@ import 'dart:async'; -import 'dart:math'; import 'dart:ui'; -import 'package:flutter/painting.dart'; +import 'component.dart'; +import '../flame.dart'; -import 'flame.dart'; - -abstract class Component { - void update(double t); - - void render(Canvas c); -} - -abstract class PositionComponent extends Component { - double x = 0.0, y = 0.0, angle = 0.0; - - double angleBetween(PositionComponent c) { - return (atan2(c.x - this.x, this.y - c.y) - PI / 2) % (2 * PI); - } - - double distance(PositionComponent c) { - return sqrt(pow(this.y - c.y, 2) + pow(this.x - c.x, 2)); - } - - void prepareCanvas(Canvas canvas) { - canvas.translate(x, y); - canvas.rotate(angle); // TODO: rotate around center - } -} - -abstract class SpriteComponent extends PositionComponent { - double width, height; - Image image; - - final Paint paint = new Paint()..color = new Color(0xffffffff); - - SpriteComponent.square(double size, String imagePath) - : this.rectangle(size, size, imagePath); - - SpriteComponent.rectangle(this.width, this.height, String imagePath) { - Flame.images.load(imagePath).then((image) { - this.image = image; - }); - } - - render(Canvas canvas) { - if (image != null) { - prepareCanvas(canvas); - _drawImage(canvas); - } - } - - void _drawImage(Canvas canvas) { - final Rect outputRect = new Rect.fromLTWH(0.0, 0.0, width, height); - final Size imageSize = - new Size(image.width.toDouble(), image.height.toDouble()); - final FittedSizes sizes = - applyBoxFit(BoxFit.cover, imageSize, outputRect.size); - final Rect inputSubrect = - Alignment.center.inscribe(sizes.source, Offset.zero & imageSize); - final Rect outputSubrect = - Alignment.center.inscribe(sizes.destination, outputRect); - canvas.drawImageRect(image, inputSubrect, outputSubrect, paint); - } - - update(double t) {} -} +import 'package:flutter/src/painting/images.dart'; class ParallaxRenderer { String filename; @@ -113,7 +52,7 @@ class ParallaxComponent extends PositionComponent { List layers = new List(); Size size; - bool loaded = false; + bool _loaded = false; ParallaxComponent(this.size); @@ -125,14 +64,14 @@ class ParallaxComponent extends PositionComponent { */ void load(List filenames) { var futures = - filenames.fold(new List(), (List result, filename) { + filenames.fold(new List(), (List result, filename) { var layer = new ParallaxRenderer(filename); layers.add(layer); result.add(layer.future); return result; }); Future.wait(futures).then((r) { - loaded = true; + _loaded = true; }); } @@ -140,9 +79,14 @@ class ParallaxComponent extends PositionComponent { layers[layerIndex].scroll = scroll; } + @override + bool loaded() { + return _loaded; + } + @override void render(Canvas canvas) { - if (!loaded) { + if (!this.loaded()) { return; } @@ -162,7 +106,7 @@ class ParallaxComponent extends PositionComponent { @override void update(double delta) { - if (!loaded) { + if (!this.loaded()) { return; } for (var i = 0; i < layers.length; i++) { @@ -174,4 +118,4 @@ class ParallaxComponent extends PositionComponent { layers[i].scroll = scroll; } } -} +} \ No newline at end of file diff --git a/lib/images.dart b/lib/images.dart index 5a69eac6b..eed24637b 100644 --- a/lib/images.dart +++ b/lib/images.dart @@ -5,7 +5,24 @@ import 'dart:async'; class Images { - Future load(String name) async { + Map loadedFiles = new Map(); + + void clear(String fileName) { + loadedFiles.remove(fileName); + } + + void clearCache() { + loadedFiles.clear(); + } + + Future load(String fileName) async { + if (!loadedFiles.containsKey(fileName)) { + loadedFiles[fileName] = await _fetchToMemory(fileName); + } + return loadedFiles[fileName]; + } + + Future _fetchToMemory(String name) async { ByteData data = await rootBundle.load('assets/images/' + name); Uint8List bytes = new Uint8List.view(data.buffer); Completer completer = new Completer(); diff --git a/lib/sprite.dart b/lib/sprite.dart new file mode 100644 index 000000000..b904056d7 --- /dev/null +++ b/lib/sprite.dart @@ -0,0 +1,35 @@ +import 'dart:ui'; + +import 'package:flame/flame.dart'; +import 'package:flutter/material.dart' show Colors; + +class Sprite { + Image image; + Rect src; + + static final Paint paint = new Paint()..color = Colors.white; + + Sprite(String fileName, {double x = 0.0, double y = 0.0, double width = -1.0, double height = -1.0}) { + Flame.images.load(fileName).then((img) { + if (width == -1.0) { + width = img.width as double; + } + if (height == -1.0) { + width = img.height as double; + } + this.image = img; + this.src = new Rect.fromLTWH(x, y, width, height); + }); + } + + bool loaded() { + return image != null && src != null; + } + + void render(Canvas canvas, double width, double height) { + if (this.loaded()) { + Rect dst = new Rect.fromLTWH(0.0, 0.0, width, height); + canvas.drawImageRect(image, src, dst, paint); + } + } +}