TOP(About this memo)) > Flutter > 一覧(Flame) > 衝突
import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flame/palette.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
SafeArea(child: GameWidget(game: Example())),
);
}
class Example extends FlameGame with HasCollisionDetection {
Example() {
debugMode = true;
}
static final _borderPaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2
..color = BasicPalette.red.color;
static final TextPaint textRenderer = TextPaint(
style: const TextStyle(color: Colors.white70, fontSize: 12),
);
@override
Future<void> onLoad() async {
add(ScreenHitbox());
add(Ember(position: Vector2(size.x / 2, size.y / 2)));
add(Rock(Vector2(size.x / 2, size.y / 2)));
final text = TextComponent(
textRenderer: textRenderer,
position: Vector2(0, 0),
anchor: Anchor.topLeft,
);
text.text = "viewport: $size";
add(text);
}
@override
void render(Canvas canvas) {
canvas.drawRect(size.toRect(), _borderPaint);
super.render(canvas);
}
}
class Ember extends SpriteAnimationComponent
with HasGameReference, CollisionCallbacks {
Ember({super.position, super.key})
: super(
priority: 2,
size: Vector2.all(50),
anchor: Anchor.center,
);
late final maxPosition =
Vector2(game.size.x - size.x / 2, game.size.y - size.y / 2);
late final minPosition = Vector2(size.x / 2, size.y / 2);
final Vector2 velocity = Vector2(10, 10);
@override
Future<void> onLoad() async {
animation = await game.loadSpriteAnimation(
'animations/ember.png',
SpriteAnimationData.sequenced(
amount: 3,
textureSize: Vector2.all(16),
stepTime: 0.15,
),
);
add(CircleHitbox());
}
@override
void onCollisionStart(
Set<Vector2> intersectionPoints,
PositionComponent other,
) {
super.onCollisionStart(intersectionPoints, other);
if (other is Rock) {
other.add(
ScaleEffect.to(
Vector2.all(0.5),
EffectController(duration: 0.2, alternate: true),
),
);
}
if (other is ScreenHitbox) {
final collisionPoint = intersectionPoints.first;
// Left Side Collision
if (collisionPoint.x == 0) {
velocity.x = -velocity.x;
velocity.y = velocity.y;
}
// Right Side Collision
if (collisionPoint.x == game.size.x) {
velocity.x = -velocity.x;
velocity.y = velocity.y;
}
// Top Side Collision
if (collisionPoint.y == 0) {
velocity.x = velocity.x;
velocity.y = -velocity.y;
}
// Bottom Side Collision
if (collisionPoint.y == game.size.y) {
velocity.x = velocity.x;
velocity.y = -velocity.y;
}
angle = -velocity.angleToSigned(Vector2(1, 0));
}
}
@override
void update(double dt) {
super.update(dt);
final deltaPosition = velocity * (10 * dt);
position.add(deltaPosition);
position.clamp(minPosition, maxPosition);
}
}
class Rock extends SpriteComponent with HasGameRef, TapCallbacks {
Rock(Vector2 position)
: super(
position: position,
size: Vector2.all(50),
priority: 1,
anchor: Anchor.center,
);
@override
Future<void> onLoad() async {
sprite = await game.loadSprite('nine-box.png');
//add(RectangleHitbox());
add(PolygonHitbox.relative(
[
Vector2(0, -5.0),
Vector2(-6, 0),
Vector2(0, 5),
Vector2(1, 3),
Vector2(1, -3),
],
parentSize: size,
));
}
}