Vector2 extension

This commit is contained in:
Lukas Klingsbo
2020-09-20 17:30:58 +02:00
parent 99b2c91069
commit 50f8ffce3b
55 changed files with 275 additions and 786 deletions

View File

@ -3,7 +3,7 @@
## 1.0.0
- Move all box2d related code and examples to the flame_box2d repo
- Rename Animation to SpriteAnimation
- Unify all the possible tuples to Vector2
- Create extension of Vector2 and unify all tuples to use that class
## 0.26.0
- Improving Flame image auto cache

View File

@ -123,7 +123,7 @@ Note that it could be any component, however complex, inside your widgets tree.
```dart
import 'package:flame/sprite_animation.dart'; // imports the SpriteAnimation class
import 'package:flame/flame.dart'; // imports the Flame helper class
import 'package:flame/vector2f.dart'; // imports the Vector2 class
import 'package:flame/vector2_extension.dart'; // imports the Vector2 class
```
How do we do the magic then? Just add the following to your widget tree:

View File

@ -4,7 +4,7 @@ import 'package:flame/flame.dart';
import 'package:flame/sprite_animation.dart';
import 'package:flame/sprite.dart';
import 'package:flame/spritesheet.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/widgets/animation_widget.dart';
import 'package:flame/widgets/sprite_widget.dart';
import 'package:flutter/material.dart';
@ -50,7 +50,7 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
Vector2F _position = Vector2F(256.0, 256.0);
Vector2 _position = Vector2(256.0, 256.0);
@override
void initState() {
@ -61,7 +61,7 @@ class _MyHomePageState extends State<MyHomePage> {
void changePosition() async {
await Future.delayed(const Duration(seconds: 1));
setState(() {
_position = Vector2F(10 + _position.x, 10 + _position.y);
_position = Vector2(10 + _position.x, 10 + _position.y);
});
}

View File

@ -2,7 +2,7 @@ import 'package:flame/gestures.dart';
import 'package:flutter/gestures.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/sprite_animation.dart';
import 'package:flame/components/sprite_animation_component.dart';
import 'package:flutter/material.dart';
@ -11,7 +11,7 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Flame.images.loadAll(['creature.png', 'chopper.png']);
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
final game = MyGame(size);
runApp(game.widget);
}
@ -54,7 +54,7 @@ class MyGame extends BaseGame with TapDetector {
addAnimation(evt.globalPosition.dx, evt.globalPosition.dy);
}
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
const s = 100.0;

View File

@ -1,18 +1,18 @@
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/sprite_animation.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/components/sprite_animation_component.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
runApp(MyGame(size).widget);
}
class MyGame extends BaseGame {
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
_start();
}
@ -23,7 +23,7 @@ class MyGame extends BaseGame {
'chopper.json',
);
final animationComponent = SpriteAnimationComponent(200, 200, animation)
..setByPosition(size / 2 - Vector2F(100, 100));
..setByPosition(size / 2 - Vector2(100, 100));
add(animationComponent);
}

View File

@ -7,12 +7,12 @@ import 'package:flame/game.dart';
import 'package:flame/palette.dart';
import 'package:flame/text_config.dart';
import 'package:flame/gestures.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
final MyGame game = MyGame(size);
runApp(game.widget);
}
@ -23,7 +23,7 @@ AudioPool pool = AudioPool('laser.mp3');
class MyGame extends BaseGame with TapDetector {
static final black = BasicPalette.black.paint;
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
}

View File

@ -1,6 +1,6 @@
import 'package:flame/game.dart';
import 'package:flame/flame.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/components/sprite_component.dart';
import 'package:flame/components/mixins/resizable.dart';
import 'package:flame/text_config.dart';
@ -81,7 +81,7 @@ class MyGame extends BaseGame {
super.render(canvas);
if (debugMode()) {
fpsTextConfig.render(canvas, fps(120).toString(), Vector2F(0, 50));
fpsTextConfig.render(canvas, fps(120).toString(), Vector2(0, 50));
}
}
}

View File

@ -3,7 +3,7 @@ import 'package:flame/effects/move_effect.dart';
import 'package:flame/effects/scale_effect.dart';
import 'package:flame/effects/rotate_effect.dart';
import 'package:flame/gestures.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
@ -37,7 +37,7 @@ class MyGame extends BaseGame with TapDetector {
greenSquare.clearEffects();
final move = MoveEffect(
destination: Vector2F(dx, dy),
destination: Vector2(dx, dy),
speed: 250.0,
curve: Curves.linear,
isInfinite: false,
@ -45,7 +45,7 @@ class MyGame extends BaseGame with TapDetector {
);
final scale = ScaleEffect(
size: Vector2F(dx, dy),
size: Vector2(dx, dy),
speed: 250.0,
curve: Curves.linear,
isInfinite: false,

View File

@ -2,7 +2,7 @@ import 'package:flame/effects/move_effect.dart';
import 'package:flame/effects/scale_effect.dart';
import 'package:flame/effects/rotate_effect.dart';
import 'package:flame/gestures.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
@ -44,7 +44,7 @@ class MyGame extends BaseGame with TapDetector {
orangeSquare.clearEffects();
greenSquare.addEffect(MoveEffect(
destination: Vector2F(dx, dy),
destination: Vector2(dx, dy),
speed: 250.0,
curve: Curves.bounceInOut,
isInfinite: true,
@ -52,7 +52,7 @@ class MyGame extends BaseGame with TapDetector {
));
redSquare.addEffect(ScaleEffect(
size: Vector2F(dx, dy),
size: Vector2(dx, dy),
speed: 250.0,
curve: Curves.easeInCubic,
isInfinite: true,

View File

@ -3,7 +3,7 @@ import 'package:flame/effects/scale_effect.dart';
import 'package:flame/effects/rotate_effect.dart';
import 'package:flame/effects/sequence_effect.dart';
import 'package:flame/gestures.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
@ -34,7 +34,7 @@ class MyGame extends BaseGame with TapDetector {
greenSquare.clearEffects();
final move1 = MoveEffect(
destination: Vector2F(dx, dy),
destination: Vector2(dx, dy),
speed: 250.0,
curve: Curves.bounceInOut,
isInfinite: false,
@ -42,7 +42,7 @@ class MyGame extends BaseGame with TapDetector {
);
final move2 = MoveEffect(
destination: Vector2F(dx, dy + 150),
destination: Vector2(dx, dy + 150),
speed: 150.0,
curve: Curves.easeIn,
isInfinite: false,
@ -50,7 +50,7 @@ class MyGame extends BaseGame with TapDetector {
);
final scale = ScaleEffect(
size: Vector2F(dx, dy),
size: Vector2(dx, dy),
speed: 250.0,
curve: Curves.easeInCubic,
isInfinite: false,

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flame/effects/effects.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import './square.dart';
@ -17,7 +17,7 @@ class MyGame extends BaseGame with TapDetector {
@override
void onTapUp(details) {
square.addEffect(MoveEffect(
destination: Vector2F.fromOffset(details.localPosition),
destination: Vector2Factory.fromOffset(details.localPosition),
speed: 250.0,
curve: Curves.bounceInOut,
));

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flame/anchor.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/effects/effects.dart';
import './square.dart';
@ -24,7 +24,7 @@ class MyGame extends BaseGame with TapDetector {
grow = !grow;
square.addEffect(ScaleEffect(
size: Vector2F(s, s),
size: Vector2(s, s),
speed: 250.0,
curve: Curves.bounceInOut,
));

View File

@ -5,7 +5,7 @@ import 'package:flame/components/component.dart';
import 'package:flame/components/joystick/joystick_component.dart';
import 'package:flame/components/joystick/joystick_events.dart';
import 'package:flame/palette.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
class Player extends Component implements JoystickListener {
final _whitePaint = BasicPalette.white.paint;
@ -43,7 +43,7 @@ class Player extends Component implements JoystickListener {
}
@override
void resize(Vector2F size) {
void resize(Vector2 size) {
_rect = Rect.fromLTWH(
(size.x / 2) - 25,
(size.y / 2) - 25,

View File

@ -2,7 +2,7 @@ import 'package:flame/game.dart';
import 'package:flame/flame.dart';
import 'package:flame/nine_tile_box.dart';
import 'package:flame/sprite.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/material.dart';
@ -15,7 +15,7 @@ void main() async {
}
class MyGame extends Game {
Vector2F size;
Vector2 size;
NineTileBox nineTileBox;
MyGame(this.size) {

View File

@ -1,7 +1,7 @@
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/components/parallax_component.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/material.dart';
void main() async {
@ -22,8 +22,8 @@ class MyGame extends BaseGame {
final parallaxComponent = ParallaxComponent(
images,
baseSpeed: Vector2F(20, 0),
layerDelta: Vector2F(30, 0),
baseSpeed: Vector2(20, 0),
layerDelta: Vector2(30, 0),
);
add(parallaxComponent);

View File

@ -21,7 +21,7 @@ import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/time.dart' as flame_time;
import 'package:flame/particle.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/sprite.dart';
import 'package:flame/spritesheet.dart';
import 'package:flame/text_config.dart';
@ -48,14 +48,14 @@ class MyGame extends BaseGame {
/// Defines the lifespan of all the particles in these examples
final sceneDuration = const Duration(seconds: 1);
Vector2F cellSize;
Vector2F halfCellSize;
Vector2 cellSize;
Vector2 halfCellSize;
@override
bool recordFps() => true;
MyGame({
Vector2F screenSize,
Vector2 screenSize,
}) {
size = screenSize;
cellSize = size / gridSize;
@ -101,7 +101,7 @@ class MyGame extends BaseGame {
final double col = particles.length % gridSize;
final double row = (particles.length ~/ gridSize).toDouble();
final cellCenter =
(cellSize.clone()..multiply(Vector2F(col, row))) + (cellSize * .5);
(cellSize.clone()..multiply(Vector2(col, row))) + (cellSize * .5);
add(
// Bind all the particles to a [Component] update
@ -294,7 +294,7 @@ class MyGame extends BaseGame {
/// be reused across particles. See example below for more details.
Particle imageParticle() {
return ImageParticle(
size: Vector2F.all(24),
size: Vector2.all(24),
image: Flame.images.loadedFiles['zap.png'].loadedImage,
);
}
@ -395,7 +395,7 @@ class MyGame extends BaseGame {
Particle animationParticle() {
return SpriteAnimationParticle(
animation: getBoomAnimation(),
size: Vector2F(128, 128),
size: Vector2(128, 128),
);
}
@ -500,8 +500,8 @@ class MyGame extends BaseGame {
super.render(canvas);
if (debugMode()) {
fpsTextConfig.render(canvas, '${fps(120).toStringAsFixed(2)}fps',
Vector2F(0, size.y - 24));
fpsTextConfig.render(
canvas, '${fps(120).toStringAsFixed(2)}fps', Vector2(0, size.y - 24));
}
}
@ -549,7 +549,7 @@ class MyGame extends BaseGame {
}
Future<BaseGame> loadGame() async {
Vector2F gameSize;
Vector2 gameSize;
WidgetsFlutterBinding.ensureInitialized();
await Future.wait([

View File

@ -2,12 +2,12 @@ import 'package:flame/sprite_animation.dart';
import 'package:flame/components/sprite_animation_component.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
final game = MyGame(size);
runApp(game.widget);
}
@ -27,7 +27,7 @@ class MyGame extends BaseGame {
return ac;
}
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
final regular = buildAnimation();

View File

@ -1,17 +1,17 @@
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/components/position_component.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
runApp(MyGame(size).widget);
}
class Ball extends PositionComponent {
final Vector2F gameSize;
final Vector2 gameSize;
final paint = Paint()..color = const Color(0xFFFFFFFF);
bool forward = true;
@ -43,7 +43,7 @@ class Ball extends PositionComponent {
}
class MyGame extends BaseGame {
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
Flame.audio.disableLog();

View File

@ -4,12 +4,12 @@ import 'package:flame/flame.dart';
import 'package:flutter/material.dart';
import 'package:flame/game.dart';
import 'package:flame/sprite_batch.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/components/sprite_batch_component.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
final game = MyGame(size);
runApp(game.widget);
}
@ -17,7 +17,7 @@ void main() async {
class MyGame extends BaseGame {
SpriteBatch spriteBatch;
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
initData();

View File

@ -3,18 +3,18 @@ import 'dart:math';
import 'package:flame/components/sprite_component.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
final game = MyGame(size);
runApp(game.widget);
}
class MyGame extends BaseGame {
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
}

View File

@ -7,11 +7,11 @@ import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/palette.dart';
import 'package:flame/text_config.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/material.dart';
void main() async {
final Vector2F size = await Flame.util.initialDimensions();
final Vector2 size = await Flame.util.initialDimensions();
runApp(MyGame(size).widget);
}
@ -35,7 +35,7 @@ class MyTextBox extends TextBoxComponent {
}
class MyGame extends BaseGame {
MyGame(Vector2F screenSize) {
MyGame(Vector2 screenSize) {
size = screenSize;
add(TextComponent('Hello, Flame', config: regular)
..anchor = Anchor.topCenter

View File

@ -3,7 +3,7 @@ import 'package:flame/game.dart';
import 'package:flame/time.dart';
import 'package:flame/text_config.dart';
import 'package:flame/gestures.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flame/components/timer_component.dart';
void main() {
@ -42,7 +42,7 @@ class RenderedTimeComponent extends TimerComponent {
textConfig.render(
canvas,
'Elapsed time: ${timer.current}',
Vector2F(10, 150),
Vector2(10, 150),
);
}
}
@ -90,8 +90,8 @@ class MyGame extends Game with TapDetector {
textConfig.render(
canvas,
'Countdown: ${countdown.current}',
Vector2F(10, 100),
Vector2(10, 100),
);
textConfig.render(canvas, 'Elapsed time: $elapsedSecs', Vector2F(10, 150));
textConfig.render(canvas, 'Elapsed time: $elapsedSecs', Vector2(10, 150));
}
}

View File

@ -60,7 +60,7 @@ import 'dart:ui';
import 'package:flame/game.dart';
import 'package:flame/text_config.dart';
import 'package:flame/time.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
class MyGame extends Game {
final TextConfig textConfig = TextConfig(color: const Color(0xFFFFFFFF));
@ -81,7 +81,7 @@ class MyGame extends Game {
@override
void render(Canvas canvas) {
textConfig.render(canvas, "Countdown: ${countdown.current.toString()}",
Vector2F(10, 100));
Vector2(10, 100));
}
}
@ -95,7 +95,7 @@ import 'dart:ui';
import 'package:flame/game.dart';
import 'package:flame/text_config.dart';
import 'package:flame/time.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
class MyGame extends Game {
final TextConfig textConfig = TextConfig(color: const Color(0xFFFFFFFF));
@ -117,7 +117,7 @@ class MyGame extends Game {
@override
void render(Canvas canvas) {
textConfig.render(canvas, "Elapsed time: $elapsedSecs", Vector2F(10, 150));
textConfig.render(canvas, "Elapsed time: $elapsedSecs", Vector2(10, 150));
}
}

View File

@ -4,7 +4,7 @@ description: A new Flutter project.
version: 0.1.0
environment:
sdk: ">=2.0.0 <3.0.0"
sdk: ">=2.7.0 <3.0.0"
dependencies:
flame:

View File

@ -1,4 +1,4 @@
import 'vector2f.dart';
import 'vector2_extension.dart';
class Anchor {
static const Anchor topLeft = Anchor(0.0, 0.0);
@ -14,11 +14,11 @@ class Anchor {
final double x;
final double y;
Vector2F get relativePosition => Vector2F(x, y);
Vector2 get relativePosition => Vector2(x, y);
const Anchor(this.x, this.y);
Vector2F translate(Vector2F p, Vector2F size) {
Vector2 translate(Vector2 p, Vector2 size) {
return p - size.clone()
..multiply(relativePosition);
}

View File

@ -1,8 +1,7 @@
import 'dart:ui';
import 'package:flutter/painting.dart';
import '../vector2f.dart';
import 'package:vector_math/vector_math_64.dart';
/// This represents a Component for your game.
///
@ -24,7 +23,7 @@ abstract class Component {
///
/// It receives the new size.
/// You can use the [Resizable] mixin if you want an implementation of this hook that keeps track of the current size.
void resize(Vector2F size) {}
void resize(Vector2 size) {}
/// Whether this component has been loaded yet. If not loaded, [BaseGame] will not try to render it.
///

View File

@ -5,11 +5,10 @@ import 'package:flame/components/joystick/joystick_component.dart';
import 'package:flame/components/joystick/joystick_events.dart';
import 'package:flame/gestures.dart';
import 'package:flame/sprite.dart';
import 'package:flame/vector2f.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../../vector2f.dart';
import '../../vector2_extension.dart';
enum JoystickActionAlign { TOP_LEFT, BOTTOM_LEFT, TOP_RIGHT, BOTTOM_RIGHT }
@ -60,7 +59,7 @@ class JoystickAction {
_tileSize = _sizeBackgroundDirection / 2;
}
void initialize(Vector2F _screenSize, JoystickController joystickController) {
void initialize(Vector2 _screenSize, JoystickController joystickController) {
_joystickController = joystickController;
final double radius = size / 2;
double dx = 0, dy = 0;
@ -155,8 +154,8 @@ class JoystickAction {
// Distance between the center of joystick background & drag position
final centerPosition =
Vector2F.fromOffset(_rectBackgroundDirection.center);
final dragPosition = Vector2F.fromOffset(_dragPosition);
Vector2Factory.fromOffset(_rectBackgroundDirection.center);
final dragPosition = Vector2Factory.fromOffset(_dragPosition);
double dist = centerPosition.distanceTo(dragPosition);
// The maximum distance for the knob position to the edge of

View File

@ -7,7 +7,7 @@ import '../component.dart';
import '../mixins/has_game_ref.dart';
import '../../game/base_game.dart';
import '../../gestures.dart';
import '../../vector2f.dart';
import '../../vector2_extension.dart';
mixin JoystickListener {
void joystickChangeDirectional(JoystickDirectionalEvent event);
@ -70,7 +70,7 @@ class JoystickComponent extends JoystickController {
}
@override
void resize(Vector2F size) {
void resize(Vector2 size) {
directional?.initialize(size, this);
actions?.forEach((action) => action.initialize(size, this));
super.resize(size);

View File

@ -6,7 +6,7 @@ import 'package:flame/gestures.dart';
import 'package:flame/sprite.dart';
import 'package:flutter/material.dart';
import '../../vector2f.dart';
import '../../vector2_extension.dart';
class JoystickDirectional {
final double size;
@ -33,7 +33,7 @@ class JoystickDirectional {
JoystickController _joystickController;
Vector2F _screenSize;
Vector2 _screenSize;
DragEvent _currentDragEvent;
@ -65,7 +65,7 @@ class JoystickDirectional {
_tileSize = size / 2;
}
void initialize(Vector2F _screenSize, JoystickController joystickController) {
void initialize(Vector2 _screenSize, JoystickController joystickController) {
this._screenSize = _screenSize;
_joystickController = joystickController;
final Offset osBackground =
@ -117,8 +117,8 @@ class JoystickDirectional {
final double degrees = _radAngle * 180 / pi;
// Distance between the center of joystick background & drag position
final centerPosition = Vector2F.fromOffset(_backgroundRect.center);
final dragPosition = Vector2F.fromOffset(_dragPosition);
final centerPosition = Vector2Factory.fromOffset(_backgroundRect.center);
final dragPosition = Vector2Factory.fromOffset(_dragPosition);
double dist = centerPosition.distanceTo(dragPosition);
// The maximum distance for the knob position the edge of

View File

@ -1,4 +1,4 @@
import '../../vector2f.dart';
import '../../vector2_extension.dart';
/// Useful mixin to add to your components if you want to hold a reference to the current screen size.
///
@ -6,10 +6,10 @@ import '../../vector2f.dart';
/// Also, it updates its [children], if any.
class Resizable {
/// This is the current updated screen size.
Vector2F size;
Vector2 size;
/// Implementation provided by this mixin to the resize hook.
void resize(Vector2F size) {
void resize(Vector2 size) {
this.size = size;
resizableChildren().where((e) => e != null).forEach((e) => e.resize(size));
}

View File

@ -1,9 +1,10 @@
import 'dart:async';
import 'dart:ui';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:vector_math/vector_math_64.dart';
import '../flame.dart';
import 'position_component.dart';
@ -38,10 +39,10 @@ class ParallaxLayer {
Future<Image> future;
Image _image;
Vector2F _screenSize;
Vector2 _screenSize;
Rect _paintArea;
Vector2F _scroll;
Vector2F _imageSize;
Vector2 _scroll;
Vector2 _imageSize;
double _scale = 1.0;
ParallaxLayer(this.parallaxImage) {
@ -50,9 +51,9 @@ class ParallaxLayer {
bool loaded() => _image != null;
Vector2F currentOffset() => _scroll;
Vector2 currentOffset() => _scroll;
void resize(Vector2F size) {
void resize(Vector2 size) {
if (!loaded()) {
_screenSize = size;
return;
@ -73,7 +74,7 @@ class ParallaxLayer {
// The image size so that it fulfills the LayerFill parameter
_imageSize =
Vector2F(_image.width.toDouble(), _image.height.toDouble()) / _scale;
Vector2(_image.width.toDouble(), _image.height.toDouble()) / _scale;
// Number of images that can fit on the canvas plus one
// to have something to scroll to without leaving canvas empty
@ -88,14 +89,14 @@ class ParallaxLayer {
final alignment = parallaxImage.alignment;
final marginX = alignment.x == 0 ? overflowX / 2 : alignment.x;
final marginY = alignment.y == 0 ? overflowY / 2 : alignment.y;
_scroll ??= Vector2F(marginX, marginY);
_scroll ??= Vector2(marginX, marginY);
// Size of the area to paint the images on
final paintSize = Vector2F(countX, countY)..multiply(_imageSize);
_paintArea = paintSize.toRect();
final paintSize = Vector2(countX, countY)..multiply(_imageSize);
_paintArea = paintSize.toOrigoRect();
}
void update(Vector2F delta) {
void update(Vector2 delta) {
if (!loaded()) {
return;
}
@ -104,13 +105,13 @@ class ParallaxLayer {
_scroll += delta..divide(_imageSize);
switch (parallaxImage.repeat) {
case ImageRepeat.repeat:
_scroll = Vector2F(_scroll.x % 1, _scroll.y % 1);
_scroll = Vector2(_scroll.x % 1, _scroll.y % 1);
break;
case ImageRepeat.repeatX:
_scroll = Vector2F(_scroll.x % 1, _scroll.y);
_scroll = Vector2(_scroll.x % 1, _scroll.y);
break;
case ImageRepeat.repeatY:
_scroll = Vector2F(_scroll.x, _scroll.y % 1);
_scroll = Vector2(_scroll.x, _scroll.y % 1);
break;
case ImageRepeat.noRepeat:
break;
@ -154,8 +155,8 @@ enum LayerFill { height, width, none }
/// A full parallax, several layers of images drawn out on the screen and each
/// layer moves with different speeds to give an effect of depth.
class ParallaxComponent extends PositionComponent {
Vector2F baseSpeed;
Vector2F layerDelta;
Vector2 baseSpeed;
Vector2 layerDelta;
List<ParallaxLayer> _layers;
bool _loaded = false;
@ -164,21 +165,21 @@ class ParallaxComponent extends PositionComponent {
this.baseSpeed,
this.layerDelta,
}) {
baseSpeed ??= Vector2F.zero();
layerDelta ??= Vector2F.zero();
baseSpeed ??= Vector2.zero();
layerDelta ??= Vector2.zero();
_load(images);
}
/// The base offset of the parallax, can be used in an outer update loop
/// if you want to transition the parallax to a certain position.
Vector2F currentOffset() => _layers[0].currentOffset();
Vector2 currentOffset() => _layers[0].currentOffset();
@override
bool loaded() => _loaded;
@mustCallSuper
@override
void resize(Vector2F size) {
void resize(Vector2 size) {
super.resize(size);
_layers.forEach((layer) => layer.resize(size));
}

View File

@ -9,7 +9,7 @@ import '../anchor.dart';
import '../effects/effects.dart';
import '../game.dart';
import '../text_config.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
import 'component.dart';
/// A [Component] implementation that represents a component that has a
@ -72,14 +72,14 @@ abstract class PositionComponent extends Component {
TextConfig get debugTextConfig => TextConfig(color: debugColor, fontSize: 12);
Vector2F toPosition() => Vector2F(x, y);
void setByPosition(Vector2F position) {
Vector2 toPosition() => Vector2(x, y);
void setByPosition(Vector2 position) {
x = position.x;
y = position.y;
}
Vector2F toSize() => Vector2F(width, height);
void setBySize(Vector2F size) {
Vector2 toSize() => Vector2(width, height);
void setBySize(Vector2 size) {
width = size.x;
height = size.y;
}
@ -120,7 +120,7 @@ abstract class PositionComponent extends Component {
debugTextConfig.render(
canvas,
'x: ${x.toStringAsFixed(2)} y:${y.toStringAsFixed(2)}',
Vector2F(-50, -15));
Vector2(-50, -15));
final Rect rect = toRect();
final dx = rect.right;
@ -128,7 +128,7 @@ abstract class PositionComponent extends Component {
debugTextConfig.render(
canvas,
'x:${dx.toStringAsFixed(2)} y:${dy.toStringAsFixed(2)}',
Vector2F(width - 50, height));
Vector2(width - 50, height));
}
void _prepareCanvas(Canvas canvas) {
@ -193,7 +193,7 @@ abstract class PositionComponent extends Component {
@mustCallSuper
@override
void resize(Vector2F size) {
void resize(Vector2 size) {
super.resize(size);
_children.forEach((child) => child.resize(size));
}

View File

@ -6,7 +6,7 @@ import 'package:flutter/widgets.dart' as widgets;
import '../palette.dart';
import '../text_config.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
import 'mixins/resizable.dart';
import 'position_component.dart';
@ -28,7 +28,7 @@ class TextBoxComponent extends PositionComponent with Resizable {
static final Paint _imagePaint = BasicPalette.white.paint
..filterQuality = FilterQuality.high;
Vector2F p = Vector2F.zero();
Vector2 p = Vector2.zero();
String _text;
TextConfig _config;

View File

@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../components/position_component.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
export './move_effect.dart';
export './rotate_effect.dart';
@ -31,9 +31,9 @@ abstract class PositionComponentEffect {
int curveDirection = 1;
/// Used to be able to determine the end state of a sequence of effects
Vector2F endPosition;
Vector2 endPosition;
double endAngle;
Vector2F endSize;
Vector2 endSize;
/// If the effect is alternating the travel time is double the normal
/// travel time

View File

@ -3,14 +3,14 @@ import 'package:meta/meta.dart';
import 'dart:math';
import '../vector2f.dart';
import '../vector2_extension.dart';
import './effects.dart';
double _direction(double p, double d) => (p - d).sign;
double _distance(double a, double b) => (a - b).abs();
class MoveEffect extends PositionComponentEffect {
Vector2F destination;
Vector2 destination;
double speed;
Curve curve;

View File

@ -3,20 +3,20 @@ import 'package:meta/meta.dart';
import 'dart:math';
import '../vector2f.dart';
import '../vector2_extension.dart';
import './effects.dart';
double _direction(double p, double d) => (p - d).sign;
double _size(double a, double b) => (a - b).abs();
class ScaleEffect extends PositionComponentEffect {
Vector2F size;
Vector2 size;
double speed;
Curve curve;
Vector2F _original;
Vector2F _diff;
final Vector2F _dir = Vector2F.zero();
Vector2 _original;
Vector2 _diff;
final Vector2 _dir = Vector2.zero();
ScaleEffect({
@required this.size,
@ -35,7 +35,7 @@ class ScaleEffect extends PositionComponentEffect {
}
_original = component.toSize();
_diff = Vector2F(
_diff = Vector2(
_size(_original.x, size.x),
_size(_original.y, size.y),
);

View File

@ -11,7 +11,7 @@ import '../components/component.dart';
import '../components/mixins/has_game_ref.dart';
import '../components/mixins/tapable.dart';
import '../components/position_component.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
import 'game.dart';
/// This is a more complete and opinionated implementation of Game.
@ -31,10 +31,10 @@ class BaseGame extends Game with FPSCounter {
final List<Component> _removeLater = [];
/// Current screen size, updated every resize via the [resize] method hook
Vector2F size;
Vector2 size;
/// Camera position; every non-HUD component is translated so that the camera position is the top-left corner of the screen.
Vector2F camera = Vector2F.zero();
Vector2 camera = Vector2.zero();
/// This method is called for every component added, both via [add] and [addLater] methods.
///
@ -138,7 +138,7 @@ class BaseGame extends Game with FPSCounter {
/// You can override it further to add more custom behaviour, but you should seriously consider calling the super implementation as well.
@override
@mustCallSuper
void resize(Vector2F size) {
void resize(Vector2 size) {
this.size = size;
components.forEach((c) => c.resize(size));
}

View File

@ -1,7 +1,7 @@
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart' hide WidgetBuilder;
import '../vector2f.dart';
import '../vector2_extension.dart';
import 'game_render_box.dart';
import 'game.dart';
@ -13,7 +13,7 @@ import 'game.dart';
/// You can bind Gesture Recognizers immediately around this to add controls to your widgets, with easy coordinate conversions.
class EmbeddedGameWidget extends LeafRenderObjectWidget {
final Game game;
final Vector2F size;
final Vector2 size;
EmbeddedGameWidget(this.game, {this.size});

View File

@ -9,7 +9,7 @@ import 'package:flutter/services.dart';
import '../keyboard.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
import 'widget_builder.dart';
/// Represents a generic game.
@ -36,7 +36,7 @@ abstract class Game {
/// This is the resize hook; every time the game widget is resized, this hook is called.
///
/// The default implementation does nothing; override to use the hook.
void resize(Vector2F size) {}
void resize(Vector2 size) {}
/// This is the lifecycle state change hook; every time the game is resumed, paused or suspended, this is called.
///

View File

@ -5,7 +5,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart' hide WidgetBuilder;
import '../vector2f.dart';
import '../vector2_extension.dart';
import 'game_loop.dart';
import 'game.dart';
@ -24,7 +24,7 @@ class GameRenderBox extends RenderBox with WidgetsBindingObserver {
@override
void performResize() {
super.performResize();
game.resize(Vector2F.fromSize(constraints.biggest));
game.resize(Vector2Factory.fromSize(constraints.biggest));
}
@override

View File

@ -4,11 +4,11 @@ import 'package:flutter/foundation.dart';
import '../sprite_animation.dart';
import '../particle.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
class SpriteAnimationParticle extends Particle {
final SpriteAnimation animation;
final Vector2F size;
final Vector2 size;
final Paint overridePaint;
final bool alignAnimationTime;
@ -36,7 +36,7 @@ class SpriteAnimationParticle extends Particle {
void render(Canvas canvas) {
animation.getSprite().renderCentered(
canvas,
Vector2F.zero(),
Vector2.zero(),
overridePaint: overridePaint,
size: size,
);

View File

@ -4,11 +4,11 @@ import 'package:flutter/foundation.dart';
import '../particle.dart';
import '../components/component.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
class ComponentParticle extends Particle {
final Component component;
final Vector2F size;
final Vector2 size;
final Paint overridePaint;
ComponentParticle({

View File

@ -3,7 +3,7 @@ import 'dart:ui';
import 'package:flutter/foundation.dart';
import '../particle.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
/// A [Particle] which renders given [Image] on a [Canvas]
/// image is centered. If any other behavior is needed, consider
@ -17,7 +17,7 @@ class ImageParticle extends Particle {
ImageParticle({
@required this.image,
Vector2F size,
Vector2 size,
double lifespan,
}) : super(lifespan: lifespan) {
final srcWidth = image.width.toDouble();

View File

@ -4,11 +4,11 @@ import 'package:flutter/foundation.dart';
import '../particle.dart';
import '../sprite.dart';
import '../vector2f.dart';
import '../vector2_extension.dart';
class SpriteParticle extends Particle {
final Sprite sprite;
final Vector2F size;
final Vector2 size;
final Paint overridePaint;
SpriteParticle({
@ -24,7 +24,7 @@ class SpriteParticle extends Particle {
void render(Canvas canvas) {
sprite.renderCentered(
canvas,
Vector2F.zero(),
Vector2.zero(),
overridePaint: overridePaint,
size: size,
);

View File

@ -4,7 +4,7 @@ import 'dart:async';
import 'flame.dart';
import 'palette.dart';
import 'vector2f.dart';
import 'vector2_extension.dart';
class Sprite {
Paint paint = BasicPalette.white.paint;
@ -63,15 +63,15 @@ class Sprite {
double get _imageHeight => image.height.toDouble();
Vector2F get originalSize {
Vector2 get originalSize {
if (!loaded()) {
return null;
}
return Vector2F(_imageWidth, _imageHeight);
return Vector2(_imageWidth, _imageHeight);
}
Vector2F get size {
return Vector2F(src.width, src.height);
Vector2 get size {
return Vector2(src.width, src.height);
}
/// Renders this Sprite on the position [p], scaled by the [scale] factor provided.
@ -79,7 +79,7 @@ class Sprite {
/// It renders with src size multiplied by [scale] in both directions.
/// Anchor is on top left as default.
/// If not loaded, does nothing.
void renderScaled(Canvas canvas, Vector2F p,
void renderScaled(Canvas canvas, Vector2 p,
{double scale = 1.0, Paint overridePaint}) {
if (!loaded()) {
return;
@ -87,14 +87,13 @@ class Sprite {
renderPosition(canvas, p, size: size * scale, overridePaint: overridePaint);
}
void renderPosition(Canvas canvas, Vector2F p,
{Vector2F size, Paint overridePaint}) {
void renderPosition(Canvas canvas, Vector2 p,
{Vector2 size, Paint overridePaint}) {
if (!loaded()) {
return;
}
size ??= this.size;
renderRect(canvas, Vector2F.rectFrom(p, size),
overridePaint: overridePaint);
renderRect(canvas, p.toRect(size), overridePaint: overridePaint);
}
void render(Canvas canvas,
@ -112,8 +111,8 @@ class Sprite {
///
/// If [size] is not provided, the original size of the src image is used.
/// If the asset is not yet loaded, it does nothing.
void renderCentered(Canvas canvas, Vector2F p,
{Vector2F size, Paint overridePaint}) {
void renderCentered(Canvas canvas, Vector2 p,
{Vector2 size, Paint overridePaint}) {
if (!loaded()) {
return;
}

View File

@ -3,7 +3,7 @@ import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'flame.dart';
import 'vector2f.dart';
import 'vector2_extension.dart';
/// sprite atlas with an image and a set of rects and transforms
class SpriteBatch {
@ -28,7 +28,7 @@ class SpriteBatch {
int get height => atlas.height;
Vector2F get size => Vector2F(width.toDouble(), height.toDouble());
Vector2 get size => Vector2(width.toDouble(), height.toDouble());
void addTransform({
@required Rect rect,

View File

@ -4,7 +4,7 @@ import 'package:flutter/material.dart' as material;
import 'anchor.dart';
import 'memory_cache.dart';
import 'vector2f.dart';
import 'vector2_extension.dart';
/// A Text Config contains all typographical information required to render texts; i.e., font size and color, family, etc.
///
@ -76,11 +76,11 @@ class TextConfig {
///
/// const TextConfig config = TextConfig(fontSize: 48.0, fontFamily: 'Awesome Font');
/// config.render(c, Offset(size.width - 10, size.height - 10, anchor: Anchor.bottomRight);
void render(Canvas canvas, String text, Vector2F p,
void render(Canvas canvas, String text, Vector2 p,
{Anchor anchor = Anchor.topLeft}) {
final material.TextPainter tp = toTextPainter(text);
final Vector2F translatedPosition =
anchor.translate(p, Vector2F.fromSize(tp.size));
final Vector2 translatedPosition =
anchor.translate(p, Vector2Factory.fromSize(tp.size));
tp.paint(canvas, translatedPosition.toOffset());
}

View File

@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:ui';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
@ -97,21 +97,22 @@ class Util {
///
/// A best practice would be to implement there resize hooks on your game and components and don't use this at all.
/// Make sure your components are able to render and update themselves for any possible screen size.
Future<Vector2F> initialDimensions() async {
Future<Vector2> initialDimensions() async {
// https://github.com/flutter/flutter/issues/5259
// "In release mode we start off at 0x0 but we don't in debug mode"
return await Future<Vector2F>(() {
return await Future<Vector2>(() {
if (window.physicalSize.isEmpty) {
final completer = Completer<Vector2F>();
final completer = Completer<Vector2>();
window.onMetricsChanged = () {
if (!window.physicalSize.isEmpty && !completer.isCompleted) {
completer.complete(Vector2F.fromSize(
completer.complete(Vector2Factory.fromSize(
window.physicalSize / window.devicePixelRatio));
}
};
return completer.future;
}
return Vector2F.fromSize(window.physicalSize / window.devicePixelRatio);
return Vector2Factory.fromSize(
window.physicalSize / window.devicePixelRatio);
});
}
@ -148,7 +149,7 @@ class Util {
///
/// Some render methods don't allow to pass a offset.
/// This method translate the canvas, draw what you want, and then translate back.
void drawWhere(Canvas c, Vector2F p, void Function(Canvas) fn) {
void drawWhere(Canvas c, Vector2 p, void Function(Canvas) fn) {
c.translate(p.x, p.y);
fn(c);
c.translate(-p.x, -p.y);

View File

@ -0,0 +1,68 @@
export 'package:vector_math/vector_math_64.dart' show Vector2;
import 'dart:math';
import 'dart:ui';
import 'package:vector_math/vector_math_64.dart';
extension Vector2Extension on Vector2 {
/// Creates an [Offset] from the [Vector2]
Offset toOffset() => Offset(x, y);
/// Creates a [Size] from the [Vector2]
Size toSize() => Size(x, y);
/// Creates a [Point] from the [Vector2]
Point toPoint() => Point(x, y);
/// Creates a [Rect] starting from [x, y] and going the [Vector2]
Rect toRect(Vector2 to) => Rect.fromLTWH(x, y, to.x, to.y);
/// Creates a [Rect] starting in origo and going the [Vector2]
Rect toOrigoRect() => Rect.fromLTWH(0, 0, x, y);
/// Linearly interpolate towards another Vector2
void lerp(Vector2 to, double t) {
setFrom(this + (to - this) * t);
}
/// Rotates the [Vector2] with [angle] in radians
void rotate(double angle) {
setValues(
x * cos(angle) - y * sin(angle),
x * sin(angle) + y * cos(angle),
);
}
/// Changes the [length] of the vector to the length provided, without changing direction.
///
/// If you try to scale the zero (empty) vector, it will remain unchanged, and no error will be thrown.
void scaleTo(double newLength) {
final l = length;
if (l != 0) {
scale(newLength.abs() / l);
}
}
}
// Until [extension] will allow static methods we need to keep these functions
// in a utility class
class Vector2Factory {
/// Creates a [Vector2] using an [Offset]
static Vector2 fromOffset(Offset offset) => Vector2(offset.dx, offset.dy);
/// Creates a [Vector2] using an [Size]
static Vector2 fromSize(Size size) => Vector2(size.width, size.height);
/// Creates a [Vector2] using a [Point]
static Vector2 fromPoint(Point point) => Vector2(point.x, point.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);
final double maxx = pts.map((e) => e.x).reduce(max);
final double miny = pts.map((e) => e.y).reduce(min);
final double maxy = pts.map((e) => e.y).reduce(max);
return Rect.fromPoints(Offset(minx, miny), Offset(maxx, maxy));
}
}

View File

@ -1,578 +0,0 @@
library flame.vector_math;
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart';
class Vector2F implements Vector2 {
final Vector2 _delegate;
/// Construct a new Vector2F with the specified values.
Vector2F(double x, double y) : _delegate = Vector2(x, y);
/// Initialized with values from [array] starting at [offset].
Vector2F.array(List<double> array, [int offset = 0])
: _delegate = Vector2.array(array, offset);
/// Zero vector.
Vector2F.zero() : _delegate = Vector2.zero();
/// Splat [value] into all lanes of the vector. Vector2F.all(double value) : _delegate = Vector2F.all(value);
Vector2F.all(double value) : _delegate = Vector2.all(value);
/// Copy of [other].
Vector2F.copy(Vector2 other) : _delegate = Vector2.copy(other);
/// Constructs Vector2F with a given [Float64List] as [storage].
Vector2F.fromFloat64List(Float64List v2storage)
: _delegate = Vector2.fromFloat64List(v2storage);
/// Constructs Vector2F with a [storage] that views given [buffer] starting at
/// [offset]. [offset] has to be multiple of [Float64List.bytesPerElement].
Vector2F.fromBuffer(ByteBuffer buffer, int offset)
: _delegate = Vector2.fromBuffer(buffer, offset);
/// Generate random vector in the range (0, 0) to (1, 1). You can
/// optionally pass your own random number generator.
Vector2F.random([Random rng]) : _delegate = Vector2.random(rng);
/// Creates a [Vector2F] using an [Offset]
Vector2F.fromOffset(Offset offset)
: _delegate = Vector2(offset.dx, offset.dy);
/// Creates a [Vector2F] using an [Size]
Vector2F.fromSize(Size size) : _delegate = Vector2(size.width, size.height);
/// Creates a [Vector2F] using a [Point]
Vector2F fromPoint(Point point) => Vector2F(point.x, point.y);
/// ==========================================================================
/// The following block are all the functions that [Vector2F] has but
/// [Vector2] doesn't have.
/// ==========================================================================
/// Creates an [Offset] from the [Vector2F]
Offset toOffset() => Offset(_delegate.x, _delegate.y);
/// Creates an [Size] from the [Vector2F]
Size toSize() => Size(_delegate.x, _delegate.y);
/// Creates a [Point] from the [Vector2F]
Point toPoint() => Point(_delegate.x, _delegate.y);
/// Creates a [Rect] starting in origo and going the [Vector2F]
Rect toRect() => Rect.fromLTWH(0, 0, _delegate.x, _delegate.y);
/// Creates a [Rect] from two [Vector2]
static Rect rectFrom(Vector2F topLeft, Vector2F size) {
return Rect.fromLTWH(topLeft.x, topLeft.y, size.x, size.y);
}
/// Creates bounds in from of a [Rect] from a list of [Vector2]
static Rect bounds(List<Vector2> pts) {
final double minx = pts.map((e) => e.x).reduce(min);
final double maxx = pts.map((e) => e.x).reduce(max);
final double miny = pts.map((e) => e.y).reduce(min);
final double maxy = pts.map((e) => e.y).reduce(max);
return Rect.fromPoints(Offset(minx, miny), Offset(maxx, maxy));
}
/// Linearly interpolate towards another Vector2
void lerp(Vector2 to, double t) {
_delegate.setFrom(_delegate + (to - _delegate) * t);
}
/// Rotates the [Vector2F] with [angle] in radians
void rotate(double angle) {
_delegate.setValues(
_delegate.x * cos(angle) - _delegate.y * sin(angle),
_delegate.x * sin(angle) + _delegate.y * cos(angle),
);
}
/// Changes the [length] of the vector to the length provided, without changing direction.
///
/// If you try to scale the zero (empty) vector, it will remain unchanged, and no error will be thrown.
void scaleTo(double newLength) {
final l = _delegate.length;
if (l != 0) {
_delegate.setFrom(_delegate * (newLength.abs() / l));
}
}
/// ==========================================================================
/// The following are all the Vector2 overridden functions that we have to
/// delegate to [_delegate], since the constructor factories makes the
/// [Vector2] class impossible to extend.
/// ==========================================================================
@override
double get g => _delegate.g;
@override
Vector2F get gr => _delegate.gr;
@override
double get length => _delegate.length;
@override
double get r => _delegate.r;
@override
Vector2F get rg => _delegate.rg;
@override
double get s => _delegate.s;
@override
Vector2F get st => _delegate.st;
@override
double get t => _delegate.t;
@override
Vector2F get ts => _delegate.ts;
@override
double get x => _delegate.x;
@override
Vector2F get xy => _delegate.xy;
@override
double get y => _delegate.y;
@override
Vector2F get yx => _delegate.yx;
@override
Vector2F operator *(double scale) => _delegate * scale;
@override
Vector2F operator +(Vector2 other) => _delegate + other;
@override
Vector2F operator -(Vector2 other) => _delegate - other;
@override
Vector2F operator -() => -_delegate;
@override
Vector2F operator /(double scale) => _delegate / scale;
@override
double operator [](int i) => _delegate[i];
@override
void operator []=(int i, double v) => _delegate[i] = v;
@override
void absolute() => _delegate.absolute();
@override
double absoluteError(Vector2 correct) => _delegate.absoluteError(correct);
@override
void add(Vector2 arg) => _delegate.add(arg);
@override
void addScaled(Vector2 arg, double factor) =>
_delegate.addScaled(arg, factor);
@override
double angleTo(Vector2 other) => _delegate.angleTo(other);
@override
double angleToSigned(Vector2 other) => _delegate.angleToSigned(other);
@override
void ceil() => _delegate.ceil();
@override
void clamp(Vector2 min, Vector2 max) => _delegate.clamp(min, max);
@override
void clampScalar(double min, double max) => _delegate.clampScalar(min, max);
@override
Vector2F clone() => _delegate.clone();
@override
void copyFromArray(List<double> array, [int offset = 0]) =>
_delegate.copyFromArray(array, offset);
@override
Vector2F copyInto(Vector2 arg) => _delegate.copyInto(arg);
@override
void copyIntoArray(List<double> array, [int offset = 0]) =>
_delegate.copyIntoArray(array, offset);
@override
double cross(Vector2 other) => _delegate.cross(other);
@override
double distanceTo(Vector2 arg) => _delegate.distanceTo(arg);
@override
double distanceToSquared(Vector2 arg) => _delegate.distanceToSquared(arg);
@override
void divide(Vector2 arg) => _delegate.divide(arg);
@override
double dot(Vector2 other) => _delegate.dot(other);
@override
void floor() => _delegate.floor();
@override
Vector2F get gg => _delegate.gg;
@override
Vector3 get ggg => _delegate.ggg;
@override
Vector4 get gggg => _delegate.gggg;
@override
Vector4 get gggr => _delegate.gggr;
@override
Vector3 get ggr => _delegate.ggr;
@override
Vector4 get ggrg => _delegate.ggrg;
@override
Vector4 get ggrr => _delegate.ggrr;
@override
Vector3 get grg => _delegate.grg;
@override
Vector4 get grgg => _delegate.grgg;
@override
Vector4 get grgr => _delegate.grgr;
@override
Vector3 get grr => _delegate.grr;
@override
Vector4 get grrg => _delegate.grrg;
@override
Vector4 get grrr => _delegate.grrr;
@override
bool get isInfinite => _delegate.isInfinite;
@override
bool get isNaN => _delegate.isNaN;
@override
double get length2 => _delegate.length2;
@override
void multiply(Vector2 arg) => _delegate.multiply(arg);
@override
void negate() => _delegate.negate();
@override
double normalize() => _delegate.normalize();
@override
Vector2F normalizeInto(Vector2 out) => _delegate.normalizeInto(out);
/// DEPRECATED: Use [normalize].
@override
@deprecated
double normalizeLength() => _delegate.normalize();
@override
Vector2F normalized() => _delegate.normalized();
@override
void postmultiply(Matrix2 arg) => _delegate.postmultiply(arg);
@override
void reflect(Vector2 normal) => _delegate.reflect(normal);
@override
Vector2F reflected(Vector2 normal) => _delegate.reflected(normal);
@override
double relativeError(Vector2 correct) => _delegate.relativeError(correct);
@override
Vector3 get rgg => _delegate.rgg;
@override
Vector4 get rggg => _delegate.rggg;
@override
Vector4 get rggr => _delegate.rggr;
@override
Vector3 get rgr => _delegate.rgr;
@override
Vector4 get rgrg => _delegate.rgrg;
@override
Vector4 get rgrr => _delegate.rgrr;
@override
void round() => _delegate.round();
@override
void roundToZero() => _delegate.roundToZero();
@override
Vector2F get rr => _delegate.rr;
@override
Vector3 get rrg => _delegate.rrg;
@override
Vector4 get rrgg => _delegate.rrgg;
@override
Vector4 get rrgr => _delegate.rrgr;
@override
Vector3 get rrr => _delegate.rrr;
@override
Vector4 get rrrg => _delegate.rrrg;
@override
Vector4 get rrrr => _delegate.rrrr;
@override
void scale(double arg) => _delegate.scale(arg);
@override
Vector2F scaleOrthogonalInto(double scale, Vector2 out) =>
_delegate.scaleOrthogonalInto(scale, out);
@override
Vector2F scaled(double arg) => _delegate.scaled(arg);
@override
void setFrom(Vector2 other) => _delegate.setFrom(other);
@override
void setValues(double x, double y) => _delegate.setValues(x, y);
@override
void setZero() => _delegate.setZero();
@override
void splat(double arg) => _delegate.splat(arg);
@override
Vector2F get ss => _delegate.ss;
@override
Vector3 get sss => _delegate.sss;
@override
Vector4 get ssss => _delegate.ssss;
@override
Vector4 get ssst => _delegate.ssst;
@override
Vector3 get sst => _delegate.sst;
@override
Vector4 get ssts => _delegate.ssts;
@override
Vector4 get sstt => _delegate.sstt;
@override
Float64List get storage => _delegate.storage;
@override
Vector3 get sts => _delegate.sts;
@override
Vector4 get stss => _delegate.stss;
@override
Vector4 get stst => _delegate.stst;
@override
Vector3 get stt => _delegate.stt;
@override
Vector4 get stts => _delegate.stts;
@override
Vector4 get sttt => _delegate.sttt;
@override
void sub(Vector2 arg) => _delegate.sub(arg);
@override
Vector3 get tss => _delegate.tss;
@override
Vector4 get tsss => _delegate.tsss;
@override
Vector4 get tsst => _delegate.tsst;
@override
Vector3 get tst => _delegate.tst;
@override
Vector4 get tsts => _delegate.tsts;
@override
Vector4 get tstt => _delegate.tstt;
@override
Vector2F get tt => _delegate.tt;
@override
Vector3 get tts => _delegate.tts;
@override
Vector4 get ttss => _delegate.ttss;
@override
Vector4 get ttst => _delegate.ttst;
@override
Vector3 get ttt => _delegate.ttt;
@override
Vector4 get ttts => _delegate.ttts;
@override
Vector4 get tttt => _delegate.tttt;
@override
Vector2F get xx => _delegate.xx;
@override
Vector3 get xxx => _delegate.xxx;
@override
Vector4 get xxxx => _delegate.xxxx;
@override
Vector4 get xxxy => _delegate.xxxy;
@override
Vector3 get xxy => _delegate.xxy;
@override
Vector4 get xxyx => _delegate.xxyx;
@override
Vector4 get xxyy => _delegate.xxyy;
@override
Vector3 get xyx => _delegate.xyx;
@override
Vector4 get xyxx => _delegate.xyxx;
@override
Vector4 get xyxy => _delegate.xyxy;
@override
Vector3 get xyy => _delegate.xyy;
@override
Vector4 get xyyx => _delegate.xyyx;
@override
Vector4 get xyyy => _delegate.xyyy;
@override
Vector3 get yxx => _delegate.yxx;
@override
Vector4 get yxxx => _delegate.yxxx;
@override
Vector4 get yxxy => _delegate.yxxy;
@override
Vector3 get yxy => _delegate.yxy;
@override
Vector4 get yxyx => _delegate.yxyx;
@override
Vector4 get yxyy => _delegate.yxyy;
@override
Vector2F get yy => _delegate.yy;
@override
Vector3 get yyx => _delegate.yyx;
@override
Vector4 get yyxx => _delegate.yyxx;
@override
Vector4 get yyxy => _delegate.yyxy;
@override
Vector3 get yyy => _delegate.yyy;
@override
Vector4 get yyyx => _delegate.yyyx;
@override
Vector4 get yyyy => _delegate.yyyy;
@override
set g(double arg) => _delegate.g = arg;
@override
set gr(Vector2 arg) => _delegate.gr = arg;
@override
set length(double value) => _delegate.length = value;
@override
set r(double arg) => _delegate.r = arg;
@override
set rg(Vector2 arg) => _delegate.rg = arg;
@override
set s(double arg) => _delegate.s = arg;
@override
set st(Vector2 arg) => _delegate.st = arg;
@override
set t(double arg) => _delegate.t = arg;
@override
set ts(Vector2 arg) => _delegate.ts = arg;
@override
set x(double arg) => _delegate.x = arg;
@override
set xy(Vector2 arg) => _delegate.xy = arg;
@override
set y(double arg) => _delegate.y = arg;
@override
set yx(Vector2 arg) => _delegate.yx = arg;
}

View File

@ -22,7 +22,7 @@ dev_dependencies:
test: ^1.9.4
environment:
sdk: ">=2.3.0 <3.0.0"
sdk: ">=2.7.0 <3.0.0"
flutter: ">=1.6.0"
flutter:

View File

@ -2,7 +2,7 @@ import 'dart:ui';
import 'package:flame/components/position_component.dart';
import 'package:flame/components/sprite_component.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:test/test.dart';
void main() {
@ -14,7 +14,7 @@ void main() {
expect(c.toPosition().x, 2.2);
expect(c.toPosition().y, 3.4);
c.setByPosition(Vector2F(1.0, 0.0));
c.setByPosition(Vector2(1.0, 0.0));
expect(c.x, 1.0);
expect(c.y, 0.0);
});
@ -26,7 +26,7 @@ void main() {
expect(c.toSize().x, 2.2);
expect(c.toSize().y, 3.4);
c.setBySize(Vector2F(1.0, 0.0));
c.setBySize(Vector2(1.0, 0.0));
expect(c.width, 1.0);
expect(c.height, 0.0);
});

View File

@ -5,7 +5,7 @@ import 'package:flame/components/mixins/has_game_ref.dart';
import 'package:flame/components/mixins/resizable.dart';
import 'package:flame/components/mixins/tapable.dart';
import 'package:flame/game/base_game.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:flutter/gestures.dart';
import 'package:test/test.dart';
@ -30,7 +30,7 @@ class MyComposed extends PositionComponent with HasGameRef, Tapable {
class PositionComponentNoNeedForRect extends PositionComponent with Tapable {}
Vector2F size = Vector2F(1.0, 1.0);
Vector2 size = Vector2(1.0, 1.0);
void main() {
group('composable component test', () {

View File

@ -1,5 +1,5 @@
import 'package:flame/game/base_game.dart';
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:test/test.dart';
import 'package:flame/components/position_component.dart';
@ -17,7 +17,7 @@ class MyComponent extends PositionComponent with Resizable {
class MyGame extends BaseGame {}
Vector2F size = Vector2F(1.0, 1.0);
Vector2 size = Vector2(1.0, 1.0);
void main() {
group('resizable test', () {

View File

@ -1,4 +1,4 @@
import 'package:flame/vector2f.dart';
import 'package:flame/vector2_extension.dart';
import 'package:test/test.dart';
import 'dart:math' as math;
@ -9,14 +9,14 @@ void expectDouble(double d1, double d2) {
void main() {
group('position test', () {
test('test add', () {
final Vector2F p = Vector2F(0.0, 5.0) + Vector2F(5.0, 5.0);
final Vector2 p = Vector2(0.0, 5.0) + Vector2(5.0, 5.0);
expectDouble(p.x, 5.0);
expectDouble(p.y, 10.0);
});
test('test clone', () {
final Vector2F p = Vector2F(1.0, 0.0);
final Vector2F clone = p.clone();
final Vector2 p = Vector2(1.0, 0.0);
final Vector2 clone = p.clone();
clone.scale(2.0);
expectDouble(p.x, 1.0);
@ -24,49 +24,49 @@ void main() {
});
test('test rotate', () {
final Vector2F p = Vector2F(1.0, 0.0)..rotate(math.pi / 2);
final Vector2 p = Vector2(1.0, 0.0)..rotate(math.pi / 2);
expectDouble(p.x, 0.0);
expectDouble(p.y, 1.0);
});
test('test length', () {
final Vector2F p1 = Vector2F(3.0, 4.0);
final Vector2 p1 = Vector2(3.0, 4.0);
expectDouble(p1.length, 5.0);
final Vector2F p2 = Vector2F(2.0, 0.0);
final Vector2 p2 = Vector2(2.0, 0.0);
expectDouble(p2.length, 2.0);
final Vector2F p3 = Vector2F(0.0, 1.5);
final Vector2 p3 = Vector2(0.0, 1.5);
expectDouble(p3.length, 1.5);
});
test('test distance', () {
final Vector2F p1 = Vector2F(10.0, 20.0);
final Vector2F p2 = Vector2F(13.0, 24.0);
final Vector2 p1 = Vector2(10.0, 20.0);
final Vector2 p2 = Vector2(13.0, 24.0);
final double result = p1.distanceTo(p2);
expectDouble(result, 5.0);
});
test('equality', () {
final Vector2F p1 = Vector2F.zero();
final Vector2F p2 = Vector2F.zero();
final Vector2 p1 = Vector2.zero();
final Vector2 p2 = Vector2.zero();
expect(p1 == p2, true);
});
test('non equality', () {
final Vector2F p1 = Vector2F.zero();
final Vector2F p2 = Vector2F(1.0, 0.0);
final Vector2 p1 = Vector2.zero();
final Vector2 p2 = Vector2(1.0, 0.0);
expect(p1 == p2, false);
});
test('hashCode', () {
final Vector2F p1 = Vector2F(2.0, -1.0);
final Vector2F p2 = Vector2F(1.0, 0.0);
final Vector2 p1 = Vector2(2.0, -1.0);
final Vector2 p2 = Vector2(1.0, 0.0);
expect(p1.hashCode == p2.hashCode, false);
});
test('scaleTo', () {
final Vector2F p = Vector2F(1.0, 0.0)
final Vector2 p = Vector2(1.0, 0.0)
..rotate(math.pi / 4)
..scaleTo(2.0);
@ -79,18 +79,18 @@ void main() {
});
test('scaleTo the zero vector', () {
final Vector2F p = Vector2F.zero();
final Vector2 p = Vector2.zero();
expect(p.normalized().length, 0.0);
});
test('limit', () {
final Vector2F p1 = Vector2F(1.0, 0.0);
final Vector2 p1 = Vector2(1.0, 0.0);
p1.clampScalar(0, 0.75);
expect(p1.length, 0.75);
expect(p1.x, 0.75);
expect(p1.y, 0.0);
final Vector2F p2 = Vector2F(1.0, 1.0);
final Vector2 p2 = Vector2(1.0, 1.0);
p2.clampScalar(0, 3.0);
expectDouble(p2.length, math.sqrt(2));
expect(p2.x, 1.0);