mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-11-01 01:18:38 +08:00 
			
		
		
		
	 fabbf928d0
			
		
	
	fabbf928d0
	
	
	
		
			
			Enable DCM rule double-literal-format. More details [here](https://dcm.dev/docs/rules/common/double-literal-format/). This both forbids trailing zeroes and mandates leading zeroes. If we would prefer a different style (e.g. prefer no leading zero instead), just lmk :)
		
			
				
	
	
		
			187 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:flame/components.dart';
 | |
| import 'package:flame/events.dart';
 | |
| import 'package:flame/experimental.dart';
 | |
| import 'package:flame/game.dart';
 | |
| import 'package:flame/input.dart';
 | |
| import 'package:flame/parallax.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| void main() {
 | |
|   runApp(GameWidget(game: SpaceShooterGame()));
 | |
| }
 | |
| 
 | |
| class SpaceShooterGame extends FlameGame with PanDetector {
 | |
|   late Player player;
 | |
| 
 | |
|   @override
 | |
|   Future<void> onLoad() async {
 | |
|     final parallax = await loadParallaxComponent(
 | |
|       [
 | |
|         ParallaxImageData('stars_0.png'),
 | |
|         ParallaxImageData('stars_1.png'),
 | |
|         ParallaxImageData('stars_2.png'),
 | |
|       ],
 | |
|       baseVelocity: Vector2(0, -5),
 | |
|       repeat: ImageRepeat.repeat,
 | |
|       velocityMultiplierDelta: Vector2(0, 5),
 | |
|     );
 | |
|     add(parallax);
 | |
| 
 | |
|     player = Player();
 | |
|     add(player);
 | |
| 
 | |
|     add(
 | |
|       SpawnComponent(
 | |
|         factory: (index) {
 | |
|           return Enemy();
 | |
|         },
 | |
|         period: 1,
 | |
|         area: Rectangle.fromLTWH(0, 0, size.x, -Enemy.enemySize),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void onPanUpdate(DragUpdateInfo info) {
 | |
|     player.move(info.delta.global);
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void onPanStart(DragStartInfo info) {
 | |
|     player.startShooting();
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void onPanEnd(DragEndInfo info) {
 | |
|     player.stopShooting();
 | |
|   }
 | |
| }
 | |
| 
 | |
| class Player extends SpriteAnimationComponent
 | |
|     with HasGameReference<SpaceShooterGame> {
 | |
|   Player()
 | |
|       : super(
 | |
|           size: Vector2(100, 150),
 | |
|           anchor: Anchor.center,
 | |
|         );
 | |
| 
 | |
|   late final SpawnComponent _bulletSpawner;
 | |
| 
 | |
|   @override
 | |
|   Future<void> onLoad() async {
 | |
|     await super.onLoad();
 | |
| 
 | |
|     animation = await game.loadSpriteAnimation(
 | |
|       'player.png',
 | |
|       SpriteAnimationData.sequenced(
 | |
|         amount: 4,
 | |
|         stepTime: 0.2,
 | |
|         textureSize: Vector2(32, 48),
 | |
|       ),
 | |
|     );
 | |
| 
 | |
|     position = game.size / 2;
 | |
| 
 | |
|     _bulletSpawner = SpawnComponent(
 | |
|       period: 0.2,
 | |
|       selfPositioning: true,
 | |
|       factory: (index) {
 | |
|         return Bullet(
 | |
|           position: position +
 | |
|               Vector2(
 | |
|                 0,
 | |
|                 -height / 2,
 | |
|               ),
 | |
|         );
 | |
|       },
 | |
|       autoStart: false,
 | |
|     );
 | |
| 
 | |
|     game.add(_bulletSpawner);
 | |
|   }
 | |
| 
 | |
|   void move(Vector2 delta) {
 | |
|     position.add(delta);
 | |
|   }
 | |
| 
 | |
|   void startShooting() {
 | |
|     _bulletSpawner.timer.start();
 | |
|   }
 | |
| 
 | |
|   void stopShooting() {
 | |
|     _bulletSpawner.timer.stop();
 | |
|   }
 | |
| }
 | |
| 
 | |
| class Bullet extends SpriteAnimationComponent
 | |
|     with HasGameReference<SpaceShooterGame> {
 | |
|   Bullet({
 | |
|     super.position,
 | |
|   }) : super(
 | |
|           size: Vector2(25, 50),
 | |
|           anchor: Anchor.center,
 | |
|         );
 | |
| 
 | |
|   @override
 | |
|   Future<void> onLoad() async {
 | |
|     await super.onLoad();
 | |
| 
 | |
|     animation = await game.loadSpriteAnimation(
 | |
|       'bullet.png',
 | |
|       SpriteAnimationData.sequenced(
 | |
|         amount: 4,
 | |
|         stepTime: 0.2,
 | |
|         textureSize: Vector2(8, 16),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void update(double dt) {
 | |
|     super.update(dt);
 | |
| 
 | |
|     position.y += dt * -500;
 | |
| 
 | |
|     if (position.y < -height) {
 | |
|       removeFromParent();
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| class Enemy extends SpriteAnimationComponent
 | |
|     with HasGameReference<SpaceShooterGame> {
 | |
|   Enemy({
 | |
|     super.position,
 | |
|   }) : super(
 | |
|           size: Vector2.all(enemySize),
 | |
|           anchor: Anchor.center,
 | |
|         );
 | |
| 
 | |
|   static const enemySize = 50.0;
 | |
| 
 | |
|   @override
 | |
|   Future<void> onLoad() async {
 | |
|     await super.onLoad();
 | |
| 
 | |
|     animation = await game.loadSpriteAnimation(
 | |
|       'enemy.png',
 | |
|       SpriteAnimationData.sequenced(
 | |
|         amount: 4,
 | |
|         stepTime: 0.2,
 | |
|         textureSize: Vector2.all(16),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void update(double dt) {
 | |
|     super.update(dt);
 | |
| 
 | |
|     position.y += dt * 250;
 | |
| 
 | |
|     if (position.y > game.size.y) {
 | |
|       removeFromParent();
 | |
|     }
 | |
|   }
 | |
| }
 |