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:
|
env:
|
||||||
FLUTTER_MIN_VERSION: '3.27.1'
|
FLUTTER_MIN_VERSION: '3.32.0'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# BEGIN LINTING STAGE
|
# BEGIN LINTING STAGE
|
||||||
|
|||||||
@ -36,11 +36,11 @@ class RectangleCollidable extends PositionComponent with CollisionCallbacks {
|
|||||||
late ShapeHitbox hitbox;
|
late ShapeHitbox hitbox;
|
||||||
|
|
||||||
RectangleCollidable(Vector2 position)
|
RectangleCollidable(Vector2 position)
|
||||||
: super(
|
: super(
|
||||||
position: position,
|
position: position,
|
||||||
size: Vector2.all(50),
|
size: Vector2.all(50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -101,11 +101,15 @@ class DragTarget extends PositionComponent with DragCallbacks {
|
|||||||
|
|
||||||
class Trail extends Component {
|
class Trail extends Component {
|
||||||
Trail(Vector2 origin)
|
Trail(Vector2 origin)
|
||||||
: _paths = [Path()..moveTo(origin.x, origin.y)],
|
: _paths = [Path()..moveTo(origin.x, origin.y)],
|
||||||
_opacities = [1],
|
_opacities = [1],
|
||||||
_lastPoint = origin.clone(),
|
_lastPoint = origin.clone(),
|
||||||
_color =
|
_color = HSLColor.fromAHSL(
|
||||||
HSLColor.fromAHSL(1, random.nextDouble() * 360, 1, 0.8).toColor();
|
1,
|
||||||
|
random.nextDouble() * 360,
|
||||||
|
1,
|
||||||
|
0.8,
|
||||||
|
).toColor();
|
||||||
|
|
||||||
final List<Path> _paths;
|
final List<Path> _paths;
|
||||||
final List<double> _opacities;
|
final List<double> _opacities;
|
||||||
|
|||||||
@ -8,8 +8,8 @@ class EmberPlayer extends SpriteAnimationComponent with TapCallbacks {
|
|||||||
required super.size,
|
required super.size,
|
||||||
super.position,
|
super.position,
|
||||||
void Function(EmberPlayer player)? onTap,
|
void Function(EmberPlayer player)? onTap,
|
||||||
}) : _onTap = onTap,
|
}) : _onTap = onTap,
|
||||||
super();
|
super();
|
||||||
|
|
||||||
Vector2 velocity = Vector2(0, 0);
|
Vector2 velocity = Vector2(0, 0);
|
||||||
final void Function(EmberPlayer player)? _onTap;
|
final void Function(EmberPlayer player)? _onTap;
|
||||||
|
|||||||
@ -14,8 +14,8 @@ class Flower extends PositionComponent
|
|||||||
void Function(Flower)? onTap,
|
void Function(Flower)? onTap,
|
||||||
Decorator? decorator,
|
Decorator? decorator,
|
||||||
super.position,
|
super.position,
|
||||||
}) : _onTap = onTap,
|
}) : _onTap = onTap,
|
||||||
super(size: Vector2.all(size), anchor: Anchor.center) {
|
super(size: Vector2.all(size), anchor: Anchor.center) {
|
||||||
this.decorator.addLast(decorator);
|
this.decorator.addLast(decorator);
|
||||||
final radius = size * 0.38;
|
final radius = size * 0.38;
|
||||||
_paths.add(_makePath(radius * 1.4, 6, -0.05, 0.8));
|
_paths.add(_makePath(radius * 1.4, 6, -0.05, 0.8));
|
||||||
|
|||||||
@ -16,14 +16,14 @@ class GlowEffectExample extends FlameGame {
|
|||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
paint: paint,
|
paint: paint,
|
||||||
)..add(
|
)..add(
|
||||||
GlowEffect(
|
GlowEffect(
|
||||||
10.0,
|
10.0,
|
||||||
EffectController(
|
EffectController(
|
||||||
duration: 2,
|
duration: 2,
|
||||||
infinite: true,
|
infinite: true,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,16 +23,19 @@ class HoverTarget extends PositionComponent with HoverCallbacks {
|
|||||||
static final Random _random = Random();
|
static final Random _random = Random();
|
||||||
|
|
||||||
HoverTarget(Vector2 position)
|
HoverTarget(Vector2 position)
|
||||||
: super(
|
: super(
|
||||||
position: position,
|
position: position,
|
||||||
size: Vector2.all(50),
|
size: Vector2.all(50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
final _paint = Paint()
|
final _paint = Paint()
|
||||||
..color = HSLColor.fromAHSL(1, _random.nextDouble() * 360, 1, 0.8)
|
..color = HSLColor.fromAHSL(
|
||||||
.toColor()
|
1,
|
||||||
.withValues(alpha: 0.5);
|
_random.nextDouble() * 360,
|
||||||
|
1,
|
||||||
|
0.8,
|
||||||
|
).toColor().withValues(alpha: 0.5);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void render(Canvas canvas) {
|
void render(Canvas canvas) {
|
||||||
|
|||||||
@ -33,8 +33,8 @@ class RemoveEffectGame extends FlameGame with TapDetector {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void update(double dt) {
|
void update(double dt) {
|
||||||
textComponent.text =
|
textComponent.text = (effect.controller.progress * delayTime)
|
||||||
(effect.controller.progress * delayTime).toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
super.update(dt);
|
super.update(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,8 +9,9 @@ class RiveExampleGame extends FlameGame with TapDetector {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
final skillsArtboard =
|
final skillsArtboard = await loadArtboard(
|
||||||
await loadArtboard(RiveFile.asset('assets/skills.riv'));
|
RiveFile.asset('assets/skills.riv'),
|
||||||
|
);
|
||||||
|
|
||||||
final controller = StateMachineController.fromArtboard(
|
final controller = StateMachineController.fromArtboard(
|
||||||
skillsArtboard,
|
skillsArtboard,
|
||||||
|
|||||||
@ -86,12 +86,12 @@ class RoundedButton extends PositionComponent with TapCallbacks {
|
|||||||
super.position,
|
super.position,
|
||||||
super.anchor = Anchor.center,
|
super.anchor = Anchor.center,
|
||||||
}) : _textDrawable = TextPaint(
|
}) : _textDrawable = TextPaint(
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Color(0xFF000000),
|
color: Color(0xFF000000),
|
||||||
fontWeight: FontWeight.w800,
|
fontWeight: FontWeight.w800,
|
||||||
),
|
),
|
||||||
).toTextPainter(text) {
|
).toTextPainter(text) {
|
||||||
size = Vector2(150, 40);
|
size = Vector2(150, 40);
|
||||||
_textOffset = Offset(
|
_textOffset = Offset(
|
||||||
(size.x - _textDrawable.width) / 2,
|
(size.x - _textDrawable.width) / 2,
|
||||||
@ -179,15 +179,15 @@ abstract class SimpleButton extends PositionComponent with TapCallbacks {
|
|||||||
|
|
||||||
class BackButton extends SimpleButton with HasGameReference<RouterGame> {
|
class BackButton extends SimpleButton with HasGameReference<RouterGame> {
|
||||||
BackButton()
|
BackButton()
|
||||||
: super(
|
: super(
|
||||||
Path()
|
Path()
|
||||||
..moveTo(22, 8)
|
..moveTo(22, 8)
|
||||||
..lineTo(10, 20)
|
..lineTo(10, 20)
|
||||||
..lineTo(22, 32)
|
..lineTo(22, 32)
|
||||||
..moveTo(12, 20)
|
..moveTo(12, 20)
|
||||||
..lineTo(34, 20),
|
..lineTo(34, 20),
|
||||||
position: Vector2.all(10),
|
position: Vector2.all(10),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void action() => game.router.pop();
|
void action() => game.router.pop();
|
||||||
@ -195,14 +195,14 @@ class BackButton extends SimpleButton with HasGameReference<RouterGame> {
|
|||||||
|
|
||||||
class PauseButton extends SimpleButton with HasGameReference<RouterGame> {
|
class PauseButton extends SimpleButton with HasGameReference<RouterGame> {
|
||||||
PauseButton()
|
PauseButton()
|
||||||
: super(
|
: super(
|
||||||
Path()
|
Path()
|
||||||
..moveTo(14, 10)
|
..moveTo(14, 10)
|
||||||
..lineTo(14, 30)
|
..lineTo(14, 30)
|
||||||
..moveTo(26, 10)
|
..moveTo(26, 10)
|
||||||
..lineTo(26, 30),
|
..lineTo(26, 30),
|
||||||
position: Vector2(60, 10),
|
position: Vector2(60, 10),
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isPaused = false;
|
bool isPaused = false;
|
||||||
|
|
||||||
@ -345,10 +345,10 @@ class Orbit extends PositionComponent {
|
|||||||
required this.planet,
|
required this.planet,
|
||||||
required this.revolutionPeriod,
|
required this.revolutionPeriod,
|
||||||
double initialAngle = 0,
|
double initialAngle = 0,
|
||||||
}) : _paint = Paint()
|
}) : _paint = Paint()
|
||||||
..style = PaintingStyle.stroke
|
..style = PaintingStyle.stroke
|
||||||
..color = const Color(0x888888aa),
|
..color = const Color(0x888888aa),
|
||||||
_angle = initialAngle {
|
_angle = initialAngle {
|
||||||
add(planet);
|
add(planet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -63,8 +63,12 @@ class TapTarget extends PositionComponent with TapCallbacks {
|
|||||||
|
|
||||||
class ExpandingCircle extends Component {
|
class ExpandingCircle extends Component {
|
||||||
ExpandingCircle(this._center)
|
ExpandingCircle(this._center)
|
||||||
: _baseColor =
|
: _baseColor = HSLColor.fromAHSL(
|
||||||
HSLColor.fromAHSL(1, random.nextDouble() * 360, 1, 0.8).toColor();
|
1,
|
||||||
|
random.nextDouble() * 360,
|
||||||
|
1,
|
||||||
|
0.8,
|
||||||
|
).toColor();
|
||||||
|
|
||||||
final Color _baseColor;
|
final Color _baseColor;
|
||||||
final Vector2 _center;
|
final Vector2 _center;
|
||||||
|
|||||||
@ -83,15 +83,15 @@ class RateRoute extends ValueRoute<int>
|
|||||||
|
|
||||||
class DialogBackground extends RectangleComponent with TapCallbacks {
|
class DialogBackground extends RectangleComponent with TapCallbacks {
|
||||||
DialogBackground({super.position, super.size, super.children})
|
DialogBackground({super.position, super.size, super.children})
|
||||||
: super(
|
: super(
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
paint: Paint()..color = const Color(0xee858585),
|
paint: Paint()..color = const Color(0xee858585),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Star extends PositionComponent with TapCallbacks {
|
class Star extends PositionComponent with TapCallbacks {
|
||||||
Star({required this.value, required this.radius, super.position})
|
Star({required this.value, required this.radius, super.position})
|
||||||
: super(size: Vector2.all(2 * radius), anchor: Anchor.center);
|
: super(size: Vector2.all(2 * radius), anchor: Anchor.center);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final double radius;
|
final double radius;
|
||||||
|
|||||||
@ -5,7 +5,7 @@ version: 1.0.0
|
|||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
flutter: ">=3.27.1"
|
flutter: ">=3.27.1"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -17,10 +17,10 @@ void main() {
|
|||||||
'step4' => step4.main(),
|
'step4' => step4.main(),
|
||||||
'step5' => step5.main(),
|
'step5' => step5.main(),
|
||||||
_ => runApp(
|
_ => runApp(
|
||||||
Directionality(
|
Directionality(
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
child: Text('Error=> unknown page name "$page"'),
|
child: Text('Error=> unknown page name "$page"'),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,10 @@ class KlondikeGame extends FlameGame {
|
|||||||
4,
|
4,
|
||||||
(i) => Foundation()
|
(i) => Foundation()
|
||||||
..size = cardSize
|
..size = cardSize
|
||||||
..position =
|
..position = Vector2(
|
||||||
Vector2((i + 3) * (cardWidth + cardGap) + cardGap, cardGap),
|
(i + 3) * (cardWidth + cardGap) + cardGap,
|
||||||
|
cardGap,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final piles = List.generate(
|
final piles = List.generate(
|
||||||
7,
|
7,
|
||||||
@ -46,8 +48,10 @@ class KlondikeGame extends FlameGame {
|
|||||||
world.addAll(foundations);
|
world.addAll(foundations);
|
||||||
world.addAll(piles);
|
world.addAll(piles);
|
||||||
|
|
||||||
camera.viewfinder.visibleGameSize =
|
camera.viewfinder.visibleGameSize = Vector2(
|
||||||
Vector2(cardWidth * 7 + cardGap * 8, 4 * cardHeight + 3 * cardGap);
|
cardWidth * 7 + cardGap * 8,
|
||||||
|
4 * cardHeight + 3 * cardGap,
|
||||||
|
);
|
||||||
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
||||||
camera.viewfinder.anchor = Anchor.topCenter;
|
camera.viewfinder.anchor = Anchor.topCenter;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,10 +8,10 @@ import '../suit.dart';
|
|||||||
|
|
||||||
class Card extends PositionComponent {
|
class Card extends PositionComponent {
|
||||||
Card(int intRank, int intSuit)
|
Card(int intRank, int intSuit)
|
||||||
: rank = Rank.fromInt(intRank),
|
: rank = Rank.fromInt(intRank),
|
||||||
suit = Suit.fromInt(intSuit),
|
suit = Suit.fromInt(intSuit),
|
||||||
_faceUp = false,
|
_faceUp = false,
|
||||||
super(size: KlondikeGame.cardSize);
|
super(size: KlondikeGame.cardSize);
|
||||||
|
|
||||||
final Rank rank;
|
final Rank rank;
|
||||||
final Suit suit;
|
final Suit suit;
|
||||||
|
|||||||
@ -31,8 +31,10 @@ class KlondikeGame extends FlameGame {
|
|||||||
4,
|
4,
|
||||||
(i) => Foundation()
|
(i) => Foundation()
|
||||||
..size = cardSize
|
..size = cardSize
|
||||||
..position =
|
..position = Vector2(
|
||||||
Vector2((i + 3) * (cardWidth + cardGap) + cardGap, cardGap),
|
(i + 3) * (cardWidth + cardGap) + cardGap,
|
||||||
|
cardGap,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final piles = List.generate(
|
final piles = List.generate(
|
||||||
7,
|
7,
|
||||||
@ -49,8 +51,10 @@ class KlondikeGame extends FlameGame {
|
|||||||
world.addAll(foundations);
|
world.addAll(foundations);
|
||||||
world.addAll(piles);
|
world.addAll(piles);
|
||||||
|
|
||||||
camera.viewfinder.visibleGameSize =
|
camera.viewfinder.visibleGameSize = Vector2(
|
||||||
Vector2(cardWidth * 7 + cardGap * 8, 4 * cardHeight + 3 * cardGap);
|
cardWidth * 7 + cardGap * 8,
|
||||||
|
4 * cardHeight + 3 * cardGap,
|
||||||
|
);
|
||||||
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
||||||
camera.viewfinder.anchor = Anchor.topCenter;
|
camera.viewfinder.anchor = Anchor.topCenter;
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@ class Rank {
|
|||||||
double y2,
|
double y2,
|
||||||
double w,
|
double w,
|
||||||
double h,
|
double h,
|
||||||
) : redSprite = klondikeSprite(x1, y1, w, h),
|
) : redSprite = klondikeSprite(x1, y1, w, h),
|
||||||
blackSprite = klondikeSprite(x2, y2, w, h);
|
blackSprite = klondikeSprite(x2, y2, w, h);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class Suit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Suit._(this.value, this.label, double x, double y, double w, double h)
|
Suit._(this.value, this.label, double x, double y, double w, double h)
|
||||||
: sprite = klondikeSprite(x, y, w, h);
|
: sprite = klondikeSprite(x, y, w, h);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -11,9 +11,9 @@ import 'tableau_pile.dart';
|
|||||||
|
|
||||||
class Card extends PositionComponent with DragCallbacks {
|
class Card extends PositionComponent with DragCallbacks {
|
||||||
Card(int intRank, int intSuit)
|
Card(int intRank, int intSuit)
|
||||||
: rank = Rank.fromInt(intRank),
|
: rank = Rank.fromInt(intRank),
|
||||||
suit = Suit.fromInt(intSuit),
|
suit = Suit.fromInt(intSuit),
|
||||||
super(size: KlondikeGame.cardSize);
|
super(size: KlondikeGame.cardSize);
|
||||||
|
|
||||||
final Rank rank;
|
final Rank rank;
|
||||||
final Suit suit;
|
final Suit suit;
|
||||||
|
|||||||
@ -9,8 +9,8 @@ import 'card.dart';
|
|||||||
|
|
||||||
class FoundationPile extends PositionComponent implements Pile {
|
class FoundationPile extends PositionComponent implements Pile {
|
||||||
FoundationPile(int intSuit, {super.position})
|
FoundationPile(int intSuit, {super.position})
|
||||||
: suit = Suit.fromInt(intSuit),
|
: suit = Suit.fromInt(intSuit),
|
||||||
super(size: KlondikeGame.cardSize);
|
super(size: KlondikeGame.cardSize);
|
||||||
|
|
||||||
final Suit suit;
|
final Suit suit;
|
||||||
final List<Card> _cards = [];
|
final List<Card> _cards = [];
|
||||||
|
|||||||
@ -26,8 +26,9 @@ class KlondikeGame extends FlameGame {
|
|||||||
await Flame.images.load('klondike-sprites.png');
|
await Flame.images.load('klondike-sprites.png');
|
||||||
|
|
||||||
final stock = StockPile(position: Vector2(cardGap, cardGap));
|
final stock = StockPile(position: Vector2(cardGap, cardGap));
|
||||||
final waste =
|
final waste = WastePile(
|
||||||
WastePile(position: Vector2(cardWidth + 2 * cardGap, cardGap));
|
position: Vector2(cardWidth + 2 * cardGap, cardGap),
|
||||||
|
);
|
||||||
final foundations = List.generate(
|
final foundations = List.generate(
|
||||||
4,
|
4,
|
||||||
(i) => FoundationPile(
|
(i) => FoundationPile(
|
||||||
@ -50,8 +51,10 @@ class KlondikeGame extends FlameGame {
|
|||||||
world.addAll(foundations);
|
world.addAll(foundations);
|
||||||
world.addAll(piles);
|
world.addAll(piles);
|
||||||
|
|
||||||
camera.viewfinder.visibleGameSize =
|
camera.viewfinder.visibleGameSize = Vector2(
|
||||||
Vector2(cardWidth * 7 + cardGap * 8, 4 * cardHeight + 3 * cardGap);
|
cardWidth * 7 + cardGap * 8,
|
||||||
|
4 * cardHeight + 3 * cardGap,
|
||||||
|
);
|
||||||
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
camera.viewfinder.position = Vector2(cardWidth * 3.5 + cardGap * 4, 0);
|
||||||
camera.viewfinder.anchor = Anchor.topCenter;
|
camera.viewfinder.anchor = Anchor.topCenter;
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@ class Rank {
|
|||||||
double y2,
|
double y2,
|
||||||
double w,
|
double w,
|
||||||
double h,
|
double h,
|
||||||
) : redSprite = klondikeSprite(x1, y1, w, h),
|
) : redSprite = klondikeSprite(x1, y1, w, h),
|
||||||
blackSprite = klondikeSprite(x2, y2, w, h);
|
blackSprite = klondikeSprite(x2, y2, w, h);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class Suit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Suit._(this.value, this.label, double x, double y, double w, double h)
|
Suit._(this.value, this.label, double x, double y, double w, double h)
|
||||||
: sprite = klondikeSprite(x, y, w, h);
|
: sprite = klondikeSprite(x, y, w, h);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -18,11 +18,11 @@ import 'tableau_pile.dart';
|
|||||||
class Card extends PositionComponent
|
class Card extends PositionComponent
|
||||||
with DragCallbacks, TapCallbacks, HasWorldReference<KlondikeWorld> {
|
with DragCallbacks, TapCallbacks, HasWorldReference<KlondikeWorld> {
|
||||||
Card(int intRank, int intSuit, {this.isBaseCard = false})
|
Card(int intRank, int intSuit, {this.isBaseCard = false})
|
||||||
: rank = Rank.fromInt(intRank),
|
: rank = Rank.fromInt(intRank),
|
||||||
suit = Suit.fromInt(intSuit),
|
suit = Suit.fromInt(intSuit),
|
||||||
super(
|
super(
|
||||||
size: KlondikeGame.cardSize,
|
size: KlondikeGame.cardSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
final Rank rank;
|
final Rank rank;
|
||||||
final Suit suit;
|
final Suit suit;
|
||||||
|
|||||||
@ -10,24 +10,24 @@ class FlatButton extends ButtonComponent {
|
|||||||
super.onReleased,
|
super.onReleased,
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
button: ButtonBackground(const Color(0xffece8a3)),
|
button: ButtonBackground(const Color(0xffece8a3)),
|
||||||
buttonDown: ButtonBackground(Colors.red),
|
buttonDown: ButtonBackground(Colors.red),
|
||||||
children: [
|
children: [
|
||||||
TextComponent(
|
TextComponent(
|
||||||
text: text,
|
text: text,
|
||||||
textRenderer: TextPaint(
|
textRenderer: TextPaint(
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 0.5 * size!.y,
|
fontSize: 0.5 * size!.y,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: const Color(0xffdbaf58),
|
color: const Color(0xffdbaf58),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
position: size / 2.0,
|
position: size / 2.0,
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ButtonBackground extends PositionComponent with HasAncestor<FlatButton> {
|
class ButtonBackground extends PositionComponent with HasAncestor<FlatButton> {
|
||||||
|
|||||||
@ -9,8 +9,8 @@ import 'card.dart';
|
|||||||
|
|
||||||
class FoundationPile extends PositionComponent implements Pile {
|
class FoundationPile extends PositionComponent implements Pile {
|
||||||
FoundationPile(int intSuit, this.checkWin, {super.position})
|
FoundationPile(int intSuit, this.checkWin, {super.position})
|
||||||
: suit = Suit.fromInt(intSuit),
|
: suit = Suit.fromInt(intSuit),
|
||||||
super(size: KlondikeGame.cardSize);
|
super(size: KlondikeGame.cardSize);
|
||||||
|
|
||||||
final VoidCallback checkWin;
|
final VoidCallback checkWin;
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,8 @@ class TableauPile extends PositionComponent implements Pile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void calculateHitArea() {
|
void calculateHitArea() {
|
||||||
height = KlondikeGame.cardHeight * 1.5 +
|
height =
|
||||||
|
KlondikeGame.cardHeight * 1.5 +
|
||||||
(_cards.length < 2 ? 0.0 : _cards.last.y - _cards.first.y);
|
(_cards.length < 2 ? 0.0 : _cards.last.y - _cards.first.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,8 +74,10 @@ class KlondikeWorld extends World with HasGameReference<KlondikeGame> {
|
|||||||
addAll(cards);
|
addAll(cards);
|
||||||
add(baseCard);
|
add(baseCard);
|
||||||
|
|
||||||
playAreaSize =
|
playAreaSize = Vector2(
|
||||||
Vector2(7 * cardSpaceWidth + cardGap, 4 * cardSpaceHeight + topGap);
|
7 * cardSpaceWidth + cardGap,
|
||||||
|
4 * cardSpaceHeight + topGap,
|
||||||
|
);
|
||||||
final gameMidX = playAreaSize.x / 2;
|
final gameMidX = playAreaSize.x / 2;
|
||||||
|
|
||||||
addButton('New deal', gameMidX, Action.newDeal);
|
addButton('New deal', gameMidX, Action.newDeal);
|
||||||
|
|||||||
@ -21,8 +21,8 @@ class Rank {
|
|||||||
double y2,
|
double y2,
|
||||||
double w,
|
double w,
|
||||||
double h,
|
double h,
|
||||||
) : redSprite = klondikeSprite(x1, y1, w, h),
|
) : redSprite = klondikeSprite(x1, y1, w, h),
|
||||||
blackSprite = klondikeSprite(x2, y2, w, h);
|
blackSprite = klondikeSprite(x2, y2, w, h);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class Suit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Suit._(this.value, this.label, double x, double y, double w, double h)
|
Suit._(this.value, this.label, double x, double y, double w, double h)
|
||||||
: sprite = klondikeSprite(x, y, w, h);
|
: sprite = klondikeSprite(x, y, w, h);
|
||||||
|
|
||||||
final int value;
|
final int value;
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -5,7 +5,7 @@ version: 1.0.0
|
|||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flame: ^1.30.1
|
flame: ^1.30.1
|
||||||
|
|||||||
@ -46,11 +46,13 @@ class EmberPlayer extends SpriteAnimationComponent
|
|||||||
@override
|
@override
|
||||||
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
|
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
|
||||||
horizontalDirection = 0;
|
horizontalDirection = 0;
|
||||||
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyA) ||
|
horizontalDirection +=
|
||||||
|
(keysPressed.contains(LogicalKeyboardKey.keyA) ||
|
||||||
keysPressed.contains(LogicalKeyboardKey.arrowLeft))
|
keysPressed.contains(LogicalKeyboardKey.arrowLeft))
|
||||||
? -1
|
? -1
|
||||||
: 0;
|
: 0;
|
||||||
horizontalDirection += (keysPressed.contains(LogicalKeyboardKey.keyD) ||
|
horizontalDirection +=
|
||||||
|
(keysPressed.contains(LogicalKeyboardKey.keyD) ||
|
||||||
keysPressed.contains(LogicalKeyboardKey.arrowRight))
|
keysPressed.contains(LogicalKeyboardKey.arrowRight))
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
@ -114,7 +116,8 @@ class EmberPlayer extends SpriteAnimationComponent
|
|||||||
if (other is GroundBlock || other is PlatformBlock) {
|
if (other is GroundBlock || other is PlatformBlock) {
|
||||||
if (intersectionPoints.length == 2) {
|
if (intersectionPoints.length == 2) {
|
||||||
// Calculate the collision normal and separation distance.
|
// Calculate the collision normal and separation distance.
|
||||||
final mid = (intersectionPoints.elementAt(0) +
|
final mid =
|
||||||
|
(intersectionPoints.elementAt(0) +
|
||||||
intersectionPoints.elementAt(1)) /
|
intersectionPoints.elementAt(1)) /
|
||||||
2;
|
2;
|
||||||
|
|
||||||
@ -154,12 +157,13 @@ class EmberPlayer extends SpriteAnimationComponent
|
|||||||
}
|
}
|
||||||
add(
|
add(
|
||||||
OpacityEffect.fadeOut(
|
OpacityEffect.fadeOut(
|
||||||
EffectController(
|
EffectController(
|
||||||
alternate: true,
|
alternate: true,
|
||||||
duration: 0.1,
|
duration: 0.1,
|
||||||
repeatCount: 5,
|
repeatCount: 5,
|
||||||
),
|
),
|
||||||
)..onComplete = () {
|
)
|
||||||
|
..onComplete = () {
|
||||||
hitByEnemy = false;
|
hitByEnemy = false;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -58,21 +58,21 @@ class EmberQuestGame extends FlameGame
|
|||||||
for (final block in segments[segmentIndex]) {
|
for (final block in segments[segmentIndex]) {
|
||||||
final component = switch (block.blockType) {
|
final component = switch (block.blockType) {
|
||||||
const (GroundBlock) => GroundBlock(
|
const (GroundBlock) => GroundBlock(
|
||||||
gridPosition: block.gridPosition,
|
gridPosition: block.gridPosition,
|
||||||
xOffset: xPositionOffset,
|
xOffset: xPositionOffset,
|
||||||
),
|
),
|
||||||
const (PlatformBlock) => PlatformBlock(
|
const (PlatformBlock) => PlatformBlock(
|
||||||
gridPosition: block.gridPosition,
|
gridPosition: block.gridPosition,
|
||||||
xOffset: xPositionOffset,
|
xOffset: xPositionOffset,
|
||||||
),
|
),
|
||||||
const (Star) => Star(
|
const (Star) => Star(
|
||||||
gridPosition: block.gridPosition,
|
gridPosition: block.gridPosition,
|
||||||
xOffset: xPositionOffset,
|
xOffset: xPositionOffset,
|
||||||
),
|
),
|
||||||
const (WaterEnemy) => WaterEnemy(
|
const (WaterEnemy) => WaterEnemy(
|
||||||
gridPosition: block.gridPosition,
|
gridPosition: block.gridPosition,
|
||||||
xOffset: xPositionOffset,
|
xOffset: xPositionOffset,
|
||||||
),
|
),
|
||||||
_ => throw UnimplementedError(),
|
_ => throw UnimplementedError(),
|
||||||
};
|
};
|
||||||
world.add(component);
|
world.add(component);
|
||||||
|
|||||||
@ -5,7 +5,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
flutter: ">=3.27.1"
|
flutter: ">=3.27.1"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -21,11 +21,11 @@ void main() {
|
|||||||
'step5' => step5.main(),
|
'step5' => step5.main(),
|
||||||
'step6' => step6.main(),
|
'step6' => step6.main(),
|
||||||
_ => runApp(
|
_ => runApp(
|
||||||
Directionality(
|
Directionality(
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
child: Text('''Error: unknown page. Pass "step{1,6}" as a GET param;
|
child: Text('''Error: unknown page. Pass "step{1,6}" as a GET param;
|
||||||
e.g: ${web.window.location}?step1'''),
|
e.g: ${web.window.location}?step1'''),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,10 @@ class SpaceShooterGame extends FlameGame with PanDetector {
|
|||||||
|
|
||||||
class Player extends SpriteComponent with HasGameReference<SpaceShooterGame> {
|
class Player extends SpriteComponent with HasGameReference<SpaceShooterGame> {
|
||||||
Player()
|
Player()
|
||||||
: super(
|
: super(
|
||||||
size: Vector2(100, 150),
|
size: Vector2(100, 150),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -39,10 +39,10 @@ class SpaceShooterGame extends FlameGame with PanDetector {
|
|||||||
class Player extends SpriteAnimationComponent
|
class Player extends SpriteAnimationComponent
|
||||||
with HasGameReference<SpaceShooterGame> {
|
with HasGameReference<SpaceShooterGame> {
|
||||||
Player()
|
Player()
|
||||||
: super(
|
: super(
|
||||||
size: Vector2(100, 150),
|
size: Vector2(100, 150),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -49,10 +49,10 @@ class SpaceShooterGame extends FlameGame with PanDetector {
|
|||||||
class Player extends SpriteAnimationComponent
|
class Player extends SpriteAnimationComponent
|
||||||
with HasGameReference<SpaceShooterGame> {
|
with HasGameReference<SpaceShooterGame> {
|
||||||
Player()
|
Player()
|
||||||
: super(
|
: super(
|
||||||
size: Vector2(100, 150),
|
size: Vector2(100, 150),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
late final SpawnComponent _bulletSpawner;
|
late final SpawnComponent _bulletSpawner;
|
||||||
|
|
||||||
@ -76,7 +76,8 @@ class Player extends SpriteAnimationComponent
|
|||||||
selfPositioning: true,
|
selfPositioning: true,
|
||||||
factory: (index) {
|
factory: (index) {
|
||||||
return Bullet(
|
return Bullet(
|
||||||
position: position +
|
position:
|
||||||
|
position +
|
||||||
Vector2(
|
Vector2(
|
||||||
0,
|
0,
|
||||||
-height / 2,
|
-height / 2,
|
||||||
@ -107,9 +108,9 @@ class Bullet extends SpriteAnimationComponent
|
|||||||
Bullet({
|
Bullet({
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
size: Vector2(25, 50),
|
size: Vector2(25, 50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -60,10 +60,10 @@ class SpaceShooterGame extends FlameGame with PanDetector {
|
|||||||
class Player extends SpriteAnimationComponent
|
class Player extends SpriteAnimationComponent
|
||||||
with HasGameReference<SpaceShooterGame> {
|
with HasGameReference<SpaceShooterGame> {
|
||||||
Player()
|
Player()
|
||||||
: super(
|
: super(
|
||||||
size: Vector2(100, 150),
|
size: Vector2(100, 150),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
late final SpawnComponent _bulletSpawner;
|
late final SpawnComponent _bulletSpawner;
|
||||||
|
|
||||||
@ -87,7 +87,8 @@ class Player extends SpriteAnimationComponent
|
|||||||
selfPositioning: true,
|
selfPositioning: true,
|
||||||
factory: (index) {
|
factory: (index) {
|
||||||
return Bullet(
|
return Bullet(
|
||||||
position: position +
|
position:
|
||||||
|
position +
|
||||||
Vector2(
|
Vector2(
|
||||||
0,
|
0,
|
||||||
-height / 2,
|
-height / 2,
|
||||||
@ -118,9 +119,9 @@ class Bullet extends SpriteAnimationComponent
|
|||||||
Bullet({
|
Bullet({
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
size: Vector2(25, 50),
|
size: Vector2(25, 50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -153,9 +154,9 @@ class Enemy extends SpriteAnimationComponent
|
|||||||
Enemy({
|
Enemy({
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
size: Vector2.all(enemySize),
|
size: Vector2.all(enemySize),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
static const enemySize = 50.0;
|
static const enemySize = 50.0;
|
||||||
|
|
||||||
|
|||||||
@ -62,10 +62,10 @@ class SpaceShooterGame extends FlameGame
|
|||||||
class Player extends SpriteAnimationComponent
|
class Player extends SpriteAnimationComponent
|
||||||
with HasGameReference<SpaceShooterGame> {
|
with HasGameReference<SpaceShooterGame> {
|
||||||
Player()
|
Player()
|
||||||
: super(
|
: super(
|
||||||
size: Vector2(100, 150),
|
size: Vector2(100, 150),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
late final SpawnComponent _bulletSpawner;
|
late final SpawnComponent _bulletSpawner;
|
||||||
|
|
||||||
@ -89,7 +89,8 @@ class Player extends SpriteAnimationComponent
|
|||||||
selfPositioning: true,
|
selfPositioning: true,
|
||||||
factory: (index) {
|
factory: (index) {
|
||||||
return Bullet(
|
return Bullet(
|
||||||
position: position +
|
position:
|
||||||
|
position +
|
||||||
Vector2(
|
Vector2(
|
||||||
0,
|
0,
|
||||||
-height / 2,
|
-height / 2,
|
||||||
@ -120,9 +121,9 @@ class Bullet extends SpriteAnimationComponent
|
|||||||
Bullet({
|
Bullet({
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
size: Vector2(25, 50),
|
size: Vector2(25, 50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -161,9 +162,9 @@ class Enemy extends SpriteAnimationComponent
|
|||||||
Enemy({
|
Enemy({
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
size: Vector2.all(enemySize),
|
size: Vector2.all(enemySize),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
static const enemySize = 50.0;
|
static const enemySize = 50.0;
|
||||||
|
|
||||||
@ -214,10 +215,10 @@ class Explosion extends SpriteAnimationComponent
|
|||||||
Explosion({
|
Explosion({
|
||||||
super.position,
|
super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
size: Vector2.all(150),
|
size: Vector2.all(150),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
removeOnFinish: true,
|
removeOnFinish: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ publish_to: 'none'
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flame: ^1.30.1
|
flame: ^1.30.1
|
||||||
|
|||||||
@ -21,17 +21,18 @@ and the glowing effect of the crystal ball.
|
|||||||
|
|
||||||
class _CrystalBallWidgetState extends State<CrystalBallWidget> {
|
class _CrystalBallWidgetState extends State<CrystalBallWidget> {
|
||||||
// PreloadedPrograms is a simple data class that holds the preloaded
|
// PreloadedPrograms is a simple data class that holds the preloaded
|
||||||
late final Future<PreloadedPrograms> preloadedPrograms = Future.wait([
|
late final Future<PreloadedPrograms> preloadedPrograms =
|
||||||
FragmentProgram.fromAsset('packages/crystal_ball/shaders/ground.frag'),
|
Future.wait([
|
||||||
FragmentProgram.fromAsset('packages/crystal_ball/shaders/fog.frag'),
|
FragmentProgram.fromAsset('packages/crystal_ball/shaders/ground.frag'),
|
||||||
FragmentProgram.fromAsset('packages/crystal_ball/shaders/firefly.frag'),
|
FragmentProgram.fromAsset('packages/crystal_ball/shaders/fog.frag'),
|
||||||
]).then(
|
FragmentProgram.fromAsset('packages/crystal_ball/shaders/firefly.frag'),
|
||||||
(l) => (
|
]).then(
|
||||||
waterFragmentProgram: l[0],
|
(l) => (
|
||||||
fogFragmentProgram: l[1],
|
waterFragmentProgram: l[0],
|
||||||
fireflyFragmentProgram: l[2],
|
fogFragmentProgram: l[1],
|
||||||
),
|
fireflyFragmentProgram: l[2],
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
|
||||||
CrystalBallGame? game;
|
CrystalBallGame? game;
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,10 @@ import 'package:flutter/services.dart';
|
|||||||
class InputHandler extends PositionComponent
|
class InputHandler extends PositionComponent
|
||||||
with TapCallbacks, HasGameReference<CrystalBallGame> {
|
with TapCallbacks, HasGameReference<CrystalBallGame> {
|
||||||
InputHandler()
|
InputHandler()
|
||||||
: super(
|
: super(
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
size: kCameraSize,
|
size: kCameraSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -17,37 +17,37 @@ class Rectangle extends PositionComponent
|
|||||||
ParentIsA<Ground>,
|
ParentIsA<Ground>,
|
||||||
HasGameReference<CrystalBallGame> {
|
HasGameReference<CrystalBallGame> {
|
||||||
Rectangle(double y)
|
Rectangle(double y)
|
||||||
: super(
|
: super(
|
||||||
anchor: Anchor.topCenter,
|
anchor: Anchor.topCenter,
|
||||||
position: Vector2(0, y),
|
position: Vector2(0, y),
|
||||||
size: Vector2(
|
size: Vector2(
|
||||||
kCameraSize.x,
|
kCameraSize.x,
|
||||||
kCameraSize.y / 2,
|
kCameraSize.y / 2,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
RectangleHitbox(
|
||||||
|
size: Vector2(
|
||||||
|
kCameraSize.x,
|
||||||
|
kCameraSize.y / 2,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
children: [
|
RectangleHitbox(
|
||||||
|
position: Vector2(0, kPlayerRadius),
|
||||||
|
size: Vector2(
|
||||||
|
kCameraSize.x,
|
||||||
|
kCameraSize.y / 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
for (var i = 2; i < 30; i++)
|
||||||
RectangleHitbox(
|
RectangleHitbox(
|
||||||
|
position: Vector2(0, kPlayerRadius * i),
|
||||||
size: Vector2(
|
size: Vector2(
|
||||||
kCameraSize.x,
|
kCameraSize.x,
|
||||||
kCameraSize.y / 2,
|
kCameraSize.y / 2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
RectangleHitbox(
|
],
|
||||||
position: Vector2(0, kPlayerRadius),
|
);
|
||||||
size: Vector2(
|
|
||||||
kCameraSize.x,
|
|
||||||
kCameraSize.y / 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
for (var i = 2; i < 30; i++)
|
|
||||||
RectangleHitbox(
|
|
||||||
position: Vector2(0, kPlayerRadius * i),
|
|
||||||
size: Vector2(
|
|
||||||
kCameraSize.x,
|
|
||||||
kCameraSize.y / 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
double get topEdge => absolutePositionOfAnchor(Anchor.topCenter).y;
|
double get topEdge => absolutePositionOfAnchor(Anchor.topCenter).y;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,15 +16,15 @@ class TheBall extends PositionComponent
|
|||||||
TheBall({
|
TheBall({
|
||||||
required Vector2 super.position,
|
required Vector2 super.position,
|
||||||
}) : super(
|
}) : super(
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
priority: 100000,
|
priority: 100000,
|
||||||
children: [
|
children: [
|
||||||
CircleHitbox(
|
CircleHitbox(
|
||||||
radius: kPlayerRadius,
|
radius: kPlayerRadius,
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
final Vector2 velocity = Vector2.zero();
|
final Vector2 velocity = Vector2.zero();
|
||||||
|
|
||||||
|
|||||||
@ -20,12 +20,12 @@ class CrystalBallGame extends FlameGame<CrystalBallGameWorld>
|
|||||||
CrystalBallGame({
|
CrystalBallGame({
|
||||||
required this.preloadedPrograms,
|
required this.preloadedPrograms,
|
||||||
}) : super(
|
}) : super(
|
||||||
camera: CameraComponent.withFixedResolution(
|
camera: CameraComponent.withFixedResolution(
|
||||||
width: kCameraSize.x,
|
width: kCameraSize.x,
|
||||||
height: kCameraSize.y,
|
height: kCameraSize.y,
|
||||||
),
|
),
|
||||||
world: CrystalBallGameWorld(),
|
world: CrystalBallGameWorld(),
|
||||||
) {
|
) {
|
||||||
camera.postProcess = PostProcessGroup(
|
camera.postProcess = PostProcessGroup(
|
||||||
postProcesses: [
|
postProcesses: [
|
||||||
PostProcessSequentialGroup(
|
PostProcessSequentialGroup(
|
||||||
|
|||||||
@ -60,8 +60,12 @@ class BallGlowPostProcess extends PostProcess {
|
|||||||
Vector2 size,
|
Vector2 size,
|
||||||
Canvas canvas,
|
Canvas canvas,
|
||||||
) {
|
) {
|
||||||
final origin =
|
final origin = world
|
||||||
world.findGame()!.camera.visibleWorldRect.topLeft.toVector2();
|
.findGame()!
|
||||||
|
.camera
|
||||||
|
.visibleWorldRect
|
||||||
|
.topLeft
|
||||||
|
.toVector2();
|
||||||
final theBall = world.theBall;
|
final theBall = world.theBall;
|
||||||
final ballPosition = theBall.absolutePosition;
|
final ballPosition = theBall.absolutePosition;
|
||||||
final uvBall = (ballPosition - origin)..divide(kCameraSize);
|
final uvBall = (ballPosition - origin)..divide(kCameraSize);
|
||||||
|
|||||||
@ -33,8 +33,9 @@ class FireflyPostProcess extends PostProcess {
|
|||||||
|
|
||||||
final groundPosition =
|
final groundPosition =
|
||||||
world.ground.rectangle.absolutePosition + Vector2(0, 1800);
|
world.ground.rectangle.absolutePosition + Vector2(0, 1800);
|
||||||
final globalGroundPosition =
|
final globalGroundPosition = camera.viewfinder.localToGlobal(
|
||||||
camera.viewfinder.localToGlobal(groundPosition);
|
groundPosition,
|
||||||
|
);
|
||||||
final uvGround = globalGroundPosition.y / size.y;
|
final uvGround = globalGroundPosition.y / size.y;
|
||||||
|
|
||||||
final cameraVerticalPos = world.cameraTarget.position.clone()
|
final cameraVerticalPos = world.cameraTarget.position.clone()
|
||||||
|
|||||||
@ -27,8 +27,8 @@ class ForegroundFogPostProcess extends PostProcess {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void postProcess(Vector2 size, Canvas canvas) {
|
void postProcess(Vector2 size, Canvas canvas) {
|
||||||
final origin =
|
final origin = CameraComponent.currentCamera!.visibleWorldRect.topLeft
|
||||||
CameraComponent.currentCamera!.visibleWorldRect.topLeft.toVector2();
|
.toVector2();
|
||||||
|
|
||||||
shader.setFloatUniforms((value) {
|
shader.setFloatUniforms((value) {
|
||||||
value.setVector(size);
|
value.setVector(size);
|
||||||
|
|||||||
@ -27,8 +27,9 @@ class WaterPostProcess extends PostProcess {
|
|||||||
void postProcess(Vector2 size, Canvas canvas) {
|
void postProcess(Vector2 size, Canvas canvas) {
|
||||||
final groundPosition = world.ground.rectangle.position;
|
final groundPosition = world.ground.rectangle.position;
|
||||||
final camera = CameraComponent.currentCamera!;
|
final camera = CameraComponent.currentCamera!;
|
||||||
final globalGroundPosition =
|
final globalGroundPosition = camera.viewfinder.localToGlobal(
|
||||||
camera.viewfinder.localToGlobal(groundPosition);
|
groundPosition,
|
||||||
|
);
|
||||||
final uvGround = globalGroundPosition.y / size.y;
|
final uvGround = globalGroundPosition.y / size.y;
|
||||||
|
|
||||||
final preRenderedSubtree = rasterizeSubtree();
|
final preRenderedSubtree = rasterizeSubtree();
|
||||||
|
|||||||
@ -5,7 +5,7 @@ publish_to: 'none'
|
|||||||
version: "0.1.0"
|
version: "0.1.0"
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
flutter: ">=3.27.1"
|
flutter: ">=3.27.1"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -88,10 +88,11 @@ List<Ball> createBalls(Vector2 trackSize, List<Wall> walls, Ball bigBall) {
|
|||||||
);
|
);
|
||||||
final touchesBall =
|
final touchesBall =
|
||||||
ball.initialPosition.distanceTo(bigBall.initialPosition) <
|
ball.initialPosition.distanceTo(bigBall.initialPosition) <
|
||||||
ball.radius + bigBall.radius;
|
ball.radius + bigBall.radius;
|
||||||
if (!touchesBall) {
|
if (!touchesBall) {
|
||||||
final touchesWall =
|
final touchesWall = walls.any(
|
||||||
walls.any((wall) => wall.asRect.overlaps(ball.asRect));
|
(wall) => wall.asRect.overlaps(ball.asRect),
|
||||||
|
);
|
||||||
if (!touchesWall) {
|
if (!touchesWall) {
|
||||||
balls.add(ball);
|
balls.add(ball);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,10 +11,10 @@ import 'package:padracing/tire.dart';
|
|||||||
|
|
||||||
class Car extends BodyComponent<PadRacingGame> {
|
class Car extends BodyComponent<PadRacingGame> {
|
||||||
Car({required this.playerNumber, required this.cameraComponent})
|
Car({required this.playerNumber, required this.cameraComponent})
|
||||||
: super(
|
: super(
|
||||||
priority: 3,
|
priority: 3,
|
||||||
paint: Paint()..color = colors[playerNumber],
|
paint: Paint()..color = colors[playerNumber],
|
||||||
);
|
);
|
||||||
|
|
||||||
static final colors = [
|
static final colors = [
|
||||||
GameColors.green.color,
|
GameColors.green.color,
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import 'package:padracing/game_colors.dart';
|
|||||||
|
|
||||||
class LapLine extends BodyComponent with ContactCallbacks {
|
class LapLine extends BodyComponent with ContactCallbacks {
|
||||||
LapLine(this.id, this.initialPosition, this.size, {required this.isFinish})
|
LapLine(this.id, this.initialPosition, this.size, {required this.isFinish})
|
||||||
: super(priority: 1);
|
: super(priority: 1);
|
||||||
|
|
||||||
final int id;
|
final int id;
|
||||||
final bool isFinish;
|
final bool isFinish;
|
||||||
@ -94,8 +94,9 @@ class LapLine extends BodyComponent with ContactCallbacks {
|
|||||||
other.lapNotifier.value++;
|
other.lapNotifier.value++;
|
||||||
other.passedStartControl.clear();
|
other.passedStartControl.clear();
|
||||||
} else if (!isFinish) {
|
} else if (!isFinish) {
|
||||||
other.passedStartControl
|
other.passedStartControl.removeWhere(
|
||||||
.removeWhere((passedControl) => passedControl.id > id);
|
(passedControl) => passedControl.id > id,
|
||||||
|
);
|
||||||
other.passedStartControl.add(this);
|
other.passedStartControl.add(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import 'package:padracing/padracing_game.dart';
|
|||||||
|
|
||||||
class LapText extends PositionComponent with HasGameReference<PadRacingGame> {
|
class LapText extends PositionComponent with HasGameReference<PadRacingGame> {
|
||||||
LapText({required this.car, required Vector2 position})
|
LapText({required this.car, required Vector2 position})
|
||||||
: super(position: position);
|
: super(position: position);
|
||||||
|
|
||||||
final Car car;
|
final Car car;
|
||||||
late final ValueNotifier<int> lapNotifier = car.lapNotifier;
|
late final ValueNotifier<int> lapNotifier = car.lapNotifier;
|
||||||
|
|||||||
@ -133,14 +133,14 @@ class PadRacingGame extends Forge2DGame with KeyboardEvents {
|
|||||||
..paint.style = PaintingStyle.stroke;
|
..paint.style = PaintingStyle.stroke;
|
||||||
final cameras = List.generate(numberOfPlayers, (i) {
|
final cameras = List.generate(numberOfPlayers, (i) {
|
||||||
return CameraComponent(
|
return CameraComponent(
|
||||||
world: world,
|
world: world,
|
||||||
viewport: FixedSizeViewport(viewportSize.x, viewportSize.y)
|
viewport: FixedSizeViewport(viewportSize.x, viewportSize.y)
|
||||||
..position = alignedVector(
|
..position = alignedVector(
|
||||||
longMultiplier: i == 0 ? 0.0 : 1 / (i + 1),
|
longMultiplier: i == 0 ? 0.0 : 1 / (i + 1),
|
||||||
shortMultiplier: 0.0,
|
shortMultiplier: 0.0,
|
||||||
)
|
)
|
||||||
..add(viewportRimGenerator()),
|
..add(viewportRimGenerator()),
|
||||||
)
|
)
|
||||||
..viewfinder.anchor = Anchor.center
|
..viewfinder.anchor = Anchor.center
|
||||||
..viewfinder.zoom = playZoom;
|
..viewfinder.zoom = playZoom;
|
||||||
});
|
});
|
||||||
@ -149,13 +149,13 @@ class PadRacingGame extends Forge2DGame with KeyboardEvents {
|
|||||||
const mapCameraZoom = 0.5;
|
const mapCameraZoom = 0.5;
|
||||||
final mapCameras = List.generate(numberOfPlayers, (i) {
|
final mapCameras = List.generate(numberOfPlayers, (i) {
|
||||||
return CameraComponent(
|
return CameraComponent(
|
||||||
world: world,
|
world: world,
|
||||||
viewport: FixedSizeViewport(mapCameraSize.x, mapCameraSize.y)
|
viewport: FixedSizeViewport(mapCameraSize.x, mapCameraSize.y)
|
||||||
..position = Vector2(
|
..position = Vector2(
|
||||||
viewportSize.x - mapCameraSize.x * mapCameraZoom - 50,
|
viewportSize.x - mapCameraSize.x * mapCameraZoom - 50,
|
||||||
50,
|
50,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
..viewfinder.anchor = Anchor.topLeft
|
..viewfinder.anchor = Anchor.topLeft
|
||||||
..viewfinder.zoom = mapCameraZoom;
|
..viewfinder.zoom = mapCameraZoom;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,12 +15,12 @@ class Tire extends BodyComponent<PadRacingGame> {
|
|||||||
required this.jointDef,
|
required this.jointDef,
|
||||||
this.isTurnableTire = false,
|
this.isTurnableTire = false,
|
||||||
}) : super(
|
}) : super(
|
||||||
paint: Paint()
|
paint: Paint()
|
||||||
..color = car.paint.color
|
..color = car.paint.color
|
||||||
..strokeWidth = 0.2
|
..strokeWidth = 0.2
|
||||||
..style = PaintingStyle.stroke,
|
..style = PaintingStyle.stroke,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
static const double _backTireMaxDriveForce = 300.0;
|
static const double _backTireMaxDriveForce = 300.0;
|
||||||
static const double _frontTireMaxDriveForce = 600.0;
|
static const double _frontTireMaxDriveForce = 600.0;
|
||||||
@ -39,10 +39,12 @@ class Tire extends BodyComponent<PadRacingGame> {
|
|||||||
|
|
||||||
final Set<LogicalKeyboardKey> pressedKeys;
|
final Set<LogicalKeyboardKey> pressedKeys;
|
||||||
|
|
||||||
late final double _maxDriveForce =
|
late final double _maxDriveForce = isFrontTire
|
||||||
isFrontTire ? _frontTireMaxDriveForce : _backTireMaxDriveForce;
|
? _frontTireMaxDriveForce
|
||||||
late final double _maxLateralImpulse =
|
: _backTireMaxDriveForce;
|
||||||
isFrontTire ? _frontTireMaxLateralImpulse : _backTireMaxLateralImpulse;
|
late final double _maxLateralImpulse = isFrontTire
|
||||||
|
? _frontTireMaxLateralImpulse
|
||||||
|
: _backTireMaxLateralImpulse;
|
||||||
|
|
||||||
// Make mutable if ice or something should be implemented
|
// Make mutable if ice or something should be implemented
|
||||||
final double _currentTraction = 1.0;
|
final double _currentTraction = 1.0;
|
||||||
@ -165,8 +167,10 @@ class Tire extends BodyComponent<PadRacingGame> {
|
|||||||
if (isTurnableTire && isTurning) {
|
if (isTurnableTire && isTurning) {
|
||||||
final turnPerTimeStep = _turnSpeedPerSecond * dt;
|
final turnPerTimeStep = _turnSpeedPerSecond * dt;
|
||||||
final angleNow = joint.jointAngle();
|
final angleNow = joint.jointAngle();
|
||||||
final angleToTurn =
|
final angleToTurn = (desiredAngle - angleNow).clamp(
|
||||||
(desiredAngle - angleNow).clamp(-turnPerTimeStep, turnPerTimeStep);
|
-turnPerTimeStep,
|
||||||
|
turnPerTimeStep,
|
||||||
|
);
|
||||||
final angle = angleNow + angleToTurn;
|
final angle = angleNow + angleToTurn;
|
||||||
joint.setLimits(angle, angle);
|
joint.setLimits(angle, angle);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ publish_to: 'none'
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
collection: ^1.17.1
|
collection: ^1.17.1
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class BulletComponent extends SpriteAnimationComponent
|
|||||||
final Vector2 deltaPosition = Vector2.zero();
|
final Vector2 deltaPosition = Vector2.zero();
|
||||||
|
|
||||||
BulletComponent({required super.position, super.angle})
|
BulletComponent({required super.position, super.angle})
|
||||||
: super(size: Vector2(10, 20), anchor: Anchor.center);
|
: super(size: Vector2(10, 20), anchor: Anchor.center);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class EnemyComponent extends SpriteAnimationComponent
|
|||||||
static final Vector2 initialSize = Vector2.all(25);
|
static final Vector2 initialSize = Vector2.all(25);
|
||||||
|
|
||||||
EnemyComponent({required super.position})
|
EnemyComponent({required super.position})
|
||||||
: super(size: initialSize, anchor: Anchor.center);
|
: super(size: initialSize, anchor: Anchor.center);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -3,11 +3,11 @@ import 'package:flame/components.dart';
|
|||||||
class ExplosionComponent extends SpriteAnimationComponent
|
class ExplosionComponent extends SpriteAnimationComponent
|
||||||
with HasGameReference {
|
with HasGameReference {
|
||||||
ExplosionComponent({super.position})
|
ExplosionComponent({super.position})
|
||||||
: super(
|
: super(
|
||||||
size: Vector2.all(50),
|
size: Vector2.all(50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
removeOnFinish: true,
|
removeOnFinish: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ class StarComponent extends SpriteAnimationComponent with HasGameReference {
|
|||||||
static const speed = 10;
|
static const speed = 10;
|
||||||
|
|
||||||
StarComponent({super.animation, super.position})
|
StarComponent({super.animation, super.position})
|
||||||
: super(size: Vector2.all(20));
|
: super(size: Vector2.all(20));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void update(double dt) {
|
void update(double dt) {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ publish_to: 'none'
|
|||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
flutter: ">=3.27.1"
|
flutter: ">=3.27.1"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -6,10 +6,10 @@ import 'package:trex_game/trex_game.dart';
|
|||||||
class Cloud extends SpriteComponent
|
class Cloud extends SpriteComponent
|
||||||
with ParentIsA<CloudManager>, HasGameReference<TRexGame> {
|
with ParentIsA<CloudManager>, HasGameReference<TRexGame> {
|
||||||
Cloud({required Vector2 position})
|
Cloud({required Vector2 position})
|
||||||
: super(
|
: super(
|
||||||
position: position,
|
position: position,
|
||||||
size: initialSize,
|
size: initialSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
static final Vector2 initialSize = Vector2(92.0, 28.0);
|
static final Vector2 initialSize = Vector2(92.0, 28.0);
|
||||||
|
|
||||||
@ -53,7 +53,8 @@ class Cloud extends SpriteComponent
|
|||||||
@override
|
@override
|
||||||
void onGameResize(Vector2 size) {
|
void onGameResize(Vector2 size) {
|
||||||
super.onGameResize(size);
|
super.onGameResize(size);
|
||||||
y = ((absolutePosition.y / 2 - (maxSkyLevel - minSkyLevel)) +
|
y =
|
||||||
|
((absolutePosition.y / 2 - (maxSkyLevel - minSkyLevel)) +
|
||||||
game.random.nextDoubleBetween(minSkyLevel, maxSkyLevel)) -
|
game.random.nextDoubleBetween(minSkyLevel, maxSkyLevel)) -
|
||||||
absolutePositionOf(absoluteTopLeftPosition).y;
|
absolutePositionOf(absoluteTopLeftPosition).y;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,8 @@ class Horizon extends PositionComponent with HasGameReference<TRexGame> {
|
|||||||
|
|
||||||
List<SpriteComponent> _generateLines() {
|
List<SpriteComponent> _generateLines() {
|
||||||
final number = 1 + (game.size.x / lineSize.x).ceil() - groundLayers.length;
|
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);
|
(groundLayers.lastOrNull?.width ?? 0);
|
||||||
return List.generate(
|
return List.generate(
|
||||||
max(number, 0),
|
max(number, 0),
|
||||||
|
|||||||
@ -29,8 +29,8 @@ class Obstacle extends SpriteComponent with HasGameReference<TRexGame> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double computeGap(double gapCoefficient, double speed) {
|
double computeGap(double gapCoefficient, double speed) {
|
||||||
final minGap =
|
final minGap = (width * speed * settings.minGap * gapCoefficient)
|
||||||
(width * speed * settings.minGap * gapCoefficient).roundToDouble();
|
.roundToDouble();
|
||||||
final maxGap = (minGap * _maxGapCoefficient).roundToDouble();
|
final maxGap = (minGap * _maxGapCoefficient).roundToDouble();
|
||||||
return game.random.nextDoubleBetween(minGap, maxGap);
|
return game.random.nextDoubleBetween(minGap, maxGap);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,15 +91,15 @@ class ObstacleTypeSettings {
|
|||||||
Sprite sprite(Image spriteImage) {
|
Sprite sprite(Image spriteImage) {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
ObstacleType.cactusSmall => Sprite(
|
ObstacleType.cactusSmall => Sprite(
|
||||||
spriteImage,
|
spriteImage,
|
||||||
srcPosition: Vector2(446.0, 2.0),
|
srcPosition: Vector2(446.0, 2.0),
|
||||||
srcSize: size,
|
srcSize: size,
|
||||||
),
|
),
|
||||||
ObstacleType.cactusLarge => Sprite(
|
ObstacleType.cactusLarge => Sprite(
|
||||||
spriteImage,
|
spriteImage,
|
||||||
srcPosition: Vector2(652.0, 2.0),
|
srcPosition: Vector2(652.0, 2.0),
|
||||||
srcSize: size,
|
srcSize: size,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ publish_to: 'none'
|
|||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.6.0 <4.0.0"
|
sdk: ">=3.8.0 <4.0.0"
|
||||||
flutter: ">=3.27.1"
|
flutter: ">=3.27.1"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -5,10 +5,10 @@ import 'package:meta/meta.dart';
|
|||||||
class Ember<T extends FlameGame> extends SpriteAnimationComponent
|
class Ember<T extends FlameGame> extends SpriteAnimationComponent
|
||||||
with HasGameReference<T> {
|
with HasGameReference<T> {
|
||||||
Ember({super.position, Vector2? size, super.priority, super.key})
|
Ember({super.position, Vector2? size, super.priority, super.key})
|
||||||
: super(
|
: super(
|
||||||
size: size ?? Vector2.all(50),
|
size: size ?? Vector2.all(50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@mustCallSuper
|
@mustCallSuper
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import 'package:examples/stories/bridge_libraries/audio/basic_audio_example.dart
|
|||||||
import 'package:flame/game.dart';
|
import 'package:flame/game.dart';
|
||||||
|
|
||||||
void addAudioStories(Dashbook dashbook) {
|
void addAudioStories(Dashbook dashbook) {
|
||||||
dashbook.storiesOf('Audio').add(
|
dashbook
|
||||||
|
.storiesOf('Audio')
|
||||||
|
.add(
|
||||||
'Basic Audio',
|
'Basic Audio',
|
||||||
(_) => GameWidget(game: BasicAudioExample()),
|
(_) => GameWidget(game: BasicAudioExample()),
|
||||||
codeLink: baseLink('bridge_libraries/audio/basic_audio_example.dart'),
|
codeLink: baseLink('bridge_libraries/audio/basic_audio_example.dart'),
|
||||||
|
|||||||
@ -15,10 +15,10 @@ class AnimatedBodyExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
AnimatedBodyExample()
|
AnimatedBodyExample()
|
||||||
: super(
|
: super(
|
||||||
gravity: Vector2.zero(),
|
gravity: Vector2.zero(),
|
||||||
world: AnimatedBodyWorld(),
|
world: AnimatedBodyWorld(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnimatedBodyWorld extends Forge2DWorld
|
class AnimatedBodyWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -28,12 +28,12 @@ class CompositionExample extends Forge2DGame {
|
|||||||
|
|
||||||
class TappableText extends TextComponent with TapCallbacks {
|
class TappableText extends TextComponent with TapCallbacks {
|
||||||
TappableText(Vector2 position)
|
TappableText(Vector2 position)
|
||||||
: super(
|
: super(
|
||||||
text: 'A normal tappable Flame component',
|
text: 'A normal tappable Flame component',
|
||||||
textRenderer: TextPaint(style: _textStyle),
|
textRenderer: TextPaint(style: _textStyle),
|
||||||
position: position,
|
position: position,
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class ContactCallbacksExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
ContactCallbacksExample()
|
ContactCallbacksExample()
|
||||||
: super(gravity: Vector2(0, 10.0), world: ContactCallbackWorld());
|
: super(gravity: Vector2(0, 10.0), world: ContactCallbackWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContactCallbackWorld extends Forge2DWorld
|
class ContactCallbackWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class DominoExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
DominoExample()
|
DominoExample()
|
||||||
: super(gravity: Vector2(0, 10.0), world: DominoExampleWorld());
|
: super(gravity: Vector2(0, 10.0), world: DominoExampleWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
class DominoExampleWorld extends Forge2DWorld
|
class DominoExampleWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class FrictionJointExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
FrictionJointExample()
|
FrictionJointExample()
|
||||||
: super(gravity: Vector2.all(0), world: FrictionJointWorld());
|
: super(gravity: Vector2.all(0), world: FrictionJointWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
class FrictionJointWorld extends Forge2DWorld
|
class FrictionJointWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -28,8 +28,11 @@ class GearJointWorld extends Forge2DWorld with HasGameReference<Forge2DGame> {
|
|||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
super.onLoad();
|
super.onLoad();
|
||||||
|
|
||||||
final box =
|
final box = DraggableBox(
|
||||||
DraggableBox(startPosition: boxAnchor, width: boxWidth, height: 20);
|
startPosition: boxAnchor,
|
||||||
|
width: boxWidth,
|
||||||
|
height: 20,
|
||||||
|
);
|
||||||
add(box);
|
add(box);
|
||||||
|
|
||||||
final ball1Anchor = boxAnchor - Vector2(boxWidth / 2 + ball1Radius, 0);
|
final ball1Anchor = boxAnchor - Vector2(boxWidth / 2 + ball1Radius, 0);
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class MotorJointExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
MotorJointExample()
|
MotorJointExample()
|
||||||
: super(gravity: Vector2.zero(), world: MotorJointWorld());
|
: super(gravity: Vector2.zero(), world: MotorJointWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MotorJointWorld extends Forge2DWorld with TapCallbacks {
|
class MotorJointWorld extends Forge2DWorld with TapCallbacks {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class MouseJointExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
MouseJointExample()
|
MouseJointExample()
|
||||||
: super(gravity: Vector2(0, 10.0), world: MouseJointWorld());
|
: super(gravity: Vector2(0, 10.0), world: MouseJointWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MouseJointWorld extends Forge2DWorld
|
class MouseJointWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class RevoluteJointExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
RevoluteJointExample()
|
RevoluteJointExample()
|
||||||
: super(gravity: Vector2(0, 10.0), world: RevoluteJointWorld());
|
: super(gravity: Vector2(0, 10.0), world: RevoluteJointWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
class RevoluteJointWorld extends Forge2DWorld
|
class RevoluteJointWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -54,11 +54,12 @@ class WeldJointWorld extends Forge2DWorld
|
|||||||
// screen space then gives us the coordinates of the upper left corner in
|
// screen space then gives us the coordinates of the upper left corner in
|
||||||
// world space.
|
// world space.
|
||||||
final halfSize = game.screenToWorld(Vector2.zero())..absolute();
|
final halfSize = game.screenToWorld(Vector2.zero())..absolute();
|
||||||
final sectionWidth = ((leftPillar.center.x.abs() +
|
final sectionWidth =
|
||||||
rightPillar.center.x.abs() +
|
((leftPillar.center.x.abs() +
|
||||||
pillarWidth) /
|
rightPillar.center.x.abs() +
|
||||||
sectionsCount)
|
pillarWidth) /
|
||||||
.ceilToDouble();
|
sectionsCount)
|
||||||
|
.ceilToDouble();
|
||||||
Body? prevSection;
|
Body? prevSection;
|
||||||
|
|
||||||
for (var i = 0; i < sectionsCount; i++) {
|
for (var i = 0; i < sectionsCount; i++) {
|
||||||
|
|||||||
@ -12,10 +12,10 @@ class SpriteBodyExample extends Forge2DGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
SpriteBodyExample()
|
SpriteBodyExample()
|
||||||
: super(
|
: super(
|
||||||
gravity: Vector2(0, 10.0),
|
gravity: Vector2(0, 10.0),
|
||||||
world: SpriteBodyWorld(),
|
world: SpriteBodyWorld(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpriteBodyWorld extends Forge2DWorld
|
class SpriteBodyWorld extends Forge2DWorld
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class Wall extends BodyComponent {
|
|||||||
final double strokeWidth;
|
final double strokeWidth;
|
||||||
|
|
||||||
Wall(this.start, this.end, {double? strokeWidth})
|
Wall(this.start, this.end, {double? strokeWidth})
|
||||||
: strokeWidth = strokeWidth ?? 1;
|
: strokeWidth = strokeWidth ?? 1;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Body createBody() {
|
Body createBody() {
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import 'package:examples/stories/bridge_libraries/flame_isolate/simple_isolate_e
|
|||||||
import 'package:flame/game.dart';
|
import 'package:flame/game.dart';
|
||||||
|
|
||||||
void addFlameIsolateExample(Dashbook dashbook) {
|
void addFlameIsolateExample(Dashbook dashbook) {
|
||||||
dashbook.storiesOf('FlameIsolate').add(
|
dashbook
|
||||||
|
.storiesOf('FlameIsolate')
|
||||||
|
.add(
|
||||||
'Simple isolate example',
|
'Simple isolate example',
|
||||||
(_) => GameWidget(
|
(_) => GameWidget(
|
||||||
game: SimpleIsolateExample(),
|
game: SimpleIsolateExample(),
|
||||||
|
|||||||
@ -10,7 +10,7 @@ class CommandLifecycleDialogueController extends DialogueControllerComponent {
|
|||||||
});
|
});
|
||||||
final FutureOr<void> Function(UserDefinedCommand command) onCommandOverride;
|
final FutureOr<void> Function(UserDefinedCommand command) onCommandOverride;
|
||||||
final FutureOr<void> Function(UserDefinedCommand command)
|
final FutureOr<void> Function(UserDefinedCommand command)
|
||||||
onCommandFinishOverride;
|
onCommandFinishOverride;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> onCommand(UserDefinedCommand command) async {
|
FutureOr<void> onCommand(UserDefinedCommand command) async {
|
||||||
|
|||||||
@ -4,14 +4,14 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class DialogueTextBox extends TextBoxComponent {
|
class DialogueTextBox extends TextBoxComponent {
|
||||||
DialogueTextBox({required super.text})
|
DialogueTextBox({required super.text})
|
||||||
: super(
|
: super(
|
||||||
position: Vector2(16, 16),
|
position: Vector2(16, 16),
|
||||||
size: Vector2(704, 96),
|
size: Vector2(704, 96),
|
||||||
textRenderer: TextPaint(
|
textRenderer: TextPaint(
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,13 +25,15 @@ commands work.
|
|||||||
final yarnProject = YarnProject();
|
final yarnProject = YarnProject();
|
||||||
final dialogueControllerComponent = CommandLifecycleDialogueController(
|
final dialogueControllerComponent = CommandLifecycleDialogueController(
|
||||||
onCommandOverride: (command) async {
|
onCommandOverride: (command) async {
|
||||||
final exampleVariable =
|
final exampleVariable = yarnProject.variables.getVariable(
|
||||||
yarnProject.variables.getVariable(r'$exampleVariable');
|
r'$exampleVariable',
|
||||||
|
);
|
||||||
onCommandLabel.text = 'onCommand: $exampleVariable';
|
onCommandLabel.text = 'onCommand: $exampleVariable';
|
||||||
},
|
},
|
||||||
onCommandFinishOverride: (command) async {
|
onCommandFinishOverride: (command) async {
|
||||||
final exampleVariable =
|
final exampleVariable = yarnProject.variables.getVariable(
|
||||||
yarnProject.variables.getVariable(r'$exampleVariable');
|
r'$exampleVariable',
|
||||||
|
);
|
||||||
onCommandFinishLabel.text = 'onCommandFinish: $exampleVariable';
|
onCommandFinishLabel.text = 'onCommandFinish: $exampleVariable';
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import 'package:examples/stories/bridge_libraries/flame_lottie/lottie_animation_
|
|||||||
import 'package:flame/game.dart';
|
import 'package:flame/game.dart';
|
||||||
|
|
||||||
void addFlameLottieExample(Dashbook dashbook) {
|
void addFlameLottieExample(Dashbook dashbook) {
|
||||||
dashbook.storiesOf('FlameLottie').add(
|
dashbook
|
||||||
|
.storiesOf('FlameLottie')
|
||||||
|
.add(
|
||||||
'Lottie Animation example',
|
'Lottie Animation example',
|
||||||
(_) => GameWidget(
|
(_) => GameWidget(
|
||||||
game: LottieAnimationExample(),
|
game: LottieAnimationExample(),
|
||||||
|
|||||||
@ -11,8 +11,9 @@ void addFlameSpineExamples(Dashbook dashbook) {
|
|||||||
(_) => GameWidget(
|
(_) => GameWidget(
|
||||||
game: FlameSpineExample(),
|
game: FlameSpineExample(),
|
||||||
),
|
),
|
||||||
codeLink:
|
codeLink: baseLink(
|
||||||
baseLink('bridge_libraries/flame_spine/basic_spine_example.dart'),
|
'bridge_libraries/flame_spine/basic_spine_example.dart',
|
||||||
|
),
|
||||||
info: FlameSpineExample.description,
|
info: FlameSpineExample.description,
|
||||||
)
|
)
|
||||||
..add(
|
..add(
|
||||||
|
|||||||
@ -85,8 +85,9 @@ void addCameraAndViewportStories(Dashbook dashbook) {
|
|||||||
..add(
|
..add(
|
||||||
'Follow and World bounds',
|
'Follow and World bounds',
|
||||||
(_) => GameWidget(game: CameraFollowAndWorldBoundsExample()),
|
(_) => GameWidget(game: CameraFollowAndWorldBoundsExample()),
|
||||||
codeLink:
|
codeLink: baseLink(
|
||||||
baseLink('camera_and_viewport/camera_follow_and_world_bounds.dart'),
|
'camera_and_viewport/camera_follow_and_world_bounds.dart',
|
||||||
|
),
|
||||||
info: CameraFollowAndWorldBoundsExample.description,
|
info: CameraFollowAndWorldBoundsExample.description,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,8 +36,10 @@ class CameraComponentExample extends FlameGame<AntWorld> with PanDetector {
|
|||||||
camera.viewfinder.position = Vector2(center.x, center.y);
|
camera.viewfinder.position = Vector2(center.x, center.y);
|
||||||
});
|
});
|
||||||
|
|
||||||
magnifyingGlass =
|
magnifyingGlass = CameraComponent(
|
||||||
CameraComponent(world: world, viewport: CircularViewport(radius));
|
world: world,
|
||||||
|
viewport: CircularViewport(radius),
|
||||||
|
);
|
||||||
magnifyingGlass.viewport.add(Bezel(radius));
|
magnifyingGlass.viewport.add(Bezel(radius));
|
||||||
magnifyingGlass.viewfinder.zoom = zoom;
|
magnifyingGlass.viewfinder.zoom = zoom;
|
||||||
}
|
}
|
||||||
@ -77,10 +79,10 @@ class CameraComponentExample extends FlameGame<AntWorld> with PanDetector {
|
|||||||
|
|
||||||
class Bezel extends PositionComponent {
|
class Bezel extends PositionComponent {
|
||||||
Bezel(this.radius)
|
Bezel(this.radius)
|
||||||
: super(
|
: super(
|
||||||
size: Vector2.all(2 * radius),
|
size: Vector2.all(2 * radius),
|
||||||
position: Vector2.all(radius),
|
position: Vector2.all(radius),
|
||||||
);
|
);
|
||||||
|
|
||||||
final double radius;
|
final double radius;
|
||||||
late final Path rim;
|
late final Path rim;
|
||||||
@ -106,23 +108,27 @@ class Bezel extends PositionComponent {
|
|||||||
rimBorder = Path()
|
rimBorder = Path()
|
||||||
..addOval(Rect.fromLTRB(-outer, -outer, outer, outer))
|
..addOval(Rect.fromLTRB(-outer, -outer, outer, outer))
|
||||||
..addOval(Rect.fromLTRB(-inner, -inner, inner, inner));
|
..addOval(Rect.fromLTRB(-inner, -inner, inner, inner));
|
||||||
handle = (Path()
|
handle =
|
||||||
..addRRect(
|
(Path()..addRRect(
|
||||||
RRect.fromLTRBR(
|
RRect.fromLTRBR(
|
||||||
radius,
|
radius,
|
||||||
-handleWidth / 2,
|
-handleWidth / 2,
|
||||||
handleLength + radius,
|
handleLength + radius,
|
||||||
handleWidth / 2,
|
handleWidth / 2,
|
||||||
const Radius.circular(5.0),
|
const Radius.circular(5.0),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
||||||
connector = (Path()
|
connector =
|
||||||
..addArc(Rect.fromLTRB(-outer, -outer, outer, outer), -0.22, 0.44))
|
(Path()..addArc(
|
||||||
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
Rect.fromLTRB(-outer, -outer, outer, outer),
|
||||||
specularHighlight = (Path()
|
-0.22,
|
||||||
..addOval(Rect.fromLTWH(-radius * 0.8, -8, 16, radius * 0.3)))
|
0.44,
|
||||||
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
))
|
||||||
|
.transform32((Matrix4.identity()..rotateZ(pi / 4)).storage);
|
||||||
|
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);
|
glassPaint = Paint()..color = const Color(0x1400ffae);
|
||||||
rimBorderPaint = Paint()
|
rimBorderPaint = Paint()
|
||||||
@ -428,8 +434,9 @@ class Ant extends PositionComponent {
|
|||||||
'nextIndex is outside of the bounds of travelPath',
|
'nextIndex is outside of the bounds of travelPath',
|
||||||
);
|
);
|
||||||
final nextPosition = travelPath[nextIndex];
|
final nextPosition = travelPath[nextIndex];
|
||||||
var nextAngle =
|
var nextAngle = angle = -(nextPosition - position).angleToSigned(
|
||||||
angle = -(nextPosition - position).angleToSigned(Vector2(0, -1));
|
Vector2(0, -1),
|
||||||
|
);
|
||||||
if (nextAngle - angle > tau / 2) {
|
if (nextAngle - angle > tau / 2) {
|
||||||
nextAngle -= tau;
|
nextAngle -= tau;
|
||||||
}
|
}
|
||||||
@ -481,9 +488,9 @@ class InsectLeg {
|
|||||||
this.l2,
|
this.l2,
|
||||||
this.l3, {
|
this.l3, {
|
||||||
required bool mirrorBendDirection,
|
required bool mirrorBendDirection,
|
||||||
}) : dir = mirrorBendDirection ? -1 : 1,
|
}) : dir = mirrorBendDirection ? -1 : 1,
|
||||||
path = Path(),
|
path = Path(),
|
||||||
foot = Vector2.zero() {
|
foot = Vector2.zero() {
|
||||||
final ok = placeFoot(Vector2(x1, y1));
|
final ok = placeFoot(Vector2(x1, y1));
|
||||||
assert(ok, 'The foot was not properly placed');
|
assert(ok, 'The foot was not properly placed');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,13 +22,14 @@ class CameraComponentPropertiesExample extends FlameGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
CameraComponentPropertiesExample()
|
CameraComponentPropertiesExample()
|
||||||
: super(
|
: super(
|
||||||
camera: CameraComponent(
|
camera:
|
||||||
viewport: FixedSizeViewport(200, 200)..add(ViewportFrame()),
|
CameraComponent(
|
||||||
)
|
viewport: FixedSizeViewport(200, 200)..add(ViewportFrame()),
|
||||||
..viewfinder.zoom = 5
|
)
|
||||||
..viewfinder.anchor = const Anchor(0.25, 0.75),
|
..viewfinder.zoom = 5
|
||||||
);
|
..viewfinder.anchor = const Anchor(0.25, 0.75),
|
||||||
|
);
|
||||||
|
|
||||||
late RectangleComponent _cullRect;
|
late RectangleComponent _cullRect;
|
||||||
|
|
||||||
@ -128,15 +129,15 @@ class Background extends Component with TapCallbacks {
|
|||||||
|
|
||||||
class ExpandingCircle extends CircleComponent {
|
class ExpandingCircle extends CircleComponent {
|
||||||
ExpandingCircle(Offset center)
|
ExpandingCircle(Offset center)
|
||||||
: super(
|
: super(
|
||||||
position: Vector2(center.dx, center.dy),
|
position: Vector2(center.dx, center.dy),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
radius: 0,
|
radius: 0,
|
||||||
paint: Paint()
|
paint: Paint()
|
||||||
..color = const Color(0xffffffff)
|
..color = const Color(0xffffffff)
|
||||||
..style = PaintingStyle.stroke
|
..style = PaintingStyle.stroke
|
||||||
..strokeWidth = 1,
|
..strokeWidth = 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
static const maxRadius = 50;
|
static const maxRadius = 50;
|
||||||
|
|
||||||
|
|||||||
@ -31,9 +31,7 @@ class CameraFollowAndWorldBoundsExample extends FlameGame
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Ground extends PositionComponent {
|
class Ground extends PositionComponent {
|
||||||
Ground()
|
Ground() : pebbles = [], super(size: Vector2(1000, 30)) {
|
||||||
: pebbles = [],
|
|
||||||
super(size: Vector2(1000, 30)) {
|
|
||||||
final random = Random();
|
final random = Random();
|
||||||
for (var i = 0; i < 25; i++) {
|
for (var i = 0; i < 25; i++) {
|
||||||
pebbles.add(
|
pebbles.add(
|
||||||
@ -67,19 +65,19 @@ class Ground extends PositionComponent {
|
|||||||
|
|
||||||
class Player extends PositionComponent with KeyboardHandler {
|
class Player extends PositionComponent with KeyboardHandler {
|
||||||
Player()
|
Player()
|
||||||
: body = Path()
|
: body = Path()
|
||||||
..moveTo(10, 0)
|
..moveTo(10, 0)
|
||||||
..cubicTo(17, 0, 28, 20, 10, 20)
|
..cubicTo(17, 0, 28, 20, 10, 20)
|
||||||
..cubicTo(-8, 20, 3, 0, 10, 0)
|
..cubicTo(-8, 20, 3, 0, 10, 0)
|
||||||
..close(),
|
..close(),
|
||||||
eyes = Path()
|
eyes = Path()
|
||||||
..addOval(const Rect.fromLTWH(12.5, 9, 4, 6))
|
..addOval(const Rect.fromLTWH(12.5, 9, 4, 6))
|
||||||
..addOval(const Rect.fromLTWH(6.5, 9, 4, 6)),
|
..addOval(const Rect.fromLTWH(6.5, 9, 4, 6)),
|
||||||
pupils = Path()
|
pupils = Path()
|
||||||
..addOval(const Rect.fromLTWH(14, 11, 2, 2))
|
..addOval(const Rect.fromLTWH(14, 11, 2, 2))
|
||||||
..addOval(const Rect.fromLTWH(8, 11, 2, 2)),
|
..addOval(const Rect.fromLTWH(8, 11, 2, 2)),
|
||||||
velocity = Vector2.zero(),
|
velocity = Vector2.zero(),
|
||||||
super(size: Vector2(20, 20), anchor: Anchor.bottomCenter);
|
super(size: Vector2(20, 20), anchor: Anchor.bottomCenter);
|
||||||
|
|
||||||
final Path body;
|
final Path body;
|
||||||
final Path eyes;
|
final Path eyes;
|
||||||
@ -144,11 +142,14 @@ class Player extends PositionComponent with KeyboardHandler {
|
|||||||
@override
|
@override
|
||||||
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
|
bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
|
||||||
final isKeyDown = event is KeyDownEvent;
|
final isKeyDown = event is KeyDownEvent;
|
||||||
final keyLeft = (event.logicalKey == LogicalKeyboardKey.arrowLeft) ||
|
final keyLeft =
|
||||||
|
(event.logicalKey == LogicalKeyboardKey.arrowLeft) ||
|
||||||
(event.logicalKey == LogicalKeyboardKey.keyA);
|
(event.logicalKey == LogicalKeyboardKey.keyA);
|
||||||
final keyRight = (event.logicalKey == LogicalKeyboardKey.arrowRight) ||
|
final keyRight =
|
||||||
|
(event.logicalKey == LogicalKeyboardKey.arrowRight) ||
|
||||||
(event.logicalKey == LogicalKeyboardKey.keyD);
|
(event.logicalKey == LogicalKeyboardKey.keyD);
|
||||||
final keyUp = (event.logicalKey == LogicalKeyboardKey.arrowUp) ||
|
final keyUp =
|
||||||
|
(event.logicalKey == LogicalKeyboardKey.arrowUp) ||
|
||||||
(event.logicalKey == LogicalKeyboardKey.keyW);
|
(event.logicalKey == LogicalKeyboardKey.keyW);
|
||||||
|
|
||||||
if (isKeyDown) {
|
if (isKeyDown) {
|
||||||
@ -161,9 +162,11 @@ class Player extends PositionComponent with KeyboardHandler {
|
|||||||
nJumpsLeft -= 1;
|
nJumpsLeft -= 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final hasLeft = keysPressed.contains(LogicalKeyboardKey.arrowLeft) ||
|
final hasLeft =
|
||||||
|
keysPressed.contains(LogicalKeyboardKey.arrowLeft) ||
|
||||||
keysPressed.contains(LogicalKeyboardKey.keyA);
|
keysPressed.contains(LogicalKeyboardKey.keyA);
|
||||||
final hasRight = keysPressed.contains(LogicalKeyboardKey.arrowRight) ||
|
final hasRight =
|
||||||
|
keysPressed.contains(LogicalKeyboardKey.arrowRight) ||
|
||||||
keysPressed.contains(LogicalKeyboardKey.keyD);
|
keysPressed.contains(LogicalKeyboardKey.keyD);
|
||||||
if (hasLeft && hasRight) {
|
if (hasLeft && hasRight) {
|
||||||
// Leave the current speed unchanged
|
// Leave the current speed unchanged
|
||||||
|
|||||||
@ -19,10 +19,10 @@ class FixedResolutionExample extends FlameGame
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
FixedResolutionExample()
|
FixedResolutionExample()
|
||||||
: super(
|
: super(
|
||||||
camera: CameraComponent.withFixedResolution(width: 600, height: 1024),
|
camera: CameraComponent.withFixedResolution(width: 600, height: 1024),
|
||||||
world: FixedResolutionWorld(),
|
world: FixedResolutionWorld(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -118,25 +118,25 @@ class TextButton extends ButtonComponent {
|
|||||||
super.anchor,
|
super.anchor,
|
||||||
TextRenderer? textRenderer,
|
TextRenderer? textRenderer,
|
||||||
}) : super(
|
}) : super(
|
||||||
button: RectangleComponent(
|
button: RectangleComponent(
|
||||||
size: Vector2(200, 100),
|
size: Vector2(200, 100),
|
||||||
paint: Paint()
|
paint: Paint()
|
||||||
..color = Colors.orange
|
..color = Colors.orange
|
||||||
..strokeWidth = 2
|
..strokeWidth = 2
|
||||||
..style = PaintingStyle.stroke,
|
..style = PaintingStyle.stroke,
|
||||||
),
|
),
|
||||||
buttonDown: RectangleComponent(
|
buttonDown: RectangleComponent(
|
||||||
size: Vector2(200, 100),
|
size: Vector2(200, 100),
|
||||||
paint: Paint()
|
paint: Paint()
|
||||||
..color = BasicPalette.orange.color.withValues(alpha: 0.5),
|
..color = BasicPalette.orange.color.withValues(alpha: 0.5),
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
TextComponent(
|
TextComponent(
|
||||||
text: text,
|
text: text,
|
||||||
textRenderer: textRenderer,
|
textRenderer: textRenderer,
|
||||||
position: Vector2(100, 50),
|
position: Vector2(100, 50),
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,12 +24,12 @@ class FollowComponentExample extends FlameGame
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
FollowComponentExample({required this.viewportResolution})
|
FollowComponentExample({required this.viewportResolution})
|
||||||
: super(
|
: super(
|
||||||
camera: CameraComponent.withFixedResolution(
|
camera: CameraComponent.withFixedResolution(
|
||||||
width: viewportResolution.x,
|
width: viewportResolution.x,
|
||||||
height: viewportResolution.y,
|
height: viewportResolution.y,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
late MovableEmber ember;
|
late MovableEmber ember;
|
||||||
final Vector2 viewportResolution;
|
final Vector2 viewportResolution;
|
||||||
@ -182,12 +182,12 @@ class Map extends Component {
|
|||||||
|
|
||||||
class Rock extends SpriteComponent with HasGameReference, TapCallbacks {
|
class Rock extends SpriteComponent with HasGameReference, TapCallbacks {
|
||||||
Rock(Vector2 position)
|
Rock(Vector2 position)
|
||||||
: super(
|
: super(
|
||||||
position: position,
|
position: position,
|
||||||
size: Vector2.all(50),
|
size: Vector2.all(50),
|
||||||
priority: 1,
|
priority: 1,
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -22,12 +22,12 @@ class StaticComponentsExample extends FlameGame
|
|||||||
StaticComponentsExample({
|
StaticComponentsExample({
|
||||||
required Vector2 viewportResolution,
|
required Vector2 viewportResolution,
|
||||||
}) : super(
|
}) : super(
|
||||||
camera: CameraComponent.withFixedResolution(
|
camera: CameraComponent.withFixedResolution(
|
||||||
width: viewportResolution.x,
|
width: viewportResolution.x,
|
||||||
height: viewportResolution.y,
|
height: viewportResolution.y,
|
||||||
),
|
),
|
||||||
world: _StaticComponentWorld(),
|
world: _StaticComponentWorld(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
|
|||||||
@ -12,10 +12,10 @@ class CirclesExample extends FlameGame {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
CirclesExample()
|
CirclesExample()
|
||||||
: super(
|
: super(
|
||||||
camera: CameraComponent.withFixedResolution(width: 600, height: 400),
|
camera: CameraComponent.withFixedResolution(width: 600, height: 400),
|
||||||
world: MyWorld(),
|
world: MyWorld(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyWorld extends World with TapCallbacks, HasCollisionDetection {
|
class MyWorld extends World with TapCallbacks, HasCollisionDetection {
|
||||||
@ -30,7 +30,7 @@ class MyWorld extends World with TapCallbacks, HasCollisionDetection {
|
|||||||
class MyCollidable extends PositionComponent
|
class MyCollidable extends PositionComponent
|
||||||
with HasGameReference<CirclesExample>, CollisionCallbacks {
|
with HasGameReference<CirclesExample>, CollisionCallbacks {
|
||||||
MyCollidable({super.position})
|
MyCollidable({super.position})
|
||||||
: super(size: Vector2.all(30), anchor: Anchor.center);
|
: super(size: Vector2.all(30), anchor: Anchor.center);
|
||||||
|
|
||||||
late Vector2 velocity;
|
late Vector2 velocity;
|
||||||
final _collisionColor = Colors.amber;
|
final _collisionColor = Colors.amber;
|
||||||
|
|||||||
@ -62,11 +62,11 @@ class AnimatedComponent extends SpriteAnimationComponent
|
|||||||
Vector2 size, {
|
Vector2 size, {
|
||||||
double angle = -pi / 4,
|
double angle = -pi / 4,
|
||||||
}) : super(
|
}) : super(
|
||||||
position: position,
|
position: position,
|
||||||
size: size,
|
size: size,
|
||||||
angle: angle,
|
angle: angle,
|
||||||
anchor: Anchor.center,
|
anchor: Anchor.center,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onLoad() async {
|
Future<void> onLoad() async {
|
||||||
@ -82,15 +82,15 @@ class AnimatedComponent extends SpriteAnimationComponent
|
|||||||
..style = PaintingStyle.stroke;
|
..style = PaintingStyle.stroke;
|
||||||
add(
|
add(
|
||||||
PolygonHitbox.relative(
|
PolygonHitbox.relative(
|
||||||
[
|
[
|
||||||
Vector2(0.0, -1.0),
|
Vector2(0.0, -1.0),
|
||||||
Vector2(-1.0, -0.1),
|
Vector2(-1.0, -0.1),
|
||||||
Vector2(-0.2, 0.4),
|
Vector2(-0.2, 0.4),
|
||||||
Vector2(0.2, 0.4),
|
Vector2(0.2, 0.4),
|
||||||
Vector2(1.0, -0.1),
|
Vector2(1.0, -0.1),
|
||||||
],
|
],
|
||||||
parentSize: size,
|
parentSize: size,
|
||||||
)
|
)
|
||||||
..paint = hitboxPaint
|
..paint = hitboxPaint
|
||||||
..renderShape = true,
|
..renderShape = true,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -19,8 +19,9 @@ void addCollisionDetectionStories(Dashbook dashbook) {
|
|||||||
..add(
|
..add(
|
||||||
'Collidable AnimationComponent',
|
'Collidable AnimationComponent',
|
||||||
(_) => GameWidget(game: CollidableAnimationExample()),
|
(_) => GameWidget(game: CollidableAnimationExample()),
|
||||||
codeLink:
|
codeLink: baseLink(
|
||||||
baseLink('collision_detection/collidable_animation_example.dart'),
|
'collision_detection/collidable_animation_example.dart',
|
||||||
|
),
|
||||||
info: CollidableAnimationExample.description,
|
info: CollidableAnimationExample.description,
|
||||||
)
|
)
|
||||||
..add(
|
..add(
|
||||||
@ -74,8 +75,9 @@ void addCollisionDetectionStories(Dashbook dashbook) {
|
|||||||
..add(
|
..add(
|
||||||
'Raycasting Max Distance',
|
'Raycasting Max Distance',
|
||||||
(_) => GameWidget(game: RaycastMaxDistanceExample()),
|
(_) => GameWidget(game: RaycastMaxDistanceExample()),
|
||||||
codeLink:
|
codeLink: baseLink(
|
||||||
baseLink('collision_detection/raycast_max_distance_example.dart'),
|
'collision_detection/raycast_max_distance_example.dart',
|
||||||
|
),
|
||||||
info: RaycastMaxDistanceExample.description,
|
info: RaycastMaxDistanceExample.description,
|
||||||
)
|
)
|
||||||
..add(
|
..add(
|
||||||
|
|||||||
@ -25,10 +25,10 @@ class MultipleShapesExample extends FlameGame with HasCollisionDetection {
|
|||||||
''';
|
''';
|
||||||
|
|
||||||
MultipleShapesExample()
|
MultipleShapesExample()
|
||||||
: super(
|
: super(
|
||||||
world: MultiShapesWorld(),
|
world: MultiShapesWorld(),
|
||||||
camera: CameraComponent()..viewfinder.anchor = Anchor.topLeft,
|
camera: CameraComponent()..viewfinder.anchor = Anchor.topLeft,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiShapesWorld extends World with HasGameReference {
|
class MultiShapesWorld extends World with HasGameReference {
|
||||||
@ -67,7 +67,8 @@ class MultiShapesWorld extends World with HasGameReference {
|
|||||||
ScreenHitbox screenHitbox,
|
ScreenHitbox screenHitbox,
|
||||||
) {
|
) {
|
||||||
final collidableSize = Vector2.all(50) + Vector2.random(_rng) * 100;
|
final collidableSize = Vector2.all(50) + Vector2.random(_rng) * 100;
|
||||||
final isXOverflow = lastCollidable.position.x +
|
final isXOverflow =
|
||||||
|
lastCollidable.position.x +
|
||||||
lastCollidable.size.x / 2 +
|
lastCollidable.size.x / 2 +
|
||||||
_distance.x +
|
_distance.x +
|
||||||
collidableSize.x >
|
collidableSize.x >
|
||||||
@ -223,7 +224,7 @@ class SnowmanPart extends CircleHitbox {
|
|||||||
final Color hitColor;
|
final Color hitColor;
|
||||||
|
|
||||||
SnowmanPart(double radius, Vector2 position, this.hitColor)
|
SnowmanPart(double radius, Vector2 position, this.hitColor)
|
||||||
: super(radius: radius, position: position, anchor: Anchor.center) {
|
: super(radius: radius, position: position, anchor: Anchor.center) {
|
||||||
paint.color = startColor;
|
paint.color = startColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,12 +289,23 @@ MyCollidable randomCollidable(
|
|||||||
final rotationSpeed = 0.5 - rng.nextDouble();
|
final rotationSpeed = 0.5 - rng.nextDouble();
|
||||||
final shapeType = Shapes.values[rng.nextInt(Shapes.values.length)];
|
final shapeType = Shapes.values[rng.nextInt(Shapes.values.length)];
|
||||||
return switch (shapeType) {
|
return switch (shapeType) {
|
||||||
Shapes.circle => CollidableCircle(position, size, velocity, screenHitbox)
|
Shapes.circle => CollidableCircle(
|
||||||
..rotationSpeed = rotationSpeed,
|
position,
|
||||||
Shapes.rectangle =>
|
size,
|
||||||
CollidableRectangle(position, size, velocity, screenHitbox)
|
velocity,
|
||||||
..rotationSpeed = rotationSpeed,
|
screenHitbox,
|
||||||
Shapes.polygon => CollidablePolygon(position, size, velocity, screenHitbox)
|
)..rotationSpeed = rotationSpeed,
|
||||||
..rotationSpeed = rotationSpeed,
|
Shapes.rectangle => CollidableRectangle(
|
||||||
|
position,
|
||||||
|
size,
|
||||||
|
velocity,
|
||||||
|
screenHitbox,
|
||||||
|
)..rotationSpeed = rotationSpeed,
|
||||||
|
Shapes.polygon => CollidablePolygon(
|
||||||
|
position,
|
||||||
|
size,
|
||||||
|
velocity,
|
||||||
|
screenHitbox,
|
||||||
|
)..rotationSpeed = rotationSpeed,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user