mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 03:15:43 +08:00
chore: Update min Dart constraint to 3.8 (#3676)
Update min Dart constraint to 3.8, which will enable us to use the fancier collection literals. This requires bumping the min Flutter version as well: <img width="1892" height="1122" alt="image" src="https://github.com/user-attachments/assets/7c7b07fc-4d96-4987-824d-9a7133ecfb85" />
This commit is contained in:
2
.github/workflows/cicd.yml
vendored
2
.github/workflows/cicd.yml
vendored
@ -9,7 +9,7 @@ on:
|
||||
|
||||
|
||||
env:
|
||||
FLUTTER_MIN_VERSION: '3.27.1'
|
||||
FLUTTER_MIN_VERSION: '3.32.0'
|
||||
|
||||
jobs:
|
||||
# BEGIN LINTING STAGE
|
||||
|
||||
@ -104,8 +104,12 @@ class Trail extends Component {
|
||||
: _paths = [Path()..moveTo(origin.x, origin.y)],
|
||||
_opacities = [1],
|
||||
_lastPoint = origin.clone(),
|
||||
_color =
|
||||
HSLColor.fromAHSL(1, random.nextDouble() * 360, 1, 0.8).toColor();
|
||||
_color = HSLColor.fromAHSL(
|
||||
1,
|
||||
random.nextDouble() * 360,
|
||||
1,
|
||||
0.8,
|
||||
).toColor();
|
||||
|
||||
final List<Path> _paths;
|
||||
final List<double> _opacities;
|
||||
|
||||
@ -30,9 +30,12 @@ class HoverTarget extends PositionComponent with HoverCallbacks {
|
||||
);
|
||||
|
||||
final _paint = Paint()
|
||||
..color = HSLColor.fromAHSL(1, _random.nextDouble() * 360, 1, 0.8)
|
||||
.toColor()
|
||||
.withValues(alpha: 0.5);
|
||||
..color = HSLColor.fromAHSL(
|
||||
1,
|
||||
_random.nextDouble() * 360,
|
||||
1,
|
||||
0.8,
|
||||
).toColor().withValues(alpha: 0.5);
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
|
||||
@ -33,8 +33,8 @@ class RemoveEffectGame extends FlameGame with TapDetector {
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
textComponent.text =
|
||||
(effect.controller.progress * delayTime).toStringAsFixed(2);
|
||||
textComponent.text = (effect.controller.progress * delayTime)
|
||||
.toStringAsFixed(2);
|
||||
super.update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,9 @@ class RiveExampleGame extends FlameGame with TapDetector {
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
final skillsArtboard =
|
||||
await loadArtboard(RiveFile.asset('assets/skills.riv'));
|
||||
final skillsArtboard = await loadArtboard(
|
||||
RiveFile.asset('assets/skills.riv'),
|
||||
);
|
||||
|
||||
final controller = StateMachineController.fromArtboard(
|
||||
skillsArtboard,
|
||||
|
||||
@ -63,8 +63,12 @@ class TapTarget extends PositionComponent with TapCallbacks {
|
||||
|
||||
class ExpandingCircle extends Component {
|
||||
ExpandingCircle(this._center)
|
||||
: _baseColor =
|
||||
HSLColor.fromAHSL(1, random.nextDouble() * 360, 1, 0.8).toColor();
|
||||
: _baseColor = HSLColor.fromAHSL(
|
||||
1,
|
||||
random.nextDouble() * 360,
|
||||
1,
|
||||
0.8,
|
||||
).toColor();
|
||||
|
||||
final Color _baseColor;
|
||||
final Vector2 _center;
|
||||
|
||||
@ -5,7 +5,7 @@ version: 1.0.0
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
@ -28,8 +28,10 @@ class KlondikeGame extends FlameGame {
|
||||
4,
|
||||
(i) => Foundation()
|
||||
..size = cardSize
|
||||
..position =
|
||||
Vector2((i + 3) * (cardWidth + cardGap) + cardGap, cardGap),
|
||||
..position = Vector2(
|
||||
(i + 3) * (cardWidth + cardGap) + cardGap,
|
||||
cardGap,
|
||||
),
|
||||
);
|
||||
final piles = List.generate(
|
||||
7,
|
||||
@ -46,8 +48,10 @@ class KlondikeGame extends FlameGame {
|
||||
world.addAll(foundations);
|
||||
world.addAll(piles);
|
||||
|
||||
camera.viewfinder.visibleGameSize =
|
||||
Vector2(cardWidth * 7 + cardGap * 8, 4 * cardHeight + 3 * cardGap);
|
||||
camera.viewfinder.visibleGameSize = Vector2(
|
||||
cardWidth * 7 + cardGap * 8,
|
||||
4 * cardHeight + 3 * cardGap,
|
||||
);
|
||||
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
||||
camera.viewfinder.anchor = Anchor.topCenter;
|
||||
}
|
||||
|
||||
@ -31,8 +31,10 @@ class KlondikeGame extends FlameGame {
|
||||
4,
|
||||
(i) => Foundation()
|
||||
..size = cardSize
|
||||
..position =
|
||||
Vector2((i + 3) * (cardWidth + cardGap) + cardGap, cardGap),
|
||||
..position = Vector2(
|
||||
(i + 3) * (cardWidth + cardGap) + cardGap,
|
||||
cardGap,
|
||||
),
|
||||
);
|
||||
final piles = List.generate(
|
||||
7,
|
||||
@ -49,8 +51,10 @@ class KlondikeGame extends FlameGame {
|
||||
world.addAll(foundations);
|
||||
world.addAll(piles);
|
||||
|
||||
camera.viewfinder.visibleGameSize =
|
||||
Vector2(cardWidth * 7 + cardGap * 8, 4 * cardHeight + 3 * cardGap);
|
||||
camera.viewfinder.visibleGameSize = Vector2(
|
||||
cardWidth * 7 + cardGap * 8,
|
||||
4 * cardHeight + 3 * cardGap,
|
||||
);
|
||||
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
||||
camera.viewfinder.anchor = Anchor.topCenter;
|
||||
|
||||
|
||||
@ -26,8 +26,9 @@ class KlondikeGame extends FlameGame {
|
||||
await Flame.images.load('klondike-sprites.png');
|
||||
|
||||
final stock = StockPile(position: Vector2(cardGap, cardGap));
|
||||
final waste =
|
||||
WastePile(position: Vector2(cardWidth + 2 * cardGap, cardGap));
|
||||
final waste = WastePile(
|
||||
position: Vector2(cardWidth + 2 * cardGap, cardGap),
|
||||
);
|
||||
final foundations = List.generate(
|
||||
4,
|
||||
(i) => FoundationPile(
|
||||
@ -50,8 +51,10 @@ class KlondikeGame extends FlameGame {
|
||||
world.addAll(foundations);
|
||||
world.addAll(piles);
|
||||
|
||||
camera.viewfinder.visibleGameSize =
|
||||
Vector2(cardWidth * 7 + cardGap * 8, 4 * cardHeight + 3 * cardGap);
|
||||
camera.viewfinder.visibleGameSize = Vector2(
|
||||
cardWidth * 7 + cardGap * 8,
|
||||
4 * cardHeight + 3 * cardGap,
|
||||
);
|
||||
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
||||
camera.viewfinder.anchor = Anchor.topCenter;
|
||||
|
||||
|
||||
@ -111,7 +111,8 @@ class TableauPile extends PositionComponent implements Pile {
|
||||
}
|
||||
|
||||
void calculateHitArea() {
|
||||
height = KlondikeGame.cardHeight * 1.5 +
|
||||
height =
|
||||
KlondikeGame.cardHeight * 1.5 +
|
||||
(_cards.length < 2 ? 0.0 : _cards.last.y - _cards.first.y);
|
||||
}
|
||||
|
||||
|
||||
@ -74,8 +74,10 @@ class KlondikeWorld extends World with HasGameReference<KlondikeGame> {
|
||||
addAll(cards);
|
||||
add(baseCard);
|
||||
|
||||
playAreaSize =
|
||||
Vector2(7 * cardSpaceWidth + cardGap, 4 * cardSpaceHeight + topGap);
|
||||
playAreaSize = Vector2(
|
||||
7 * cardSpaceWidth + cardGap,
|
||||
4 * cardSpaceHeight + topGap,
|
||||
);
|
||||
final gameMidX = playAreaSize.x / 2;
|
||||
|
||||
addButton('New deal', gameMidX, Action.newDeal);
|
||||
|
||||
@ -5,7 +5,7 @@ version: 1.0.0
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
flame: ^1.30.1
|
||||
|
||||
@ -46,11 +46,13 @@ class EmberPlayer extends SpriteAnimationComponent
|
||||
@override
|
||||
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
|
||||
horizontalDirection = 0;
|
||||
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyA) ||
|
||||
horizontalDirection +=
|
||||
(keysPressed.contains(LogicalKeyboardKey.keyA) ||
|
||||
keysPressed.contains(LogicalKeyboardKey.arrowLeft))
|
||||
? -1
|
||||
: 0;
|
||||
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyD) ||
|
||||
horizontalDirection +=
|
||||
(keysPressed.contains(LogicalKeyboardKey.keyD) ||
|
||||
keysPressed.contains(LogicalKeyboardKey.arrowRight))
|
||||
? 1
|
||||
: 0;
|
||||
@ -114,7 +116,8 @@ class EmberPlayer extends SpriteAnimationComponent
|
||||
if (other is GroundBlock || other is PlatformBlock) {
|
||||
if (intersectionPoints.length == 2) {
|
||||
// Calculate the collision normal and separation distance.
|
||||
final mid = (intersectionPoints.elementAt(0) +
|
||||
final mid =
|
||||
(intersectionPoints.elementAt(0) +
|
||||
intersectionPoints.elementAt(1)) /
|
||||
2;
|
||||
|
||||
@ -159,7 +162,8 @@ class EmberPlayer extends SpriteAnimationComponent
|
||||
duration: 0.1,
|
||||
repeatCount: 5,
|
||||
),
|
||||
)..onComplete = () {
|
||||
)
|
||||
..onComplete = () {
|
||||
hitByEnemy = false;
|
||||
},
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
@ -76,7 +76,8 @@ class Player extends SpriteAnimationComponent
|
||||
selfPositioning: true,
|
||||
factory: (index) {
|
||||
return Bullet(
|
||||
position: position +
|
||||
position:
|
||||
position +
|
||||
Vector2(
|
||||
0,
|
||||
-height / 2,
|
||||
|
||||
@ -87,7 +87,8 @@ class Player extends SpriteAnimationComponent
|
||||
selfPositioning: true,
|
||||
factory: (index) {
|
||||
return Bullet(
|
||||
position: position +
|
||||
position:
|
||||
position +
|
||||
Vector2(
|
||||
0,
|
||||
-height / 2,
|
||||
|
||||
@ -89,7 +89,8 @@ class Player extends SpriteAnimationComponent
|
||||
selfPositioning: true,
|
||||
factory: (index) {
|
||||
return Bullet(
|
||||
position: position +
|
||||
position:
|
||||
position +
|
||||
Vector2(
|
||||
0,
|
||||
-height / 2,
|
||||
|
||||
@ -7,7 +7,7 @@ publish_to: 'none'
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
flame: ^1.30.1
|
||||
|
||||
@ -21,7 +21,8 @@ and the glowing effect of the crystal ball.
|
||||
|
||||
class _CrystalBallWidgetState extends State<CrystalBallWidget> {
|
||||
// PreloadedPrograms is a simple data class that holds the preloaded
|
||||
late final Future<PreloadedPrograms> preloadedPrograms = Future.wait([
|
||||
late final Future<PreloadedPrograms> preloadedPrograms =
|
||||
Future.wait([
|
||||
FragmentProgram.fromAsset('packages/crystal_ball/shaders/ground.frag'),
|
||||
FragmentProgram.fromAsset('packages/crystal_ball/shaders/fog.frag'),
|
||||
FragmentProgram.fromAsset('packages/crystal_ball/shaders/firefly.frag'),
|
||||
|
||||
@ -60,8 +60,12 @@ class BallGlowPostProcess extends PostProcess {
|
||||
Vector2 size,
|
||||
Canvas canvas,
|
||||
) {
|
||||
final origin =
|
||||
world.findGame()!.camera.visibleWorldRect.topLeft.toVector2();
|
||||
final origin = world
|
||||
.findGame()!
|
||||
.camera
|
||||
.visibleWorldRect
|
||||
.topLeft
|
||||
.toVector2();
|
||||
final theBall = world.theBall;
|
||||
final ballPosition = theBall.absolutePosition;
|
||||
final uvBall = (ballPosition - origin)..divide(kCameraSize);
|
||||
|
||||
@ -33,8 +33,9 @@ class FireflyPostProcess extends PostProcess {
|
||||
|
||||
final groundPosition =
|
||||
world.ground.rectangle.absolutePosition + Vector2(0, 1800);
|
||||
final globalGroundPosition =
|
||||
camera.viewfinder.localToGlobal(groundPosition);
|
||||
final globalGroundPosition = camera.viewfinder.localToGlobal(
|
||||
groundPosition,
|
||||
);
|
||||
final uvGround = globalGroundPosition.y / size.y;
|
||||
|
||||
final cameraVerticalPos = world.cameraTarget.position.clone()
|
||||
|
||||
@ -27,8 +27,8 @@ class ForegroundFogPostProcess extends PostProcess {
|
||||
|
||||
@override
|
||||
void postProcess(Vector2 size, Canvas canvas) {
|
||||
final origin =
|
||||
CameraComponent.currentCamera!.visibleWorldRect.topLeft.toVector2();
|
||||
final origin = CameraComponent.currentCamera!.visibleWorldRect.topLeft
|
||||
.toVector2();
|
||||
|
||||
shader.setFloatUniforms((value) {
|
||||
value.setVector(size);
|
||||
|
||||
@ -27,8 +27,9 @@ class WaterPostProcess extends PostProcess {
|
||||
void postProcess(Vector2 size, Canvas canvas) {
|
||||
final groundPosition = world.ground.rectangle.position;
|
||||
final camera = CameraComponent.currentCamera!;
|
||||
final globalGroundPosition =
|
||||
camera.viewfinder.localToGlobal(groundPosition);
|
||||
final globalGroundPosition = camera.viewfinder.localToGlobal(
|
||||
groundPosition,
|
||||
);
|
||||
final uvGround = globalGroundPosition.y / size.y;
|
||||
|
||||
final preRenderedSubtree = rasterizeSubtree();
|
||||
|
||||
@ -5,7 +5,7 @@ publish_to: 'none'
|
||||
version: "0.1.0"
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
@ -90,8 +90,9 @@ List<Ball> createBalls(Vector2 trackSize, List<Wall> walls, Ball bigBall) {
|
||||
ball.initialPosition.distanceTo(bigBall.initialPosition) <
|
||||
ball.radius + bigBall.radius;
|
||||
if (!touchesBall) {
|
||||
final touchesWall =
|
||||
walls.any((wall) => wall.asRect.overlaps(ball.asRect));
|
||||
final touchesWall = walls.any(
|
||||
(wall) => wall.asRect.overlaps(ball.asRect),
|
||||
);
|
||||
if (!touchesWall) {
|
||||
balls.add(ball);
|
||||
}
|
||||
|
||||
@ -94,8 +94,9 @@ class LapLine extends BodyComponent with ContactCallbacks {
|
||||
other.lapNotifier.value++;
|
||||
other.passedStartControl.clear();
|
||||
} else if (!isFinish) {
|
||||
other.passedStartControl
|
||||
.removeWhere((passedControl) => passedControl.id > id);
|
||||
other.passedStartControl.removeWhere(
|
||||
(passedControl) => passedControl.id > id,
|
||||
);
|
||||
other.passedStartControl.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +39,12 @@ class Tire extends BodyComponent<PadRacingGame> {
|
||||
|
||||
final Set<LogicalKeyboardKey> pressedKeys;
|
||||
|
||||
late final double _maxDriveForce =
|
||||
isFrontTire ? _frontTireMaxDriveForce : _backTireMaxDriveForce;
|
||||
late final double _maxLateralImpulse =
|
||||
isFrontTire ? _frontTireMaxLateralImpulse : _backTireMaxLateralImpulse;
|
||||
late final double _maxDriveForce = isFrontTire
|
||||
? _frontTireMaxDriveForce
|
||||
: _backTireMaxDriveForce;
|
||||
late final double _maxLateralImpulse = isFrontTire
|
||||
? _frontTireMaxLateralImpulse
|
||||
: _backTireMaxLateralImpulse;
|
||||
|
||||
// Make mutable if ice or something should be implemented
|
||||
final double _currentTraction = 1.0;
|
||||
@ -165,8 +167,10 @@ class Tire extends BodyComponent<PadRacingGame> {
|
||||
if (isTurnableTire && isTurning) {
|
||||
final turnPerTimeStep = _turnSpeedPerSecond * dt;
|
||||
final angleNow = joint.jointAngle();
|
||||
final angleToTurn =
|
||||
(desiredAngle - angleNow).clamp(-turnPerTimeStep, turnPerTimeStep);
|
||||
final angleToTurn = (desiredAngle - angleNow).clamp(
|
||||
-turnPerTimeStep,
|
||||
turnPerTimeStep,
|
||||
);
|
||||
final angle = angleNow + angleToTurn;
|
||||
joint.setLimits(angle, angle);
|
||||
} else {
|
||||
|
||||
@ -5,7 +5,7 @@ publish_to: 'none'
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
collection: ^1.17.1
|
||||
|
||||
@ -7,7 +7,7 @@ publish_to: 'none'
|
||||
version: 0.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
@ -53,7 +53,8 @@ class Cloud extends SpriteComponent
|
||||
@override
|
||||
void onGameResize(Vector2 size) {
|
||||
super.onGameResize(size);
|
||||
y = ((absolutePosition.y / 2 - (maxSkyLevel - minSkyLevel)) +
|
||||
y =
|
||||
((absolutePosition.y / 2 - (maxSkyLevel - minSkyLevel)) +
|
||||
game.random.nextDoubleBetween(minSkyLevel, maxSkyLevel)) -
|
||||
absolutePositionOf(absoluteTopLeftPosition).y;
|
||||
}
|
||||
|
||||
@ -66,7 +66,8 @@ class Horizon extends PositionComponent with HasGameReference<TRexGame> {
|
||||
|
||||
List<SpriteComponent> _generateLines() {
|
||||
final number = 1 + (game.size.x / lineSize.x).ceil() - groundLayers.length;
|
||||
final lastX = (groundLayers.lastOrNull?.x ?? 0) +
|
||||
final lastX =
|
||||
(groundLayers.lastOrNull?.x ?? 0) +
|
||||
(groundLayers.lastOrNull?.width ?? 0);
|
||||
return List.generate(
|
||||
max(number, 0),
|
||||
|
||||
@ -29,8 +29,8 @@ class Obstacle extends SpriteComponent with HasGameReference<TRexGame> {
|
||||
}
|
||||
|
||||
double computeGap(double gapCoefficient, double speed) {
|
||||
final minGap =
|
||||
(width * speed * settings.minGap * gapCoefficient).roundToDouble();
|
||||
final minGap = (width * speed * settings.minGap * gapCoefficient)
|
||||
.roundToDouble();
|
||||
final maxGap = (minGap * _maxGapCoefficient).roundToDouble();
|
||||
return game.random.nextDoubleBetween(minGap, maxGap);
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ publish_to: 'none'
|
||||
version: 0.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/bridge_libraries/audio/basic_audio_example.dart
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addAudioStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Audio').add(
|
||||
dashbook
|
||||
.storiesOf('Audio')
|
||||
.add(
|
||||
'Basic Audio',
|
||||
(_) => GameWidget(game: BasicAudioExample()),
|
||||
codeLink: baseLink('bridge_libraries/audio/basic_audio_example.dart'),
|
||||
|
||||
@ -28,8 +28,11 @@ class GearJointWorld extends Forge2DWorld with HasGameReference<Forge2DGame> {
|
||||
Future<void> onLoad() async {
|
||||
super.onLoad();
|
||||
|
||||
final box =
|
||||
DraggableBox(startPosition: boxAnchor, width: boxWidth, height: 20);
|
||||
final box = DraggableBox(
|
||||
startPosition: boxAnchor,
|
||||
width: boxWidth,
|
||||
height: 20,
|
||||
);
|
||||
add(box);
|
||||
|
||||
final ball1Anchor = boxAnchor - Vector2(boxWidth / 2 + ball1Radius, 0);
|
||||
|
||||
@ -54,7 +54,8 @@ class WeldJointWorld extends Forge2DWorld
|
||||
// screen space then gives us the coordinates of the upper left corner in
|
||||
// world space.
|
||||
final halfSize = game.screenToWorld(Vector2.zero())..absolute();
|
||||
final sectionWidth = ((leftPillar.center.x.abs() +
|
||||
final sectionWidth =
|
||||
((leftPillar.center.x.abs() +
|
||||
rightPillar.center.x.abs() +
|
||||
pillarWidth) /
|
||||
sectionsCount)
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/bridge_libraries/flame_isolate/simple_isolate_e
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addFlameIsolateExample(Dashbook dashbook) {
|
||||
dashbook.storiesOf('FlameIsolate').add(
|
||||
dashbook
|
||||
.storiesOf('FlameIsolate')
|
||||
.add(
|
||||
'Simple isolate example',
|
||||
(_) => GameWidget(
|
||||
game: SimpleIsolateExample(),
|
||||
|
||||
@ -25,13 +25,15 @@ commands work.
|
||||
final yarnProject = YarnProject();
|
||||
final dialogueControllerComponent = CommandLifecycleDialogueController(
|
||||
onCommandOverride: (command) async {
|
||||
final exampleVariable =
|
||||
yarnProject.variables.getVariable(r'$exampleVariable');
|
||||
final exampleVariable = yarnProject.variables.getVariable(
|
||||
r'$exampleVariable',
|
||||
);
|
||||
onCommandLabel.text = 'onCommand: $exampleVariable';
|
||||
},
|
||||
onCommandFinishOverride: (command) async {
|
||||
final exampleVariable =
|
||||
yarnProject.variables.getVariable(r'$exampleVariable');
|
||||
final exampleVariable = yarnProject.variables.getVariable(
|
||||
r'$exampleVariable',
|
||||
);
|
||||
onCommandFinishLabel.text = 'onCommandFinish: $exampleVariable';
|
||||
},
|
||||
);
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/bridge_libraries/flame_lottie/lottie_animation_
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addFlameLottieExample(Dashbook dashbook) {
|
||||
dashbook.storiesOf('FlameLottie').add(
|
||||
dashbook
|
||||
.storiesOf('FlameLottie')
|
||||
.add(
|
||||
'Lottie Animation example',
|
||||
(_) => GameWidget(
|
||||
game: LottieAnimationExample(),
|
||||
|
||||
@ -11,8 +11,9 @@ void addFlameSpineExamples(Dashbook dashbook) {
|
||||
(_) => GameWidget(
|
||||
game: FlameSpineExample(),
|
||||
),
|
||||
codeLink:
|
||||
baseLink('bridge_libraries/flame_spine/basic_spine_example.dart'),
|
||||
codeLink: baseLink(
|
||||
'bridge_libraries/flame_spine/basic_spine_example.dart',
|
||||
),
|
||||
info: FlameSpineExample.description,
|
||||
)
|
||||
..add(
|
||||
|
||||
@ -85,8 +85,9 @@ void addCameraAndViewportStories(Dashbook dashbook) {
|
||||
..add(
|
||||
'Follow and World bounds',
|
||||
(_) => GameWidget(game: CameraFollowAndWorldBoundsExample()),
|
||||
codeLink:
|
||||
baseLink('camera_and_viewport/camera_follow_and_world_bounds.dart'),
|
||||
codeLink: baseLink(
|
||||
'camera_and_viewport/camera_follow_and_world_bounds.dart',
|
||||
),
|
||||
info: CameraFollowAndWorldBoundsExample.description,
|
||||
);
|
||||
}
|
||||
|
||||
@ -36,8 +36,10 @@ class CameraComponentExample extends FlameGame<AntWorld> with PanDetector {
|
||||
camera.viewfinder.position = Vector2(center.x, center.y);
|
||||
});
|
||||
|
||||
magnifyingGlass =
|
||||
CameraComponent(world: world, viewport: CircularViewport(radius));
|
||||
magnifyingGlass = CameraComponent(
|
||||
world: world,
|
||||
viewport: CircularViewport(radius),
|
||||
);
|
||||
magnifyingGlass.viewport.add(Bezel(radius));
|
||||
magnifyingGlass.viewfinder.zoom = zoom;
|
||||
}
|
||||
@ -106,8 +108,8 @@ class Bezel extends PositionComponent {
|
||||
rimBorder = Path()
|
||||
..addOval(Rect.fromLTRB(-outer, -outer, outer, outer))
|
||||
..addOval(Rect.fromLTRB(-inner, -inner, inner, inner));
|
||||
handle = (Path()
|
||||
..addRRect(
|
||||
handle =
|
||||
(Path()..addRRect(
|
||||
RRect.fromLTRBR(
|
||||
radius,
|
||||
-handleWidth / 2,
|
||||
@ -117,11 +119,15 @@ class Bezel extends PositionComponent {
|
||||
),
|
||||
))
|
||||
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
||||
connector = (Path()
|
||||
..addArc(Rect.fromLTRB(-outer, -outer, outer, outer), -0.22, 0.44))
|
||||
connector =
|
||||
(Path()..addArc(
|
||||
Rect.fromLTRB(-outer, -outer, outer, outer),
|
||||
-0.22,
|
||||
0.44,
|
||||
))
|
||||
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
||||
specularHighlight = (Path()
|
||||
..addOval(Rect.fromLTWH(-radius * 0.8, -8, 16, radius * 0.3)))
|
||||
specularHighlight =
|
||||
(Path()..addOval(Rect.fromLTWH(-radius * 0.8, -8, 16, radius * 0.3)))
|
||||
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
||||
|
||||
glassPaint = Paint()..color = const Color(0x1400ffae);
|
||||
@ -428,8 +434,9 @@ class Ant extends PositionComponent {
|
||||
'nextIndex is outside of the bounds of travelPath',
|
||||
);
|
||||
final nextPosition = travelPath[nextIndex];
|
||||
var nextAngle =
|
||||
angle = -(nextPosition - position).angleToSigned(Vector2(0, -1));
|
||||
var nextAngle = angle = -(nextPosition - position).angleToSigned(
|
||||
Vector2(0, -1),
|
||||
);
|
||||
if (nextAngle - angle > tau / 2) {
|
||||
nextAngle -= tau;
|
||||
}
|
||||
|
||||
@ -23,7 +23,8 @@ class CameraComponentPropertiesExample extends FlameGame {
|
||||
|
||||
CameraComponentPropertiesExample()
|
||||
: super(
|
||||
camera: CameraComponent(
|
||||
camera:
|
||||
CameraComponent(
|
||||
viewport: FixedSizeViewport(200, 200)..add(ViewportFrame()),
|
||||
)
|
||||
..viewfinder.zoom = 5
|
||||
|
||||
@ -31,9 +31,7 @@ class CameraFollowAndWorldBoundsExample extends FlameGame
|
||||
}
|
||||
|
||||
class Ground extends PositionComponent {
|
||||
Ground()
|
||||
: pebbles = [],
|
||||
super(size: Vector2(1000, 30)) {
|
||||
Ground() : pebbles = [], super(size: Vector2(1000, 30)) {
|
||||
final random = Random();
|
||||
for (var i = 0; i < 25; i++) {
|
||||
pebbles.add(
|
||||
@ -144,11 +142,14 @@ class Player extends PositionComponent with KeyboardHandler {
|
||||
@override
|
||||
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
|
||||
final isKeyDown = event is KeyDownEvent;
|
||||
final keyLeft = (event.logicalKey == LogicalKeyboardKey.arrowLeft) ||
|
||||
final keyLeft =
|
||||
(event.logicalKey == LogicalKeyboardKey.arrowLeft) ||
|
||||
(event.logicalKey == LogicalKeyboardKey.keyA);
|
||||
final keyRight = (event.logicalKey == LogicalKeyboardKey.arrowRight) ||
|
||||
final keyRight =
|
||||
(event.logicalKey == LogicalKeyboardKey.arrowRight) ||
|
||||
(event.logicalKey == LogicalKeyboardKey.keyD);
|
||||
final keyUp = (event.logicalKey == LogicalKeyboardKey.arrowUp) ||
|
||||
final keyUp =
|
||||
(event.logicalKey == LogicalKeyboardKey.arrowUp) ||
|
||||
(event.logicalKey == LogicalKeyboardKey.keyW);
|
||||
|
||||
if (isKeyDown) {
|
||||
@ -161,9 +162,11 @@ class Player extends PositionComponent with KeyboardHandler {
|
||||
nJumpsLeft -= 1;
|
||||
}
|
||||
} else {
|
||||
final hasLeft = keysPressed.contains(LogicalKeyboardKey.arrowLeft) ||
|
||||
final hasLeft =
|
||||
keysPressed.contains(LogicalKeyboardKey.arrowLeft) ||
|
||||
keysPressed.contains(LogicalKeyboardKey.keyA);
|
||||
final hasRight = keysPressed.contains(LogicalKeyboardKey.arrowRight) ||
|
||||
final hasRight =
|
||||
keysPressed.contains(LogicalKeyboardKey.arrowRight) ||
|
||||
keysPressed.contains(LogicalKeyboardKey.keyD);
|
||||
if (hasLeft && hasRight) {
|
||||
// Leave the current speed unchanged
|
||||
|
||||
@ -19,8 +19,9 @@ void addCollisionDetectionStories(Dashbook dashbook) {
|
||||
..add(
|
||||
'Collidable AnimationComponent',
|
||||
(_) => GameWidget(game: CollidableAnimationExample()),
|
||||
codeLink:
|
||||
baseLink('collision_detection/collidable_animation_example.dart'),
|
||||
codeLink: baseLink(
|
||||
'collision_detection/collidable_animation_example.dart',
|
||||
),
|
||||
info: CollidableAnimationExample.description,
|
||||
)
|
||||
..add(
|
||||
@ -74,8 +75,9 @@ void addCollisionDetectionStories(Dashbook dashbook) {
|
||||
..add(
|
||||
'Raycasting Max Distance',
|
||||
(_) => GameWidget(game: RaycastMaxDistanceExample()),
|
||||
codeLink:
|
||||
baseLink('collision_detection/raycast_max_distance_example.dart'),
|
||||
codeLink: baseLink(
|
||||
'collision_detection/raycast_max_distance_example.dart',
|
||||
),
|
||||
info: RaycastMaxDistanceExample.description,
|
||||
)
|
||||
..add(
|
||||
|
||||
@ -67,7 +67,8 @@ class MultiShapesWorld extends World with HasGameReference {
|
||||
ScreenHitbox screenHitbox,
|
||||
) {
|
||||
final collidableSize = Vector2.all(50) + Vector2.random(_rng) * 100;
|
||||
final isXOverflow = lastCollidable.position.x +
|
||||
final isXOverflow =
|
||||
lastCollidable.position.x +
|
||||
lastCollidable.size.x / 2 +
|
||||
_distance.x +
|
||||
collidableSize.x >
|
||||
@ -288,12 +289,23 @@ MyCollidable randomCollidable(
|
||||
final rotationSpeed = 0.5 - rng.nextDouble();
|
||||
final shapeType = Shapes.values[rng.nextInt(Shapes.values.length)];
|
||||
return switch (shapeType) {
|
||||
Shapes.circle => CollidableCircle(position, size, velocity, screenHitbox)
|
||||
..rotationSpeed = rotationSpeed,
|
||||
Shapes.rectangle =>
|
||||
CollidableRectangle(position, size, velocity, screenHitbox)
|
||||
..rotationSpeed = rotationSpeed,
|
||||
Shapes.polygon => CollidablePolygon(position, size, velocity, screenHitbox)
|
||||
..rotationSpeed = rotationSpeed,
|
||||
Shapes.circle => CollidableCircle(
|
||||
position,
|
||||
size,
|
||||
velocity,
|
||||
screenHitbox,
|
||||
)..rotationSpeed = rotationSpeed,
|
||||
Shapes.rectangle => CollidableRectangle(
|
||||
position,
|
||||
size,
|
||||
velocity,
|
||||
screenHitbox,
|
||||
)..rotationSpeed = rotationSpeed,
|
||||
Shapes.polygon => CollidablePolygon(
|
||||
position,
|
||||
size,
|
||||
velocity,
|
||||
screenHitbox,
|
||||
)..rotationSpeed = rotationSpeed,
|
||||
};
|
||||
}
|
||||
|
||||
@ -229,8 +229,10 @@ class Player extends SpriteComponent
|
||||
Set<Vector2> intersectionPoints,
|
||||
PositionComponent other,
|
||||
) {
|
||||
final myCenter =
|
||||
Vector2(position.x + tileSize / 2, position.y + tileSize / 2);
|
||||
final myCenter = Vector2(
|
||||
position.x + tileSize / 2,
|
||||
position.y + tileSize / 2,
|
||||
);
|
||||
if (other is GameCollidable) {
|
||||
final diffX = myCenter.x - other.cachedCenter.x;
|
||||
if (diffX < 0) {
|
||||
@ -348,8 +350,10 @@ mixin GameCollidable on PositionComponent {
|
||||
}
|
||||
|
||||
void initCenter() {
|
||||
cachedCenter =
|
||||
Vector2(position.x + tileSize / 2, position.y + tileSize / 2);
|
||||
cachedCenter = Vector2(
|
||||
position.x + tileSize / 2,
|
||||
position.y + tileSize / 2,
|
||||
);
|
||||
}
|
||||
|
||||
late final Vector2 cachedCenter;
|
||||
@ -430,4 +434,5 @@ class QuadTreeDebugComponent extends PositionComponent with HasPaint {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@ -57,7 +57,8 @@ class RaysInShapeWorld extends World
|
||||
List<Ray2> randomRays(int count) => List<Ray2>.generate(
|
||||
count,
|
||||
(index) => Ray2(
|
||||
origin: (Vector2.random(_rng)) * playArea.size.width -
|
||||
origin:
|
||||
(Vector2.random(_rng)) * playArea.size.width -
|
||||
playArea.size.toVector2() / 2,
|
||||
direction: (Vector2.random(_rng) - Vector2(0.5, 0.5)).normalized(),
|
||||
),
|
||||
|
||||
@ -63,8 +63,7 @@ bounce on will appear.
|
||||
_timePassed = 0;
|
||||
if (extraChildren.isEmpty) {
|
||||
addAll(
|
||||
extraChildren
|
||||
..addAll(
|
||||
extraChildren..addAll(
|
||||
[
|
||||
CircleComponent(
|
||||
position: Vector2(100, 100),
|
||||
|
||||
@ -62,8 +62,9 @@ void addComponentsStories(Dashbook dashbook) {
|
||||
..add(
|
||||
'Component Notifier (with provider)',
|
||||
(_) => const ComponentsNotifierProviderExampleWidget(),
|
||||
codeLink:
|
||||
baseLink('components/components_notifier_provider_example.dart'),
|
||||
codeLink: baseLink(
|
||||
'components/components_notifier_provider_example.dart',
|
||||
),
|
||||
info: ComponentsNotifierProviderExampleWidget.description,
|
||||
)
|
||||
..add(
|
||||
|
||||
@ -12,7 +12,8 @@ import 'package:flutter/services.dart';
|
||||
|
||||
class LookAtExample extends FlameGame<_TapWorld>
|
||||
with HasKeyboardHandlerComponents {
|
||||
static const description = 'This example demonstrates how a component can be '
|
||||
static const description =
|
||||
'This example demonstrates how a component can be '
|
||||
'made to look at a specific target using the lookAt method. Tap anywhere '
|
||||
'to change the target point for both the choppers. '
|
||||
'It also shows how nativeAngle can be used to make the component '
|
||||
@ -168,7 +169,8 @@ class _ChopperParent extends PositionComponent
|
||||
@override
|
||||
void update(double dt) {
|
||||
final angleTo = chopper.angleTo(game.world.target.position);
|
||||
textBox.text = '''
|
||||
textBox.text =
|
||||
'''
|
||||
nativeAngle = ${chopper.nativeAngle.toStringAsFixed(2)}
|
||||
angleTo = ${angleTo.toStringAsFixed(2)}
|
||||
absoluteAngle = ${chopper.absoluteAngle.toStringAsFixed(2)}
|
||||
|
||||
@ -10,7 +10,8 @@ import 'package:flame/sprite.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LookAtSmoothExample extends FlameGame {
|
||||
static const description = 'This example demonstrates how a component can be '
|
||||
static const description =
|
||||
'This example demonstrates how a component can be '
|
||||
'made to smoothly rotate towards a target using the angleTo method. '
|
||||
'Tap anywhere to change the target point for both the choppers. '
|
||||
'It also shows how nativeAngle can be used to make the component '
|
||||
|
||||
@ -30,7 +30,8 @@ class _RotateAroundEffectWorld extends World {
|
||||
add(_GlowingBall(position: Vector2.zero(), radius: 30));
|
||||
final rotatingBalls = List.generate(
|
||||
4,
|
||||
(i) => _GlowingBall(
|
||||
(i) =>
|
||||
_GlowingBall(
|
||||
position: Vector2(100 + 10.0 * i, 0),
|
||||
radius: 10,
|
||||
)..add(
|
||||
|
||||
@ -18,9 +18,9 @@ class DoubleTapCallbacksExample extends FlameGame with DoubleTapCallbacks {
|
||||
|
||||
@override
|
||||
void onGameResize(Vector2 size) {
|
||||
children
|
||||
.query<DoubleTappableEmber>()
|
||||
.forEach((element) => element.removeFromParent());
|
||||
children.query<DoubleTappableEmber>().forEach(
|
||||
(element) => element.removeFromParent(),
|
||||
);
|
||||
add(DoubleTappableEmber(position: size / 2));
|
||||
|
||||
super.onGameResize(size);
|
||||
|
||||
@ -200,8 +200,10 @@ class JoystickAdvancedExample extends FlameGame with HasCollisionDetection {
|
||||
void update(double dt) {
|
||||
super.update(dt);
|
||||
speedText.text = 'Speed: ${(joystick.intensity * player.maxSpeed).round()}';
|
||||
final direction =
|
||||
joystick.direction.toString().replaceAll('JoystickDirection.', '');
|
||||
final direction = joystick.direction.toString().replaceAll(
|
||||
'JoystickDirection.',
|
||||
'',
|
||||
);
|
||||
directionText.text = 'Direction: $direction';
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/layout/align_component.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addLayoutStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Layout').add(
|
||||
dashbook
|
||||
.storiesOf('Layout')
|
||||
.add(
|
||||
'AlignComponent',
|
||||
(_) => GameWidget(game: AlignComponentExample()),
|
||||
codeLink: baseLink('layout/align_component.dart'),
|
||||
|
||||
@ -327,7 +327,8 @@ class ParticlesExample extends FlameGame {
|
||||
Particle acceleratedParticles() {
|
||||
return Particle.generate(
|
||||
generator: (i) => AcceleratedParticle(
|
||||
speed: Vector2(
|
||||
speed:
|
||||
Vector2(
|
||||
rnd.nextDouble() * 600 - 300,
|
||||
-rnd.nextDouble() * 600,
|
||||
) *
|
||||
@ -432,8 +433,9 @@ class ParticlesExample extends FlameGame {
|
||||
renderer: (canvas, particle) {
|
||||
final paint = randomElement(paints);
|
||||
// Override the color to dynamically update opacity
|
||||
paint.color =
|
||||
paint.color.withValues(alpha: 1 - particle.progress);
|
||||
paint.color = paint.color.withValues(
|
||||
alpha: 1 - particle.progress,
|
||||
);
|
||||
|
||||
canvas.drawCircle(
|
||||
Offset.zero,
|
||||
|
||||
@ -8,7 +8,8 @@ import 'package:flame/particles.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ParticlesInteractiveExample extends FlameGame with PanDetector {
|
||||
static const description = 'An example which shows how '
|
||||
static const description =
|
||||
'An example which shows how '
|
||||
'ParticleSystemComponent can be added in runtime '
|
||||
'following an event, in this example, the mouse '
|
||||
'dragging';
|
||||
@ -39,7 +40,8 @@ class ParticlesInteractiveExample extends FlameGame with PanDetector {
|
||||
generator: (i) {
|
||||
return AcceleratedParticle(
|
||||
lifespan: 2,
|
||||
speed: Vector2(
|
||||
speed:
|
||||
Vector2(
|
||||
noise.transform(random.nextDouble()),
|
||||
noise.transform(random.nextDouble()),
|
||||
) *
|
||||
|
||||
@ -51,7 +51,8 @@ class RichTextExample extends FlameGame {
|
||||
ParagraphNode.group([
|
||||
PlainTextNode(
|
||||
'Suddenly, like a lump of submerged wreckage breaking the surface '
|
||||
'of water, the thought burst into his mind: '),
|
||||
'of water, the thought burst into his mind: ',
|
||||
),
|
||||
ItalicTextNode.group([
|
||||
PlainTextNode('"It doesn\'t really happen. We imagine it. It is '),
|
||||
BoldTextNode.simple('hallucination'),
|
||||
|
||||
@ -31,8 +31,8 @@ class TextExample extends FlameGame {
|
||||
MyTextBox(
|
||||
'"This is our world now. The world of the electron and the switch; '
|
||||
'the beauty of the baud. We exist without nationality, skin color, '
|
||||
'or religious bias. You wage wars, murder, cheat, lie to us and try '
|
||||
"to make us believe it's for our own good, yet we're the "
|
||||
'or religious bias. You wage wars, murder, cheat, lie to us and '
|
||||
"try to make us believe it's for our own good, yet we're the "
|
||||
'criminals. Yes, I am a criminal. My crime is that of curiosity."',
|
||||
)
|
||||
..anchor = Anchor.bottomLeft
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/router/router_world_example.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addRouterStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Router').add(
|
||||
dashbook
|
||||
.storiesOf('Router')
|
||||
.add(
|
||||
'Router with multiple worlds',
|
||||
(_) => GameWidget(game: RouterWorldExample()),
|
||||
codeLink: baseLink('router/router_world_example.dart'),
|
||||
|
||||
@ -15,14 +15,20 @@ class SpriteSheetExample extends FlameGame {
|
||||
srcSize: Vector2(16.0, 18.0),
|
||||
);
|
||||
|
||||
final vampireAnimation =
|
||||
spriteSheet.createAnimation(row: 0, stepTime: 0.1, to: 7);
|
||||
final vampireAnimation = spriteSheet.createAnimation(
|
||||
row: 0,
|
||||
stepTime: 0.1,
|
||||
to: 7,
|
||||
);
|
||||
|
||||
final ghostAnimation =
|
||||
spriteSheet.createAnimation(row: 1, stepTime: 0.1, to: 7);
|
||||
final ghostAnimation = spriteSheet.createAnimation(
|
||||
row: 1,
|
||||
stepTime: 0.1,
|
||||
to: 7,
|
||||
);
|
||||
|
||||
final ghostAnimationVariableStepTimes =
|
||||
spriteSheet.createAnimationWithVariableStepTimes(
|
||||
final ghostAnimationVariableStepTimes = spriteSheet
|
||||
.createAnimationWithVariableStepTimes(
|
||||
row: 1,
|
||||
to: 7,
|
||||
stepTimes: [0.1, 0.1, 0.3, 0.3, 0.5, 0.3, 0.1],
|
||||
|
||||
@ -62,8 +62,7 @@ class ResettableLevel extends Level {
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
add(
|
||||
Ember()
|
||||
..add(
|
||||
Ember()..add(
|
||||
ScaleEffect.by(
|
||||
Vector2.all(3),
|
||||
EffectController(duration: 1, alternate: true, infinite: true),
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/structure/levels.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addStructureStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Structure').add(
|
||||
dashbook
|
||||
.storiesOf('Structure')
|
||||
.add(
|
||||
'Levels',
|
||||
(_) => GameWidget(game: LevelsExample()),
|
||||
info: LevelsExample.description,
|
||||
|
||||
@ -4,7 +4,9 @@ import 'package:examples/stories/svg/svg_component.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addSvgStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Svg').add(
|
||||
dashbook
|
||||
.storiesOf('Svg')
|
||||
.add(
|
||||
'Svg Component',
|
||||
(_) => GameWidget(game: SvgComponentExample()),
|
||||
codeLink: baseLink('svg/svg_component.dart'),
|
||||
|
||||
@ -5,7 +5,9 @@ import 'package:examples/stories/tiled/flame_tiled_animation_example.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
void addTiledStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Tiled').add(
|
||||
dashbook
|
||||
.storiesOf('Tiled')
|
||||
.add(
|
||||
'Flame Tiled Animation',
|
||||
(_) => GameWidget(game: FlameTiledAnimationExample()),
|
||||
codeLink: baseLink('tiled/flame_tiled_animation_example.dart'),
|
||||
|
||||
@ -21,7 +21,8 @@ Widget spriteAnimationWidgetBuilder(DashbookContext ctx) {
|
||||
anchor: Anchor.valueOf(
|
||||
ctx.listProperty('anchor', 'center', anchorOptions),
|
||||
),
|
||||
paint: paintList[paintChoices.indexOf(
|
||||
paint:
|
||||
paintList[paintChoices.indexOf(
|
||||
ctx.listProperty(
|
||||
'paint',
|
||||
'none',
|
||||
|
||||
@ -18,7 +18,8 @@ Widget spriteWidgetBuilder(DashbookContext ctx) {
|
||||
anchor: Anchor.valueOf(
|
||||
ctx.listProperty('anchor', 'center', anchorOptions),
|
||||
),
|
||||
paint: paintList[paintChoices.indexOf(
|
||||
paint:
|
||||
paintList[paintChoices.indexOf(
|
||||
ctx.listProperty(
|
||||
'paint',
|
||||
'none',
|
||||
|
||||
@ -7,7 +7,7 @@ publish_to: "none"
|
||||
version: 0.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
@ -34,8 +34,9 @@ class UpdateComponentsBenchmark extends AsyncBenchmarkBase {
|
||||
|
||||
await _game.ready();
|
||||
|
||||
_components =
|
||||
_game.children.whereType<_BenchmarkComponent>().toList(growable: false);
|
||||
_components = _game.children.whereType<_BenchmarkComponent>().toList(
|
||||
growable: false,
|
||||
);
|
||||
|
||||
_dts = List.generate(_amountTicks, (_) => random.nextDouble());
|
||||
_inputTicks = List.generate(
|
||||
|
||||
@ -5,7 +5,7 @@ version: 0.1.0
|
||||
publish_to: 'none'
|
||||
|
||||
environment:
|
||||
sdk: ">=3.6.0 <4.0.0"
|
||||
sdk: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
||||
dependencies:
|
||||
|
||||
25
packages/flame/lib/src/cache/images.dart
vendored
25
packages/flame/lib/src/cache/images.dart
vendored
@ -66,8 +66,9 @@ class Images {
|
||||
String name,
|
||||
Future<Image> Function() imageGenerator,
|
||||
) {
|
||||
return (_assets[name] ??= _ImageAsset.future(imageGenerator()))
|
||||
.retrieveAsync();
|
||||
return (_assets[name] ??= _ImageAsset.future(
|
||||
imageGenerator(),
|
||||
)).retrieveAsync();
|
||||
}
|
||||
|
||||
/// Removes the image [name] from the cache.
|
||||
@ -117,9 +118,9 @@ class Images {
|
||||
/// By default the key in the cache is the [fileName], if another key is
|
||||
/// desired, specify the optional [key] argument.
|
||||
Future<Image> load(String fileName, {String? key}) {
|
||||
return (_assets[key ?? fileName] ??=
|
||||
_ImageAsset.future(_fetchToMemory(fileName)))
|
||||
.retrieveAsync();
|
||||
return (_assets[key ?? fileName] ??= _ImageAsset.future(
|
||||
_fetchToMemory(fileName),
|
||||
)).retrieveAsync();
|
||||
}
|
||||
|
||||
/// Loads all images with the specified [fileNames] into the cache.
|
||||
@ -142,9 +143,12 @@ class Images {
|
||||
Future<List<Image>> loadAllFromPattern(Pattern pattern) async {
|
||||
final manifestContent = await bundle.loadString('AssetManifest.json');
|
||||
final manifestMap = json.decode(manifestContent) as Map<String, dynamic>;
|
||||
final imagePaths = manifestMap.keys.where((path) {
|
||||
return path.startsWith(_prefix) && path.toLowerCase().contains(pattern);
|
||||
}).map((path) => path.replaceFirst(_prefix, ''));
|
||||
final imagePaths = manifestMap.keys
|
||||
.where((path) {
|
||||
return path.startsWith(_prefix) &&
|
||||
path.toLowerCase().contains(pattern);
|
||||
})
|
||||
.map((path) => path.replaceFirst(_prefix, ''));
|
||||
return loadAll(imagePaths.toList());
|
||||
}
|
||||
|
||||
@ -166,8 +170,9 @@ class Images {
|
||||
}
|
||||
|
||||
Future<Image> fromBase64(String key, String base64) {
|
||||
return (_assets[key] ??= _ImageAsset.future(_fetchFromBase64(base64)))
|
||||
.retrieveAsync();
|
||||
return (_assets[key] ??= _ImageAsset.future(
|
||||
_fetchFromBase64(base64),
|
||||
)).retrieveAsync();
|
||||
}
|
||||
|
||||
Future<Image> _fetchFromBase64(String base64Data) {
|
||||
|
||||
@ -255,8 +255,10 @@ class CameraComponent extends Component {
|
||||
///
|
||||
/// Opposite of [globalToLocal].
|
||||
Vector2 localToGlobal(Vector2 position, {Vector2? output}) {
|
||||
final viewfinderPosition =
|
||||
viewfinder.localToGlobal(position, output: output);
|
||||
final viewfinderPosition = viewfinder.localToGlobal(
|
||||
position,
|
||||
output: output,
|
||||
);
|
||||
return viewport.localToGlobal(viewfinderPosition, output: output);
|
||||
}
|
||||
|
||||
@ -394,8 +396,8 @@ class CameraComponent extends Component {
|
||||
/// [Circle] shapes.
|
||||
void setBounds(Shape? bounds, {bool considerViewport = false}) {
|
||||
final boundedBehavior = viewfinder.firstChild<BoundedPositionBehavior>();
|
||||
final viewPortAwareBoundsBehavior =
|
||||
viewfinder.firstChild<ViewportAwareBoundsBehavior>();
|
||||
final viewPortAwareBoundsBehavior = viewfinder
|
||||
.firstChild<ViewportAwareBoundsBehavior>();
|
||||
|
||||
if (bounds == null) {
|
||||
// When bounds is null, all bounds-related components need to be dropped.
|
||||
@ -442,8 +444,9 @@ class CameraComponent extends Component {
|
||||
// in this exact cycle but did not mount into the tree.
|
||||
// We must wait for that component to mount first in order for
|
||||
// ViewportAwareBoundsBehavior to correctly affect the camera.
|
||||
boundedBehaviorFuture
|
||||
.whenComplete(() => _addViewPortAwareBoundsBehavior(bounds));
|
||||
boundedBehaviorFuture.whenComplete(
|
||||
() => _addViewPortAwareBoundsBehavior(bounds),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
viewPortAwareBoundsBehavior.boundsShape = bounds;
|
||||
@ -500,10 +503,10 @@ class CameraComponent extends Component {
|
||||
PostProcess? get postProcess =>
|
||||
children.query<PostProcessComponent>().firstOrNull?.postProcess;
|
||||
set postProcess(PostProcess? postProcess) {
|
||||
final postProcessComponents =
|
||||
children.query<PostProcessComponent>().toList();
|
||||
final queuedPostProcessAdds = findGame()
|
||||
?.queue
|
||||
final postProcessComponents = children
|
||||
.query<PostProcessComponent>()
|
||||
.toList();
|
||||
final queuedPostProcessAdds = findGame()?.queue
|
||||
.where(
|
||||
(event) =>
|
||||
event.kind == LifecycleEventKind.add &&
|
||||
|
||||
@ -3,15 +3,17 @@ import 'dart:collection';
|
||||
import 'package:flame/collisions.dart';
|
||||
import 'package:flame/extensions.dart';
|
||||
|
||||
typedef ExternalBroadphaseCheck = bool Function(
|
||||
typedef ExternalBroadphaseCheck =
|
||||
bool Function(
|
||||
ShapeHitbox first,
|
||||
ShapeHitbox second,
|
||||
);
|
||||
);
|
||||
|
||||
typedef ExternalMinDistanceCheck = bool Function(
|
||||
typedef ExternalMinDistanceCheck =
|
||||
bool Function(
|
||||
Vector2 activeItemCenter,
|
||||
Vector2 potentialCenter,
|
||||
);
|
||||
);
|
||||
|
||||
/// Performs Quad Tree broadphase check.
|
||||
///
|
||||
|
||||
@ -332,8 +332,11 @@ class QuadTreeNodeDebugInfo {
|
||||
}
|
||||
|
||||
class QuadTreeNode<T extends Hitbox<T>> {
|
||||
final List<QuadTreeNode?> children =
|
||||
List.generate(4, (index) => null, growable: false);
|
||||
final List<QuadTreeNode?> children = List.generate(
|
||||
4,
|
||||
(index) => null,
|
||||
growable: false,
|
||||
);
|
||||
|
||||
List<T> hitboxes = <T>[];
|
||||
|
||||
|
||||
@ -165,10 +165,11 @@ mixin CollisionCallbacks on Component
|
||||
|
||||
/// Can be used used to implement an `onCollisionCallback` or an
|
||||
/// `onCollisionStartCallback`.
|
||||
typedef CollisionCallback<T> = void Function(
|
||||
typedef CollisionCallback<T> =
|
||||
void Function(
|
||||
Set<Vector2> intersectionPoints,
|
||||
T other,
|
||||
);
|
||||
);
|
||||
|
||||
/// Can be used used to implement an `onCollisionEndCallback`.
|
||||
typedef CollisionEndCallback<T> = void Function(T other);
|
||||
|
||||
@ -8,8 +8,10 @@ import 'package:flutter/material.dart';
|
||||
///
|
||||
/// If the [HasCollisionDetection] mixin is added to the game, [run] is called
|
||||
/// every tick to check for collisions.
|
||||
abstract class CollisionDetection<T extends Hitbox<T>,
|
||||
B extends Broadphase<T>> {
|
||||
abstract class CollisionDetection<
|
||||
T extends Hitbox<T>,
|
||||
B extends Broadphase<T>
|
||||
> {
|
||||
final B broadphase;
|
||||
|
||||
List<T> get items => broadphase.items;
|
||||
|
||||
@ -15,9 +15,11 @@ mixin CollisionPassthrough on CollisionCallbacks {
|
||||
@mustCallSuper
|
||||
void onMount() {
|
||||
super.onMount();
|
||||
passthroughParent = ancestors().firstWhereOrNull(
|
||||
passthroughParent =
|
||||
ancestors().firstWhereOrNull(
|
||||
(c) => c is CollisionCallbacks,
|
||||
) as CollisionCallbacks?;
|
||||
)
|
||||
as CollisionCallbacks?;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -108,8 +108,8 @@ class CircleHitbox extends CircleComponent with ShapeHitbox {
|
||||
..setFrom(ray.direction)
|
||||
..reflect(_temporaryNormal);
|
||||
|
||||
final reflectionRay = (out?.reflectionRay
|
||||
?..setWith(
|
||||
final reflectionRay =
|
||||
(out?.reflectionRay?..setWith(
|
||||
origin: intersectionPoint,
|
||||
direction: reflectionDirection,
|
||||
)) ??
|
||||
|
||||
@ -78,19 +78,24 @@ mixin ShapeHitbox on ShapeComponent implements Hitbox<ShapeHitbox> {
|
||||
@override
|
||||
void onMount() {
|
||||
super.onMount();
|
||||
_hitboxParent = ancestors().firstWhere(
|
||||
_hitboxParent =
|
||||
ancestors().firstWhere(
|
||||
(c) => c is PositionComponent && c is! CompositeHitbox,
|
||||
orElse: () {
|
||||
throw StateError('A ShapeHitbox needs a PositionComponent ancestor');
|
||||
throw StateError(
|
||||
'A ShapeHitbox needs a PositionComponent ancestor',
|
||||
);
|
||||
},
|
||||
) as PositionComponent;
|
||||
)
|
||||
as PositionComponent;
|
||||
|
||||
_transformListener = () {
|
||||
_validAabb = false;
|
||||
onAabbChanged?.call();
|
||||
};
|
||||
final positionComponents =
|
||||
ancestors(includeSelf: true).whereType<PositionComponent>();
|
||||
final positionComponents = ancestors(
|
||||
includeSelf: true,
|
||||
).whereType<PositionComponent>();
|
||||
for (final ancestor in positionComponents) {
|
||||
_transformAncestors.add(ancestor.transform);
|
||||
ancestor.transform.addListener(_transformListener);
|
||||
@ -241,14 +246,17 @@ mixin ShapeHitbox on ShapeComponent implements Hitbox<ShapeHitbox> {
|
||||
bool onComponentTypeCheck(PositionComponent other) {
|
||||
final otherHitboxParent = (other as ShapeHitbox).hitboxParent;
|
||||
|
||||
final thisCanCollideWithOther = (hitboxParent is! CollisionCallbacks) ||
|
||||
(hitboxParent as CollisionCallbacks)
|
||||
.onComponentTypeCheck(otherHitboxParent);
|
||||
final thisCanCollideWithOther =
|
||||
(hitboxParent is! CollisionCallbacks) ||
|
||||
(hitboxParent as CollisionCallbacks).onComponentTypeCheck(
|
||||
otherHitboxParent,
|
||||
);
|
||||
|
||||
final otherCanCollideWithThis =
|
||||
(otherHitboxParent is! CollisionCallbacks) ||
|
||||
(otherHitboxParent as CollisionCallbacks)
|
||||
.onComponentTypeCheck(hitboxParent);
|
||||
(otherHitboxParent as CollisionCallbacks).onComponentTypeCheck(
|
||||
hitboxParent,
|
||||
);
|
||||
|
||||
return thisCanCollideWithOther && otherCanCollideWithThis;
|
||||
}
|
||||
@ -262,5 +270,5 @@ mixin ShapeHitbox on ShapeComponent implements Hitbox<ShapeHitbox> {
|
||||
@override
|
||||
CollisionEndCallback<ShapeHitbox>? onCollisionEndCallback;
|
||||
|
||||
//#endregion
|
||||
//#endregion
|
||||
}
|
||||
|
||||
@ -90,8 +90,10 @@ class StandardCollisionDetection<B extends Broadphase<ShapeHitbox>>
|
||||
if (!item.aabb.intersectsWithAabb2(_temporaryRayAabb)) {
|
||||
continue;
|
||||
}
|
||||
final currentResult =
|
||||
item.rayIntersection(ray, out: _temporaryRaycastResult);
|
||||
final currentResult = item.rayIntersection(
|
||||
ray,
|
||||
out: _temporaryRaycastResult,
|
||||
);
|
||||
final possiblyFirstResult = !(finalResult?.isActive ?? false);
|
||||
if (currentResult != null &&
|
||||
(possiblyFirstResult ||
|
||||
@ -175,8 +177,9 @@ class StandardCollisionDetection<B extends Broadphase<ShapeHitbox>>
|
||||
var currentRay = ray;
|
||||
for (var i = 0; i < maxDepth; i++) {
|
||||
final hasResultObject = (out?.length ?? 0) > i;
|
||||
final storeResult =
|
||||
hasResultObject ? out![i] : RaycastResult<ShapeHitbox>();
|
||||
final storeResult = hasResultObject
|
||||
? out![i]
|
||||
: RaycastResult<ShapeHitbox>();
|
||||
final currentResult = raycast(
|
||||
currentRay,
|
||||
hitboxFilter: hitboxFilter,
|
||||
|
||||
@ -419,9 +419,10 @@ class Component {
|
||||
bool Function(T) handler, {
|
||||
bool includeSelf = false,
|
||||
}) {
|
||||
return descendants(reversed: true, includeSelf: includeSelf)
|
||||
.whereType<T>()
|
||||
.every(handler);
|
||||
return descendants(
|
||||
reversed: true,
|
||||
includeSelf: includeSelf,
|
||||
).whereType<T>().every(handler);
|
||||
}
|
||||
|
||||
@internal
|
||||
@ -1138,7 +1139,8 @@ class Component {
|
||||
if (!_debugPaintCache.isCacheValid([debugColor])) {
|
||||
final paint = Paint()
|
||||
..color = debugColor
|
||||
..strokeWidth = 0 // hairline-width
|
||||
..strokeWidth =
|
||||
0 // hairline-width
|
||||
..style = PaintingStyle.stroke;
|
||||
_debugPaintCache.updateCache(paint, [debugColor]);
|
||||
}
|
||||
|
||||
@ -57,7 +57,8 @@ class HudMarginComponent extends PositionComponent {
|
||||
Anchor.topLeft,
|
||||
scaledSize,
|
||||
);
|
||||
final bottomRight = sizeProvider.size -
|
||||
final bottomRight =
|
||||
sizeProvider.size -
|
||||
anchor.toOtherAnchorPosition(
|
||||
position,
|
||||
Anchor.bottomRight,
|
||||
|
||||
@ -147,8 +147,7 @@ class IsometricTileMapComponent extends PositionComponent {
|
||||
/// This is the opposite of [getBlock].
|
||||
Vector2 getBlockCenterPosition(Block block) {
|
||||
final tile = effectiveTileSize;
|
||||
return getBlockRenderPosition(block)
|
||||
..translate(
|
||||
return getBlockRenderPosition(block)..translate(
|
||||
(tile.x / 2) * scale.x,
|
||||
(tile.y - effectiveTileHeight - tile.y / 4) * scale.y,
|
||||
);
|
||||
|
||||
@ -44,7 +44,8 @@ mixin ComponentViewportMargin<T extends FlameGame>
|
||||
Anchor.topLeft,
|
||||
scaledSize,
|
||||
);
|
||||
final bottomRight = bounds -
|
||||
final bottomRight =
|
||||
bounds -
|
||||
anchor.toOtherAnchorPosition(
|
||||
position,
|
||||
Anchor.bottomRight,
|
||||
|
||||
@ -230,9 +230,9 @@ class _MultiPaintOpacityProvider<T extends Object> implements OpacityProvider {
|
||||
if (includeLayers) {
|
||||
final paintLayersInternal = target.paintLayersInternal;
|
||||
for (var i = 0; i < (paintLayersInternal?.length ?? 0); ++i) {
|
||||
paintLayersInternal![i].color = paintLayersInternal[i]
|
||||
.color
|
||||
.withValues(alpha: value * _layerOpacityRatios![i]);
|
||||
paintLayersInternal![i].color = paintLayersInternal[i].color.withValues(
|
||||
alpha: value * _layerOpacityRatios![i],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,8 +21,10 @@ mixin HasWorldReference<T extends World> on Component {
|
||||
set world(T? value) => _world = value;
|
||||
|
||||
T? findWorld() {
|
||||
return ancestors(includeSelf: true)
|
||||
.firstWhereOrNull((ancestor) => ancestor is T) as T?;
|
||||
return ancestors(
|
||||
includeSelf: true,
|
||||
).firstWhereOrNull((ancestor) => ancestor is T)
|
||||
as T?;
|
||||
}
|
||||
|
||||
T _findWorldAndCheck() {
|
||||
|
||||
@ -417,14 +417,16 @@ class PositionComponent extends Component
|
||||
);
|
||||
final angleDifference = targetAngle - absoluteAngle - nativeAngle;
|
||||
|
||||
final hasOddFlips = parentAbsoluteScale.x.isNegative ^
|
||||
final hasOddFlips =
|
||||
parentAbsoluteScale.x.isNegative ^
|
||||
parentAbsoluteScale.y.isNegative ^
|
||||
scale.x.isNegative ^
|
||||
scale.y.isNegative;
|
||||
final hasSelfYFlip =
|
||||
!parentAbsoluteScale.y.isNegative && scale.y.isNegative;
|
||||
|
||||
final result = (hasOddFlips ? -1 : 1) * angleDifference +
|
||||
final result =
|
||||
(hasOddFlips ? -1 : 1) * angleDifference +
|
||||
(hasSelfYFlip ? 1 : 0) * math.pi;
|
||||
return result.toNormalizedAngle();
|
||||
}
|
||||
|
||||
@ -70,7 +70,8 @@ class SpawnComponent extends Component {
|
||||
!(selfPositioning && area != null),
|
||||
"Don't set an area when you are using selfPositioning=true",
|
||||
),
|
||||
_period = minPeriod +
|
||||
_period =
|
||||
minPeriod +
|
||||
(random ?? randomFallback).nextDouble() * (maxPeriod - minPeriod),
|
||||
multiFactory = multiFactory ?? _wrapFactory(factory!),
|
||||
_random = random ?? randomFallback;
|
||||
@ -183,7 +184,8 @@ class SpawnComponent extends Component {
|
||||
} else {
|
||||
maybeProvidedPosition = null;
|
||||
}
|
||||
final targetPosition = maybeProvidedPosition ??
|
||||
final targetPosition =
|
||||
maybeProvidedPosition ??
|
||||
ancestors().whereType<PositionProvider>().firstOrNull?.position ??
|
||||
Vector2.zero();
|
||||
|
||||
@ -198,7 +200,8 @@ class SpawnComponent extends Component {
|
||||
} else {
|
||||
maybeProvidedSize = null;
|
||||
}
|
||||
final targetSize = maybeProvidedSize ??
|
||||
final targetSize =
|
||||
maybeProvidedSize ??
|
||||
ancestors().whereType<ReadOnlySizeProvider>().firstOrNull?.size ??
|
||||
Vector2.zero();
|
||||
assert(
|
||||
|
||||
@ -85,8 +85,9 @@ class TextBoxComponent<T extends TextRenderer> extends TextComponent {
|
||||
|
||||
// Notifies when a new line is rendered with the position of the new line.
|
||||
@internal
|
||||
final ValueNotifier<double> newLinePositionNotifier =
|
||||
ValueNotifier<double>(0);
|
||||
final ValueNotifier<double> newLinePositionNotifier = ValueNotifier<double>(
|
||||
0,
|
||||
);
|
||||
|
||||
double _currentLinePosition = 0.0;
|
||||
bool _isOnCompleteExecuted = false;
|
||||
@ -114,7 +115,8 @@ class TextBoxComponent<T extends TextRenderer> extends TextComponent {
|
||||
}) : boxConfig = boxConfig ?? const TextBoxConfig(),
|
||||
_fixedSize = size != null,
|
||||
align = align ?? Anchor.topLeft,
|
||||
pixelRatio = pixelRatio ??
|
||||
pixelRatio =
|
||||
pixelRatio ??
|
||||
PlatformDispatcher.instance.views.first.devicePixelRatio;
|
||||
|
||||
/// Alignment of the text within its bounding box.
|
||||
@ -169,8 +171,9 @@ class TextBoxComponent<T extends TextRenderer> extends TextComponent {
|
||||
final maxBoxWidth = _fixedSize ? width : boxConfig.maxWidth;
|
||||
for (final word in text.split(' ')) {
|
||||
final wordLines = word.split('\n');
|
||||
final possibleLine =
|
||||
lines.isEmpty ? wordLines[0] : '${lines.last} ${wordLines[0]}';
|
||||
final possibleLine = lines.isEmpty
|
||||
? wordLines[0]
|
||||
: '${lines.last} ${wordLines[0]}';
|
||||
final metrics = textRenderer.getLineMetrics(possibleLine);
|
||||
lineHeight = max(lineHeight, metrics.height);
|
||||
|
||||
@ -244,14 +247,17 @@ class TextBoxComponent<T extends TextRenderer> extends TextComponent {
|
||||
var totalCharCount = 0;
|
||||
final cachedCurrentChar = currentChar;
|
||||
final cachedCurrentLine = currentLine;
|
||||
final textWidth = lines.sublist(0, cachedCurrentLine + 1).map((line) {
|
||||
final textWidth = lines
|
||||
.sublist(0, cachedCurrentLine + 1)
|
||||
.map((line) {
|
||||
final charCount = (i < cachedCurrentLine)
|
||||
? line.length
|
||||
: (cachedCurrentChar - totalCharCount);
|
||||
totalCharCount += line.length;
|
||||
i++;
|
||||
return getLineWidth(line, charCount);
|
||||
}).reduce(math.max);
|
||||
})
|
||||
.reduce(math.max);
|
||||
return Vector2(
|
||||
textWidth + boxConfig.margins.horizontal,
|
||||
_lineHeight * lines.length + boxConfig.margins.vertical,
|
||||
|
||||
@ -32,8 +32,7 @@ abstract class AnchorEffect extends Effect
|
||||
AnchorProvider? target,
|
||||
void Function()? onComplete,
|
||||
ComponentKey? key,
|
||||
}) =>
|
||||
AnchorByEffect(
|
||||
}) => AnchorByEffect(
|
||||
offset,
|
||||
controller,
|
||||
target: target,
|
||||
@ -47,8 +46,7 @@ abstract class AnchorEffect extends Effect
|
||||
AnchorProvider? target,
|
||||
void Function()? onComplete,
|
||||
ComponentKey? key,
|
||||
}) =>
|
||||
AnchorToEffect(
|
||||
}) => AnchorToEffect(
|
||||
destination,
|
||||
controller,
|
||||
target: target,
|
||||
|
||||
@ -176,7 +176,8 @@ abstract class EffectController {
|
||||
if (hasReverse) {
|
||||
final reverseIsLinear =
|
||||
reverseCurve == Curves.linear || ((reverseCurve == null) && isLinear);
|
||||
final reverseHasDuration = (reverseDuration != null) ||
|
||||
final reverseHasDuration =
|
||||
(reverseDuration != null) ||
|
||||
(reverseSpeed == null && duration != null);
|
||||
if (reverseIsLinear) {
|
||||
items.add(
|
||||
@ -214,8 +215,9 @@ abstract class EffectController {
|
||||
}
|
||||
|
||||
assert(items.isNotEmpty);
|
||||
var controller =
|
||||
items.length == 1 ? items[0] : SequenceEffectController(items);
|
||||
var controller = items.length == 1
|
||||
? items[0]
|
||||
: SequenceEffectController(items);
|
||||
if (infinite) {
|
||||
controller = InfiniteEffectController(controller);
|
||||
}
|
||||
|
||||
@ -213,5 +213,5 @@ abstract class Effect extends Component {
|
||||
/// This is a main method that MUST be implemented in every derived class.
|
||||
void apply(double progress);
|
||||
|
||||
//#endregion
|
||||
//#endregion
|
||||
}
|
||||
|
||||
@ -32,8 +32,7 @@ abstract class MoveEffect extends Effect
|
||||
PositionProvider? target,
|
||||
void Function()? onComplete,
|
||||
ComponentKey? key,
|
||||
}) =>
|
||||
MoveByEffect(
|
||||
}) => MoveByEffect(
|
||||
offset,
|
||||
controller,
|
||||
target: target,
|
||||
@ -47,8 +46,7 @@ abstract class MoveEffect extends Effect
|
||||
PositionProvider? target,
|
||||
void Function()? onComplete,
|
||||
ComponentKey? key,
|
||||
}) =>
|
||||
MoveToEffect(
|
||||
}) => MoveToEffect(
|
||||
destination,
|
||||
controller,
|
||||
target: target,
|
||||
|
||||
@ -28,8 +28,7 @@ class ScaleEffect extends Effect with EffectTarget<ScaleProvider> {
|
||||
EffectController controller, {
|
||||
void Function()? onComplete,
|
||||
ComponentKey? key,
|
||||
}) =>
|
||||
_ScaleToEffect(
|
||||
}) => _ScaleToEffect(
|
||||
targetScale,
|
||||
controller,
|
||||
onComplete: onComplete,
|
||||
|
||||
@ -37,8 +37,7 @@ class SizeEffect extends Effect with EffectTarget<SizeProvider> {
|
||||
EffectController controller, {
|
||||
void Function()? onComplete,
|
||||
ComponentKey? key,
|
||||
}) =>
|
||||
_SizeToEffect(
|
||||
}) => _SizeToEffect(
|
||||
targetSize,
|
||||
controller,
|
||||
onComplete: onComplete,
|
||||
|
||||
@ -52,10 +52,10 @@ class DoubleTapDispatcher extends Component with HasGameReference<FlameGame> {
|
||||
game.gestureDetectors.add(
|
||||
DoubleTapGestureRecognizer.new,
|
||||
(DoubleTapGestureRecognizer instance) {
|
||||
instance.onDoubleTapDown =
|
||||
(details) => _onDoubleTapDown(DoubleTapDownEvent(game, details));
|
||||
instance.onDoubleTapCancel =
|
||||
() => _onDoubleTapCancel(DoubleTapCancelEvent());
|
||||
instance.onDoubleTapDown = (details) =>
|
||||
_onDoubleTapDown(DoubleTapDownEvent(game, details));
|
||||
instance.onDoubleTapCancel = () =>
|
||||
_onDoubleTapCancel(DoubleTapCancelEvent());
|
||||
instance.onDoubleTap = () => _onDoubleTapUp(DoubleTapEvent());
|
||||
},
|
||||
);
|
||||
|
||||
@ -6,10 +6,7 @@ import 'package:flame/src/game/game.dart';
|
||||
///
|
||||
/// This represents a user event that has a start and end locations, as the
|
||||
/// ones that are represented by a [DisplacementEvent].
|
||||
typedef DisplacementContext = ({
|
||||
Vector2 start,
|
||||
Vector2 end,
|
||||
});
|
||||
typedef DisplacementContext = ({Vector2 start, Vector2 end});
|
||||
|
||||
extension DisplacementContextDelta on DisplacementContext {
|
||||
/// Displacement delta
|
||||
@ -44,8 +41,9 @@ abstract class DisplacementEvent
|
||||
/// relative to the game canvas.
|
||||
///
|
||||
/// This could be considered the Flame-level global position.
|
||||
late final Vector2 canvasStartPosition =
|
||||
_game.convertGlobalToLocalCoordinate(deviceStartPosition);
|
||||
late final Vector2 canvasStartPosition = _game.convertGlobalToLocalCoordinate(
|
||||
deviceStartPosition,
|
||||
);
|
||||
|
||||
/// Event start position in the local coordinate space of the current
|
||||
/// component.
|
||||
@ -67,8 +65,9 @@ abstract class DisplacementEvent
|
||||
/// relative to the game canvas.
|
||||
///
|
||||
/// This could be considered the Flame-level global position.
|
||||
late final Vector2 canvasEndPosition =
|
||||
_game.convertGlobalToLocalCoordinate(deviceEndPosition);
|
||||
late final Vector2 canvasEndPosition = _game.convertGlobalToLocalCoordinate(
|
||||
deviceEndPosition,
|
||||
);
|
||||
|
||||
/// Event end position in the local coordinate space of the current
|
||||
/// component.
|
||||
|
||||
@ -25,7 +25,8 @@ class DragStartEvent extends PositionEvent {
|
||||
final PointerDeviceKind deviceKind;
|
||||
|
||||
@override
|
||||
String toString() => 'DragStartEvent(canvasPosition: $canvasPosition, '
|
||||
String toString() =>
|
||||
'DragStartEvent(canvasPosition: $canvasPosition, '
|
||||
'devicePosition: $devicePosition, '
|
||||
'pointedId: $pointerId, deviceKind: $deviceKind)';
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user