mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-03 12:28:03 +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 {
|
class Audio {
|
||||||
Map<String, File> loadedFiles = new Map();
|
Map<String, File> loadedFiles = new Map();
|
||||||
|
|
||||||
|
void clear(String fileName) {
|
||||||
|
loadedFiles.remove(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearCache() {
|
||||||
|
loadedFiles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void disableLog() {
|
void disableLog() {
|
||||||
AudioPlayer.logEnabled = false;
|
AudioPlayer.logEnabled = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import 'dart:ui';
|
|||||||
|
|
||||||
import 'package:box2d/box2d.dart' hide Timer;
|
import 'package:box2d/box2d.dart' hide Timer;
|
||||||
import 'package:flame/box2d/viewport.dart';
|
import 'package:flame/box2d/viewport.dart';
|
||||||
import 'package:flame/component.dart';
|
import 'package:flame/components/component.dart';
|
||||||
|
|
||||||
abstract class Box2DComponent extends Component {
|
abstract class Box2DComponent extends Component {
|
||||||
static const int DEFAULT_WORLD_POOL_SIZE = 100;
|
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:async';
|
||||||
import 'dart:math';
|
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/painting.dart';
|
import 'component.dart';
|
||||||
|
import '../flame.dart';
|
||||||
|
|
||||||
import 'flame.dart';
|
import 'package:flutter/src/painting/images.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) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ParallaxRenderer {
|
class ParallaxRenderer {
|
||||||
String filename;
|
String filename;
|
||||||
@ -113,7 +52,7 @@ class ParallaxComponent extends PositionComponent {
|
|||||||
|
|
||||||
List<ParallaxRenderer> layers = new List();
|
List<ParallaxRenderer> layers = new List();
|
||||||
Size size;
|
Size size;
|
||||||
bool loaded = false;
|
bool _loaded = false;
|
||||||
|
|
||||||
ParallaxComponent(this.size);
|
ParallaxComponent(this.size);
|
||||||
|
|
||||||
@ -132,7 +71,7 @@ class ParallaxComponent extends PositionComponent {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
Future.wait(futures).then((r) {
|
Future.wait(futures).then((r) {
|
||||||
loaded = true;
|
_loaded = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,9 +79,14 @@ class ParallaxComponent extends PositionComponent {
|
|||||||
layers[layerIndex].scroll = scroll;
|
layers[layerIndex].scroll = scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool loaded() {
|
||||||
|
return _loaded;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void render(Canvas canvas) {
|
void render(Canvas canvas) {
|
||||||
if (!loaded) {
|
if (!this.loaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +106,7 @@ class ParallaxComponent extends PositionComponent {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void update(double delta) {
|
void update(double delta) {
|
||||||
if (!loaded) {
|
if (!this.loaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < layers.length; i++) {
|
for (var i = 0; i < layers.length; i++) {
|
||||||
@ -5,7 +5,24 @@ import 'dart:async';
|
|||||||
|
|
||||||
class Images {
|
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);
|
ByteData data = await rootBundle.load('assets/images/' + name);
|
||||||
Uint8List bytes = new Uint8List.view(data.buffer);
|
Uint8List bytes = new Uint8List.view(data.buffer);
|
||||||
Completer<Image> completer = new Completer();
|
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