Simplified the usage of ShapeComponent (#1068)

* Simplified the usage of ShapeComponent

* Default constructor for _RandomCircle

* Use default constructor

* Forced Anchor.center on ShapeComponent

* Fix examples using SquareComponent

* Removed unnecesary import

* Renamed edgeLength to size
This commit is contained in:
Lukas Klingsbo
2021-11-03 14:30:58 +01:00
committed by GitHub
parent b8ea25eceb
commit b7a2d3fdf8
15 changed files with 115 additions and 102 deletions

View File

@ -1,28 +0,0 @@
import 'dart:ui';
import 'package:flame/components.dart';
class CircleComponent extends PositionComponent {
CircleComponent({this.radius = 10.0})
: paint = Paint()..color = const Color(0xFF60CB35),
super(
size: Vector2.all(2 * radius),
anchor: Anchor.center,
);
Paint paint;
double radius;
@override
void render(Canvas canvas) {
super.render(canvas);
canvas.drawCircle(Offset(radius, radius), radius, paint);
}
@override
bool containsPoint(Vector2 point) {
final local = absoluteToLocal(point);
final center = Vector2.all(radius);
return local.distanceToSquared(center) <= radius * radius;
}
}

View File

@ -2,21 +2,17 @@ import 'dart:ui';
import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame/palette.dart';
class SquareComponent extends PositionComponent with EffectsHelper {
Paint paint = BasicPalette.white.paint();
SquareComponent({int priority = 0, double size = 100.0})
: super(
size: Vector2.all(size),
class SquareComponent extends RectangleComponent with EffectsHelper {
SquareComponent({
Vector2? position,
double size = 100.0,
Paint? paint,
int priority = 0,
}) : super(
Vector2.all(size),
position: position,
paint: paint,
priority: priority,
anchor: Anchor.center,
);
@override
void render(Canvas c) {
super.render(c);
c.drawRect(size.toRect(), paint);
}
}

View File

@ -60,11 +60,7 @@ class OnlyShapes extends FlameGame with HasTappableComponents {
class MyShapeComponent extends ShapeComponent with Tappable {
MyShapeComponent(Shape shape, Paint shapePaint)
: super(
shape,
shapePaint,
anchor: Anchor.center,
);
: super(shape, paint: shapePaint);
@override
bool onTapDown(TapDownInfo info) {

View File

@ -15,13 +15,8 @@ class CombinedEffectGame extends FlameGame with TapDetector {
@override
Future<void> onLoad() async {
await super.onLoad();
greenSquare = SquareComponent()
..paint = green
..position.setValues(100, 100);
redSquare = SquareComponent()
..paint = red
..position.setValues(100, 100);
greenSquare = SquareComponent(position: Vector2.all(100), paint: green);
redSquare = SquareComponent(position: Vector2.all(100), paint: red);
add(greenSquare);
add(redSquare);

View File

@ -13,9 +13,7 @@ final red = Paint()..color = const Color(0xAA883333);
final orange = Paint()..color = const Color(0xAABB6633);
SquareComponent makeSquare(Paint paint) {
return SquareComponent()
..paint = paint
..position.setValues(100, 100);
return SquareComponent(position: Vector2.all(100), paint: paint);
}
class InfiniteEffectGame extends FlameGame with TapDetector {

View File

@ -4,7 +4,6 @@ import 'package:flame/extensions.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import '../../commons/circle_component.dart';
import '../../commons/square_component.dart';
class MoveEffectGame extends FlameGame with TapDetector {
@ -21,12 +20,10 @@ class MoveEffectGame extends FlameGame with TapDetector {
@override
Future<void> onLoad() async {
await super.onLoad();
square = SquareComponent(size: 50)..position.setValues(200, 150);
square = SquareComponent(size: 50, position: Vector2(200, 150));
add(square);
add(Component()
..addAll([
for (final point in path) CircleComponent(radius: 3)..position = point
]));
final pathMarkers = path.map((p) => CircleComponent(3, position: p));
addAll(pathMarkers);
}
@override

View File

@ -5,7 +5,6 @@ import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flame/src/effects2/remove_effect.dart'; // ignore: implementation_imports
import 'package:flutter/material.dart';
import '../../commons/circle_component.dart';
class RemoveEffectExample extends FlameGame with HasTappableComponents {
static const description = '''
@ -19,18 +18,24 @@ class RemoveEffectExample extends FlameGame with HasTappableComponents {
camera.viewport = FixedResolutionViewport(Vector2(400, 600));
final rng = Random();
for (var i = 0; i < 20; i++) {
add(_RandomCircle(rng));
add(_RandomCircle.random(rng));
}
}
}
class _RandomCircle extends CircleComponent with Tappable {
_RandomCircle(Random rng) : super(radius: rng.nextDouble() * 30 + 10) {
position.setValues(
_RandomCircle(double radius, {Vector2? position, Paint? paint})
: super(radius, position: position, paint: paint);
factory _RandomCircle.random(Random rng) {
final radius = rng.nextDouble() * 30 + 10;
final position = Vector2(
rng.nextDouble() * 320 + 40,
rng.nextDouble() * 520 + 40,
);
paint.color = Colors.primaries[rng.nextInt(Colors.primaries.length)];
final paint = Paint()
..color = Colors.primaries[rng.nextInt(Colors.primaries.length)];
return _RandomCircle(radius, position: position, paint: paint);
}
@override

View File

@ -14,9 +14,7 @@ class RotateEffectGame extends FlameGame with TapDetector {
@override
Future<void> onLoad() async {
await super.onLoad();
square = SquareComponent()
..position.setValues(200, 200)
..anchor = Anchor.center;
square = SquareComponent(position: Vector2.all(200));
add(square);
}

View File

@ -19,10 +19,7 @@ class ScaleEffectGame extends FlameGame with TapDetector {
..position.setValues(200, 200)
..anchor = Anchor.center;
square.paint = BasicPalette.white.paint()..style = PaintingStyle.stroke;
final childSquare = SquareComponent()
..position = Vector2.all(70)
..size = Vector2.all(20)
..anchor = Anchor.center;
final childSquare = SquareComponent(position: Vector2.all(70), size: 20);
square.add(childSquare);
add(square);

View File

@ -14,9 +14,7 @@ class SequenceEffectGame extends FlameGame with TapDetector {
@override
Future<void> onLoad() async {
await super.onLoad();
greenSquare = SquareComponent()
..paint = green
..position.setValues(100, 100);
greenSquare = SquareComponent(position: Vector2.all(100), paint: green);
add(greenSquare);
}

View File

@ -22,15 +22,11 @@ class SizeEffectGame extends FlameGame with TapDetector {
@override
Future<void> onLoad() async {
await super.onLoad();
square = SquareComponent()
..position.setValues(200, 200)
..anchor = Anchor.center;
square.paint = BasicPalette.white.paint()..style = PaintingStyle.stroke;
final childSquare = SquareComponent()
..position = Vector2.all(70)
..size = Vector2.all(20)
..anchor = Anchor.center;
square = SquareComponent(
position: Vector2.all(200),
paint: BasicPalette.white.paint()..style = PaintingStyle.stroke,
);
final childSquare = SquareComponent(position: Vector2.all(70), size: 20);
square.add(childSquare);
add(square);
}

View File

@ -13,6 +13,7 @@
- Possibility to manually remove `TimerComponent`
- Rename `Hitbox` mixin to `HasHitboxes`
- Added `RemoveEffect` and `SimpleEffectController`
- Create default implementations of `RectangleComponent`, `CircleComponent` and `PolygonComponent`
## [1.0.0-releasecandidate.16]
- `changePriority` no longer breaks game loop iteration

View File

@ -223,7 +223,7 @@ class Component with Loadable {
/// Adds multiple children.
///
/// See [add] for details.
Future<void> addAll(List<Component> components) {
Future<void> addAll(Iterable<Component> components) {
return children.addChildren(components);
}

View File

@ -1,24 +1,32 @@
import 'dart:ui' hide Offset;
import 'package:flutter/material.dart';
import '../../components.dart';
import '../../geometry.dart';
import '../../palette.dart';
import '../anchor.dart';
import '../extensions/vector2.dart';
class ShapeComponent extends PositionComponent {
final Shape shape;
final Paint shapePaint;
Paint paint;
/// Currently the [anchor] can only be center for [ShapeComponent], since
/// shape doesn't take any anchor into consideration.
@override
final Anchor anchor = Anchor.center;
ShapeComponent(
this.shape,
this.shapePaint, {
Anchor anchor = Anchor.topLeft,
this.shape, {
Paint? paint,
int? priority,
}) : super(
}) : paint = paint ?? BasicPalette.white.paint(),
super(
position: shape.position,
size: shape.size,
angle: shape.angle,
anchor: anchor,
anchor: Anchor.center,
priority: priority,
) {
shape.isCanvasPrepared = true;
@ -27,9 +35,70 @@ class ShapeComponent extends PositionComponent {
@override
void render(Canvas canvas) {
super.render(canvas);
shape.render(canvas, shapePaint);
shape.render(canvas, paint);
}
@override
bool containsPoint(Vector2 point) => shape.containsPoint(point);
}
class CircleComponent extends ShapeComponent {
CircleComponent(
double radius, {
Vector2? position,
Paint? paint,
int? priority,
}) : super(
Circle(radius: radius, position: position),
paint: paint,
priority: priority,
);
}
class RectangleComponent extends ShapeComponent {
RectangleComponent(
Vector2 size, {
Vector2? position,
Paint? paint,
int? priority,
}) : super(
Rectangle(size: size, position: position),
paint: paint,
priority: priority,
);
RectangleComponent.square(
double size, {
Vector2? position,
Paint? paint,
int? priority,
}) : super(
Rectangle(size: Vector2.all(size), position: position),
paint: paint,
priority: priority,
);
}
class PolygonComponent extends ShapeComponent {
PolygonComponent(
List<Vector2> points, {
Paint? paint,
int? priority,
}) : super(Polygon(points), paint: paint, priority: priority);
PolygonComponent.fromDefinition(
List<Vector2> normalizedVertices, {
Vector2? size,
Vector2? position,
Paint? paint,
int? priority,
}) : super(
Polygon.fromDefinition(
normalizedVertices,
position: position,
size: size,
),
paint: paint,
priority: priority,
);
}

View File

@ -2,7 +2,6 @@ import 'dart:ui';
import '../../components.dart';
import '../../game.dart';
import '../../palette.dart';
import '../components/cache/value_cache.dart';
import '../extensions/vector2.dart';
import 'shape_intersections.dart' as intersection_system;
@ -123,12 +122,8 @@ abstract class Shape {
/// Do note that while a [Shape] is defined from the center, a
/// [ShapeComponent] like all other components default to an [Anchor] in the
/// top left corner.
ShapeComponent toComponent({Paint? paint, Anchor anchor = Anchor.topLeft}) {
return ShapeComponent(
this,
paint ?? BasicPalette.white.paint(),
anchor: anchor,
);
ShapeComponent toComponent({Paint? paint}) {
return ShapeComponent(this, paint: paint);
}
}