mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 19:12:31 +08:00
Fixed with regards to the comments
This commit is contained in:
@ -14,13 +14,13 @@ The most commonly used implementation, `SpriteComponent`, can be created with a
|
||||
Sprite sprite = Sprite('player.png');
|
||||
|
||||
final size = Vector2.all(128.0);
|
||||
var player = SpriteComponent.fromSprite(size, sprite); // width, height, sprite
|
||||
var player = SpriteComponent.fromSprite(size, sprite);
|
||||
|
||||
// screen coordinates
|
||||
player.position = ... // Vector2(0.0, 0,0) by default
|
||||
player.position = ... // Vector2(0.0, 0.0) by default
|
||||
player.angle = ... // 0 by default
|
||||
|
||||
player.render(canvas); // it will render only if the image is loaded and the x, y, width and height parameters are not null
|
||||
player.render(canvas); // it will render only if the image is loaded and the position and size parameters are not null
|
||||
```
|
||||
|
||||
In the event that you want to easily change the direction of your components rendering, you can also use
|
||||
@ -54,20 +54,31 @@ This component uses an instance of the [Animation](/doc/images.md#Animation) cla
|
||||
This will create a simple three frame animation
|
||||
|
||||
```dart
|
||||
List<Sprite> sprites = [0, 1, 2].map((i) => new Sprite('player_${i}.png')).toList();
|
||||
final size = Vector2(64.0, 64.0);
|
||||
List<Sprite> sprites = [0, 1, 2].map((i) => Sprite('player_${i}.png')).toList();
|
||||
final size = Vector2.all(64.0);
|
||||
this.player = AnimationComponent(size, new Animation.spriteList(sprites, stepTime: 0.01));
|
||||
```
|
||||
|
||||
If you have a sprite sheet, you can use the `sequenced` constructor, identical to the one provided by the `Animation` class (check more details in [the appropriate section](/doc/images.md#Animation)):
|
||||
|
||||
```dart
|
||||
final size = Vector2(64.0, 64.0);
|
||||
final size = Vector2.all(64.0);
|
||||
this.player = AnimationComponent.sequenced(size, 'player.png', 2);
|
||||
```
|
||||
|
||||
If you are not using `BaseGame`, don't forget this component needs to be update'd even if static, because the animation object needs to be ticked to move the frames.
|
||||
|
||||
## SvgComponent
|
||||
|
||||
This component uses an instance of `Svg` class to represent a Component that has a svg that is rendered on the game:
|
||||
|
||||
```dart
|
||||
Svg svg = Svg('android.svg');
|
||||
SvgComponent android = SvgComponent.fromSvg(100, 100, svg);
|
||||
android.x = 100;
|
||||
android.y = 100;
|
||||
```
|
||||
|
||||
## FlareActor Component
|
||||
|
||||
*Note*: The previous implementation of a Flare integration API using `FlareAnimation` and `FlareComponent` has been deprecated.
|
||||
|
||||
@ -24,7 +24,7 @@ class MyGame extends BaseGame {
|
||||
);
|
||||
final spriteSize = Vector2.all(200);
|
||||
final animationComponent = SpriteAnimationComponent(spriteSize, animation)
|
||||
..position = size / 2 - Vector2(100, 100);
|
||||
..position = size / 2 - Vector2.all(100);
|
||||
|
||||
add(animationComponent);
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ class AndroidComponent extends SpriteComponent with Resizable {
|
||||
int xDirection = 1;
|
||||
int yDirection = 1;
|
||||
|
||||
AndroidComponent() : super.square(100, 'android.png');
|
||||
AndroidComponent() : super.fromImagePath(Vector2.all(100), 'android.png');
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
|
||||
@ -24,8 +24,8 @@ class MyGame extends BaseGame with TapDetector {
|
||||
MyGame() {
|
||||
final green = Paint()..color = const Color(0xAA338833);
|
||||
final red = Paint()..color = const Color(0xAA883333);
|
||||
greenSquare = Square(green, 100, 100);
|
||||
final redSquare = Square(red, 100, 100);
|
||||
greenSquare = Square(green, Vector2.all(100));
|
||||
final redSquare = Square(red, Vector2.all(100));
|
||||
add(greenSquare);
|
||||
add(redSquare);
|
||||
}
|
||||
|
||||
@ -8,10 +8,9 @@ import 'package:flame/extensions/vector2.dart';
|
||||
class Square extends PositionComponent {
|
||||
final Paint _paint;
|
||||
|
||||
Square(this._paint, double x, double y, {double angle = 0.0}) {
|
||||
size = Vector2(width, height);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
Square(this._paint, Vector2 position, {double angle = 0.0}) {
|
||||
size = Vector2.all(100.0);
|
||||
this.position = position;
|
||||
this.angle = angle;
|
||||
anchor = Anchor.center;
|
||||
}
|
||||
|
||||
@ -26,9 +26,9 @@ class MyGame extends BaseGame with TapDetector {
|
||||
final green = Paint()..color = const Color(0xAA338833);
|
||||
final red = Paint()..color = const Color(0xAA883333);
|
||||
final orange = Paint()..color = const Color(0xAABB6633);
|
||||
greenSquare = Square(green, 100, 100);
|
||||
redSquare = Square(red, 200, 200);
|
||||
orangeSquare = Square(orange, 200, 400);
|
||||
greenSquare = Square(green, Vector2.all(100));
|
||||
redSquare = Square(red, Vector2.all(200));
|
||||
orangeSquare = Square(orange, Vector2(200, 400));
|
||||
add(greenSquare);
|
||||
add(redSquare);
|
||||
add(orangeSquare);
|
||||
|
||||
@ -8,10 +8,9 @@ import 'package:flame/extensions/vector2.dart';
|
||||
class Square extends PositionComponent {
|
||||
final Paint _paint;
|
||||
|
||||
Square(this._paint, double x, double y, {double angle = 0.0}) {
|
||||
size = Vector2(width, height);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
Square(this._paint, Vector2 position, {double angle = 0.0}) {
|
||||
size = Vector2.all(100.0);
|
||||
this.position = position;
|
||||
this.angle = angle;
|
||||
anchor = Anchor.center;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ class MyGame extends BaseGame with TapDetector {
|
||||
|
||||
MyGame() {
|
||||
final green = Paint()..color = const Color(0xAA338833);
|
||||
greenSquare = Square(green, 100, 100);
|
||||
greenSquare = Square(green, Vector2.all(100));
|
||||
add(greenSquare);
|
||||
}
|
||||
|
||||
|
||||
@ -8,10 +8,9 @@ import 'package:flame/extensions/vector2.dart';
|
||||
class Square extends PositionComponent {
|
||||
final Paint _paint;
|
||||
|
||||
Square(this._paint, double x, double y, {double angle = 0.0}) {
|
||||
size = Vector2(width, height);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
Square(this._paint, Vector2 position, {double angle = 0.0}) {
|
||||
size = Vector2.all(100.0);
|
||||
this.position = position;
|
||||
this.angle = angle;
|
||||
anchor = Anchor.center;
|
||||
}
|
||||
|
||||
@ -22,10 +22,9 @@ class TapableSquare extends PositionComponent with Tapable {
|
||||
|
||||
bool _beenPressed = false;
|
||||
|
||||
TapableSquare({double y = 100, double x = 100}) {
|
||||
TapableSquare({Vector2 position}) {
|
||||
size = Vector2.all(100);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.position = position ?? Vector2.all(100);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -52,7 +51,7 @@ class TapableSquare extends PositionComponent with Tapable {
|
||||
|
||||
class MyGame extends BaseGame with HasTapableComponents {
|
||||
MyGame() {
|
||||
add(TapableSquare(y: 100));
|
||||
add(TapableSquare(y: 250));
|
||||
add(TapableSquare());
|
||||
add(TapableSquare()..y = 250);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,8 @@ class Selector extends SpriteComponent {
|
||||
bool show = false;
|
||||
|
||||
Selector(double s)
|
||||
: super.fromSprite(s, s, Sprite('selector.png', width: 32, height: 32));
|
||||
: super.fromSprite(
|
||||
Vector2.all(s), Sprite('selector.png', size: Vector2.all(32.0)));
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
@ -81,6 +82,6 @@ class MyGame extends BaseGame with MouseMovementDetector {
|
||||
final screenPosition = event.position.toVector2();
|
||||
final block = base.getBlock(screenPosition);
|
||||
selector.show = base.containsBlock(block);
|
||||
selector.setPosition(base.getBlockPosition(block) + topLeft);
|
||||
selector.position = base.getBlockPosition(block) + topLeft;
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,6 +52,6 @@ class MyGame extends BaseGame {
|
||||
|
||||
add(Ball(size)
|
||||
..y = (size.y / 2) - 50
|
||||
..size = Vector2(100, 100));
|
||||
..size = Vector2.all(100));
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,8 +27,10 @@ class MyGame extends BaseGame {
|
||||
|
||||
void initSprites() async {
|
||||
final r = Random();
|
||||
List.generate(500, (i) => SpriteComponent.square(32, 'test.png'))
|
||||
.forEach((sprite) {
|
||||
List.generate(
|
||||
500,
|
||||
(i) => SpriteComponent.fromImagePath(Vector2.all(32), 'test.png'),
|
||||
).forEach((sprite) {
|
||||
sprite.x = r.nextInt(size.x.toInt()).toDouble();
|
||||
sprite.y = r.nextInt(size.y.toInt()).toDouble();
|
||||
add(sprite);
|
||||
|
||||
@ -30,7 +30,8 @@ class FlareComponent extends PositionComponent {
|
||||
}
|
||||
}
|
||||
|
||||
void updateSize(Vector2 newSize) {
|
||||
@override
|
||||
set size(Vector2 newSize) {
|
||||
super.size = newSize;
|
||||
if (loaded()) {
|
||||
_flareAnimation.size = size;
|
||||
|
||||
@ -93,17 +93,14 @@ class IsometricTileMapComponent extends PositionComponent {
|
||||
void render(Canvas c) {
|
||||
super.render(c);
|
||||
|
||||
final size = Vector2(
|
||||
effectiveTileSize.toDouble(),
|
||||
effectiveTileSize.toDouble(),
|
||||
);
|
||||
final size = Vector2.all(effectiveTileSize.toDouble());
|
||||
for (int i = 0; i < matrix.length; i++) {
|
||||
for (int j = 0; j < matrix[i].length; j++) {
|
||||
final element = matrix[i][j];
|
||||
if (element != -1) {
|
||||
final sprite = tileset.getTile(element);
|
||||
final p = getBlockPositionInts(j, i);
|
||||
sprite.renderRect(c, p.toRect(size));
|
||||
sprite.renderRect(c, p.toPositionedRect(size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import 'dart:ui';
|
||||
import 'dart:ui' hide Offset;
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:ordered_set/comparing.dart';
|
||||
@ -8,6 +8,7 @@ import '../anchor.dart';
|
||||
import '../effects/effects.dart';
|
||||
import '../game.dart';
|
||||
import '../text_config.dart';
|
||||
import '../extensions/offset.dart';
|
||||
import '../extensions/vector2.dart';
|
||||
import 'component.dart';
|
||||
|
||||
@ -41,9 +42,21 @@ abstract class PositionComponent extends Component {
|
||||
|
||||
/// Width (size) that this component is rendered with.
|
||||
double get width => size.x;
|
||||
set width(double width) => size.x = width;
|
||||
|
||||
/// Height (size) that this component is rendered with.
|
||||
double get height => size.y;
|
||||
set height(double height) => size.y = height;
|
||||
|
||||
/// Get the top left position regardless of the anchor
|
||||
Vector2 get anchorPosition {
|
||||
return position - anchor.relativePosition.clone()..multiply(size);
|
||||
}
|
||||
|
||||
/// Set the top left position regardless of the anchor
|
||||
set anchorPosition(Vector2 position) {
|
||||
this.position = position + anchor.relativePosition.clone()..multiply(size);
|
||||
}
|
||||
|
||||
/// Angle (with respect to the x-axis) this component should be rendered with.
|
||||
/// It is rotated around its anchor.
|
||||
@ -80,23 +93,13 @@ abstract class PositionComponent extends Component {
|
||||
|
||||
/// Returns the relative position/size of this component.
|
||||
/// Relative because it might be translated by their parents (which is not considered here).
|
||||
Rect toRect() {
|
||||
return Rect.fromLTWH(
|
||||
x - anchor.relativePosition.x * width,
|
||||
y - anchor.relativePosition.y * height,
|
||||
width,
|
||||
height,
|
||||
);
|
||||
}
|
||||
Rect toRect() => anchorPosition.toPositionedRect(size);
|
||||
|
||||
/// Mutates x, y, width and height using the provided [rect] as basis.
|
||||
/// Mutates position and size using the provided [rect] as basis.
|
||||
/// This is a relative rect, same definition that [toRect] use (therefore both methods are compatible, i.e. setByRect ∘ toRect = identity).
|
||||
void setByRect(Rect rect) {
|
||||
position.setValues(
|
||||
rect.left + anchor.relativePosition.x * rect.width,
|
||||
rect.top + anchor.relativePosition.y * rect.height,
|
||||
);
|
||||
size.setValues(rect.width, rect.height);
|
||||
anchorPosition = rect.topLeft.toVector2();
|
||||
}
|
||||
|
||||
double angleTo(PositionComponent c) => position.angleTo(c.position);
|
||||
@ -125,9 +128,8 @@ abstract class PositionComponent extends Component {
|
||||
canvas.translate(x, y);
|
||||
|
||||
canvas.rotate(angle);
|
||||
final double dx = -anchor.relativePosition.x * width;
|
||||
final double dy = -anchor.relativePosition.y * height;
|
||||
canvas.translate(dx, dy);
|
||||
final Vector2 delta = -anchor.relativePosition.clone()..multiply(size);
|
||||
canvas.translate(delta.x, delta.y);
|
||||
|
||||
// Handle inverted rendering by moving center and flipping.
|
||||
if (renderFlipX || renderFlipY) {
|
||||
|
||||
@ -23,10 +23,7 @@ class SpriteComponent extends PositionComponent {
|
||||
|
||||
SpriteComponent();
|
||||
|
||||
SpriteComponent.square(double size, String imagePath)
|
||||
: this.rectangle(Vector2(size, size), imagePath);
|
||||
|
||||
SpriteComponent.rectangle(Vector2 size, String imagePath)
|
||||
SpriteComponent.fromImagePath(Vector2 size, String imagePath)
|
||||
: this.fromSprite(size, Sprite(imagePath));
|
||||
|
||||
SpriteComponent.fromSprite(Vector2 size, this.sprite) {
|
||||
|
||||
@ -16,17 +16,6 @@ extension RectExtension on Rect {
|
||||
// Until [extension] will allow static methods we need to keep these functions
|
||||
// in a utility class
|
||||
class RectFactory {
|
||||
/// Creates a [Rect] with the size of [Size]
|
||||
static Rect fromSize(Size size) {
|
||||
return Rect.fromLTWH(0, 0, size.width, size.height);
|
||||
}
|
||||
|
||||
/// Creates a [Rect] having its left upper corner in start and its right
|
||||
/// bottom corner in end
|
||||
static Rect fromVectors(Vector2 start, Vector2 end) {
|
||||
return Rect.fromLTWH(start.x, start.y, end.x, end.y);
|
||||
}
|
||||
|
||||
/// Creates bounds in from of a [Rect] from a list of [Vector2]
|
||||
static Rect fromBounds(List<Vector2> pts) {
|
||||
final double minx = pts.map((e) => e.x).reduce(min);
|
||||
|
||||
@ -19,7 +19,7 @@ extension Vector2Extension on Vector2 {
|
||||
/// argument [Vector2]
|
||||
Rect toPositionedRect(Vector2 size) => Rect.fromLTWH(x, y, size.x, size.y);
|
||||
|
||||
/// Creates a [Rect] starting in origo and going the [Vector2]
|
||||
/// Creates a [Rect] starting in origin and going the [Vector2]
|
||||
Rect toRect() => Rect.fromLTWH(0, 0, x, y);
|
||||
|
||||
/// Linearly interpolate towards another Vector2
|
||||
|
||||
@ -85,7 +85,7 @@ class SpriteAnimation {
|
||||
amountPerRow ??= amount;
|
||||
texturePosition ??= Vector2.zero();
|
||||
frames = List<SpriteAnimationFrame>(amount);
|
||||
for (var i = 0; i < amount; i++) {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
final position = Vector2(
|
||||
texturePosition.x + (i % amountPerRow) * textureSize.x,
|
||||
texturePosition.y + (i ~/ amountPerRow) * textureSize.y,
|
||||
@ -111,7 +111,7 @@ class SpriteAnimation {
|
||||
}) : assert(amountPerRow == null || amount >= amountPerRow) {
|
||||
amountPerRow ??= amount;
|
||||
frames = List<SpriteAnimationFrame>(amount);
|
||||
for (var i = 0; i < amount; i++) {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
final position = Vector2(
|
||||
texturePosition.x + (i % amountPerRow) * textureSize.x,
|
||||
texturePosition.y + (i ~/ amountPerRow) * textureSize.y,
|
||||
|
||||
Reference in New Issue
Block a user