mirror of
				https://github.com/flame-engine/flame.git
				synced 2025-10-31 08:56:01 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'dart:math' as math;
 | |
| import 'dart:ui';
 | |
| 
 | |
| import 'package:flame/collisions.dart';
 | |
| import 'package:flame/components.dart';
 | |
| import 'package:flame/game.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| class BouncingBallExample extends FlameGame with HasCollisionDetection {
 | |
|   static const description = '''
 | |
|     This example shows how you can use the Collisions detection api to know when a ball
 | |
|     collides with the screen boundaries and then update it to bounce off these boundaries.
 | |
|   ''';
 | |
|   @override
 | |
|   void onLoad() {
 | |
|     addAll([
 | |
|       ScreenHitbox(),
 | |
|       Ball(),
 | |
|     ]);
 | |
|   }
 | |
| }
 | |
| 
 | |
| class Ball extends CircleComponent
 | |
|     with HasGameReference<FlameGame>, CollisionCallbacks {
 | |
|   late Vector2 velocity;
 | |
| 
 | |
|   Ball() {
 | |
|     paint = Paint()..color = Colors.white;
 | |
|     radius = 10;
 | |
|   }
 | |
| 
 | |
|   static const double speed = 500;
 | |
|   static const degree = math.pi / 180;
 | |
| 
 | |
|   @override
 | |
|   Future<void> onLoad() async {
 | |
|     super.onLoad();
 | |
|     _resetBall;
 | |
|     final hitBox = CircleHitbox(
 | |
|       radius: radius,
 | |
|     );
 | |
| 
 | |
|     addAll([
 | |
|       hitBox,
 | |
|     ]);
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void update(double dt) {
 | |
|     super.update(dt);
 | |
|     position += velocity * dt;
 | |
|   }
 | |
| 
 | |
|   void get _resetBall {
 | |
|     position = game.size / 2;
 | |
|     final spawnAngle = getSpawnAngle;
 | |
| 
 | |
|     final vx = math.cos(spawnAngle * degree) * speed;
 | |
|     final vy = math.sin(spawnAngle * degree) * speed;
 | |
|     velocity = Vector2(
 | |
|       vx,
 | |
|       vy,
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   double get getSpawnAngle {
 | |
|     final random = math.Random().nextDouble();
 | |
|     final spawnAngle = lerpDouble(0, 360, random)!;
 | |
| 
 | |
|     return spawnAngle;
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void onCollisionStart(
 | |
|     Set<Vector2> intersectionPoints,
 | |
|     PositionComponent other,
 | |
|   ) {
 | |
|     super.onCollisionStart(intersectionPoints, other);
 | |
| 
 | |
|     if (other is ScreenHitbox) {
 | |
|       final collisionPoint = intersectionPoints.first;
 | |
| 
 | |
|       // Left Side Collision
 | |
|       if (collisionPoint.x == 0) {
 | |
|         velocity.x = -velocity.x;
 | |
|         velocity.y = velocity.y;
 | |
|       }
 | |
|       // Right Side Collision
 | |
|       if (collisionPoint.x == game.size.x) {
 | |
|         velocity.x = -velocity.x;
 | |
|         velocity.y = velocity.y;
 | |
|       }
 | |
|       // Top Side Collision
 | |
|       if (collisionPoint.y == 0) {
 | |
|         velocity.x = velocity.x;
 | |
|         velocity.y = -velocity.y;
 | |
|       }
 | |
|       // Bottom Side Collision
 | |
|       if (collisionPoint.y == game.size.y) {
 | |
|         velocity.x = velocity.x;
 | |
|         velocity.y = -velocity.y;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | 
