mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 19:12:31 +08:00
Start v1.0 apis (sprite, animation, box2d, etc)
This commit is contained in:
@ -10,6 +10,14 @@ import 'package:path_provider/path_provider.dart';
|
||||
class Audio {
|
||||
Map<String, File> loadedFiles = new Map();
|
||||
|
||||
void clear(String fileName) {
|
||||
loadedFiles.remove(fileName);
|
||||
}
|
||||
|
||||
void clearCache() {
|
||||
loadedFiles.clear();
|
||||
}
|
||||
|
||||
void disableLog() {
|
||||
AudioPlayer.logEnabled = false;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
42
lib/components/animation_component.dart
Normal file
42
lib/components/animation_component.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'component.dart';
|
||||
import '../sprite.dart';
|
||||
|
||||
class AnimationComponent extends PositionComponent {
|
||||
|
||||
double width, height;
|
||||
|
||||
List<Sprite> 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<Sprite>(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;
|
||||
}
|
||||
}
|
||||
69
lib/components/component.dart
Normal file
69
lib/components/component.dart
Normal file
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ParallaxRenderer> 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<String> filenames) {
|
||||
var futures =
|
||||
filenames.fold(new List<Future>(), (List<Future> result, filename) {
|
||||
filenames.fold(new List<Future>(), (List<Future> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,24 @@ import 'dart:async';
|
||||
|
||||
class Images {
|
||||
|
||||
Future<Image> load(String name) async {
|
||||
Map<String, Image> loadedFiles = new Map();
|
||||
|
||||
void clear(String fileName) {
|
||||
loadedFiles.remove(fileName);
|
||||
}
|
||||
|
||||
void clearCache() {
|
||||
loadedFiles.clear();
|
||||
}
|
||||
|
||||
Future<Image> load(String fileName) async {
|
||||
if (!loadedFiles.containsKey(fileName)) {
|
||||
loadedFiles[fileName] = await _fetchToMemory(fileName);
|
||||
}
|
||||
return loadedFiles[fileName];
|
||||
}
|
||||
|
||||
Future<Image> _fetchToMemory(String name) async {
|
||||
ByteData data = await rootBundle.load('assets/images/' + name);
|
||||
Uint8List bytes = new Uint8List.view(data.buffer);
|
||||
Completer<Image> completer = new Completer();
|
||||
|
||||
35
lib/sprite.dart
Normal file
35
lib/sprite.dart
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user