mirror of
https://github.com/johrpan/christmas_cats.git
synced 2025-10-28 19:27:25 +01:00
91 lines
2 KiB
Dart
91 lines
2 KiB
Dart
import 'dart:math';
|
|
import 'dart:ui';
|
|
|
|
import 'package:flame/anchor.dart';
|
|
import 'package:flame/components/component.dart';
|
|
import 'package:flame/sprite.dart';
|
|
import 'package:vector_math/vector_math_64.dart';
|
|
|
|
final random = Random(DateTime.now().millisecondsSinceEpoch);
|
|
|
|
class Cat extends PositionComponent {
|
|
static const vmin = 0.1;
|
|
static const vmax = 150.0;
|
|
static const accLength = 20.0;
|
|
static const minDistance = 4.0;
|
|
|
|
final anchor = Anchor.bottomCenter;
|
|
final renderFlipX = true;
|
|
final axis = Vector2(-1.0, 0.0);
|
|
|
|
final catNumber = random.nextInt(7) + 1;
|
|
|
|
void Function() onBored;
|
|
|
|
bool shouldDestroy = false;
|
|
|
|
Vector2 target;
|
|
Vector2 position;
|
|
Vector2 velocity = Vector2.zero();
|
|
bool bored = false;
|
|
|
|
bool get isSitting => velocity.length < vmin;
|
|
double get width => isSitting ? 25.0 : 40.0;
|
|
double get height => isSitting ? 18.0 : 18.0;
|
|
double get x => position.x;
|
|
double get y => position.y;
|
|
double get angle => -velocity.angleToSigned(axis);
|
|
bool get renderFlipY => angle.abs() > 0.5 * pi;
|
|
|
|
Sprite sitting;
|
|
Sprite running;
|
|
|
|
Cat() {
|
|
sitting = Sprite('cat${catNumber}s.png');
|
|
running = Sprite('cat${catNumber}r.png');
|
|
}
|
|
|
|
void runTo(Vector2 target) {
|
|
bored = false;
|
|
this.target = target;
|
|
|
|
if (position == null) {
|
|
position = target;
|
|
}
|
|
|
|
velocity = (target - position).normalized() * vmax;
|
|
}
|
|
|
|
@override
|
|
void render(Canvas canvas) {
|
|
prepareCanvas(canvas);
|
|
|
|
if (isSitting) {
|
|
sitting.render(canvas, width: width, height: height);
|
|
} else {
|
|
running.render(canvas, width: width, height: height);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void update(double t) {
|
|
if ((position - target).length < minDistance) {
|
|
position = target;
|
|
velocity.setZero();
|
|
if (!bored) {
|
|
bored = true;
|
|
if (onBored != null) {
|
|
onBored();
|
|
}
|
|
}
|
|
} else {
|
|
position += velocity * t;
|
|
}
|
|
}
|
|
|
|
@override
|
|
bool destroy() => shouldDestroy;
|
|
|
|
@override
|
|
int priority() => 10000;
|
|
}
|