mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 11:43:19 +08:00
Example showcasing how to use the ContactCallback
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -10,6 +10,8 @@ pubspec.lock
|
|||||||
doc/api/
|
doc/api/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
.vscode/
|
.vscode/
|
||||||
|
**/.flutter-plugins
|
||||||
|
**/.flutter-plugins-dependencies
|
||||||
|
|
||||||
android/
|
android/
|
||||||
ios/
|
ios/
|
||||||
|
|||||||
70
doc/examples/box2d/contact_callbacks/.gitignore
vendored
Normal file
70
doc/examples/box2d/contact_callbacks/.gitignore
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Visual Studio Code related
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Android related
|
||||||
|
**/android/**/gradle-wrapper.jar
|
||||||
|
**/android/.gradle
|
||||||
|
**/android/captures/
|
||||||
|
**/android/gradlew
|
||||||
|
**/android/gradlew.bat
|
||||||
|
**/android/local.properties
|
||||||
|
**/android/**/GeneratedPluginRegistrant.java
|
||||||
|
|
||||||
|
# iOS/XCode related
|
||||||
|
**/ios/**/*.mode1v3
|
||||||
|
**/ios/**/*.mode2v3
|
||||||
|
**/ios/**/*.moved-aside
|
||||||
|
**/ios/**/*.pbxuser
|
||||||
|
**/ios/**/*.perspectivev3
|
||||||
|
**/ios/**/*sync/
|
||||||
|
**/ios/**/.sconsign.dblite
|
||||||
|
**/ios/**/.tags*
|
||||||
|
**/ios/**/.vagrant/
|
||||||
|
**/ios/**/DerivedData/
|
||||||
|
**/ios/**/Icon?
|
||||||
|
**/ios/**/Pods/
|
||||||
|
**/ios/**/.symlinks/
|
||||||
|
**/ios/**/profile
|
||||||
|
**/ios/**/xcuserdata
|
||||||
|
**/ios/.generated/
|
||||||
|
**/ios/Flutter/App.framework
|
||||||
|
**/ios/Flutter/Flutter.framework
|
||||||
|
**/ios/Flutter/Generated.xcconfig
|
||||||
|
**/ios/Flutter/app.flx
|
||||||
|
**/ios/Flutter/app.zip
|
||||||
|
**/ios/Flutter/flutter_assets/
|
||||||
|
**/ios/ServiceDefinitions.json
|
||||||
|
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# Exceptions to above rules.
|
||||||
|
!**/ios/**/default.mode1v3
|
||||||
|
!**/ios/**/default.mode2v3
|
||||||
|
!**/ios/**/default.pbxuser
|
||||||
|
!**/ios/**/default.perspectivev3
|
||||||
|
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||||
10
doc/examples/box2d/contact_callbacks/.metadata
Normal file
10
doc/examples/box2d/contact_callbacks/.metadata
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: 7fc14a55af64462763d28abfb4e610086c6e0f39
|
||||||
|
channel: dev
|
||||||
|
|
||||||
|
project_type: app
|
||||||
4
doc/examples/box2d/contact_callbacks/README.md
Normal file
4
doc/examples/box2d/contact_callbacks/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# box2d contact callbacks
|
||||||
|
|
||||||
|
A Flame game showcasing how to use box2d_game's contact callbacks.
|
||||||
|
Balls will bounce around and change colour when they come in contact.
|
||||||
57
doc/examples/box2d/contact_callbacks/lib/boundaries.dart
Normal file
57
doc/examples/box2d/contact_callbacks/lib/boundaries.dart
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:box2d_flame/box2d.dart';
|
||||||
|
import 'package:flame/box2d/box2d_component.dart';
|
||||||
|
import 'package:flame/box2d/viewport.dart';
|
||||||
|
import 'package:flame/palette.dart';
|
||||||
|
|
||||||
|
List<Wall> createBoundaries(Box2DComponent box) {
|
||||||
|
final Viewport viewport = box.viewport;
|
||||||
|
final Vector2 screenSize = Vector2(viewport.width, viewport.height)
|
||||||
|
*viewport.scale;
|
||||||
|
final Vector2 topLeft = viewport.getScreenToWorld(Vector2.zero());
|
||||||
|
final Vector2 bottomRight = viewport.getScreenToWorld(screenSize);
|
||||||
|
final Vector2 topRight = Vector2(bottomRight.x, topLeft.y);
|
||||||
|
final Vector2 bottomLeft = Vector2(topLeft.x, bottomRight.y);
|
||||||
|
|
||||||
|
return [
|
||||||
|
Wall(topLeft, topRight, box),
|
||||||
|
Wall(topRight, bottomRight, box),
|
||||||
|
Wall(bottomRight, bottomLeft, box),
|
||||||
|
Wall(bottomLeft, topLeft, box),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Wall extends BodyComponent {
|
||||||
|
Paint paint = BasicPalette.white.paint;
|
||||||
|
final Vector2 start;
|
||||||
|
final Vector2 end;
|
||||||
|
|
||||||
|
Wall(this.start, this.end, Box2DComponent box) : super(box) {
|
||||||
|
_createBody(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void renderPolygon(Canvas canvas, List<Offset> coordinates) {
|
||||||
|
Offset start = coordinates[0];
|
||||||
|
Offset end = coordinates[1];
|
||||||
|
canvas.drawLine(start, end, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _createBody(Vector2 start, Vector2 end) {
|
||||||
|
final PolygonShape shape = PolygonShape();
|
||||||
|
shape.setAsEdge(start, end);
|
||||||
|
|
||||||
|
final fixtureDef = FixtureDef();
|
||||||
|
fixtureDef.setUserData(this); // To be able to determine object in collision
|
||||||
|
fixtureDef.shape = shape;
|
||||||
|
fixtureDef.restitution = 0.0;
|
||||||
|
fixtureDef.friction = 0.1;
|
||||||
|
|
||||||
|
final bodyDef = BodyDef();
|
||||||
|
bodyDef.position = Vector2.zero();
|
||||||
|
bodyDef.type = BodyType.STATIC;
|
||||||
|
|
||||||
|
body = world.createBody(bodyDef)..createFixtureFromFixtureDef(fixtureDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
122
doc/examples/box2d/contact_callbacks/lib/main.dart
Normal file
122
doc/examples/box2d/contact_callbacks/lib/main.dart
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import 'dart:math' as math;
|
||||||
|
import 'package:box2d_contact_callbacks/boundaries.dart';
|
||||||
|
import 'package:flame/box2d/box2d_component.dart';
|
||||||
|
import 'package:flame/box2d/box2d_game.dart';
|
||||||
|
import 'package:flame/box2d/contact_listeners.dart';
|
||||||
|
import 'package:flame/flame.dart';
|
||||||
|
import 'package:flame/palette.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:box2d_flame/box2d.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await Flame.util.fullScreen();
|
||||||
|
runApp(GameController().widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ball extends BodyComponent {
|
||||||
|
Paint originalPaint, currentPaint;
|
||||||
|
|
||||||
|
Ball(Vector2 position, Box2DComponent box) : super(box) {
|
||||||
|
originalPaint = _randomPaint();
|
||||||
|
currentPaint = originalPaint;
|
||||||
|
Vector2 worldPosition = viewport.getScreenToWorld(position);
|
||||||
|
_createBody(5.0, worldPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
Paint _randomPaint() {
|
||||||
|
math.Random rng = math.Random();
|
||||||
|
return PaletteEntry(Color.fromARGB(rng.nextInt(255), rng.nextInt(255),
|
||||||
|
rng.nextInt(255), rng.nextInt(255))).paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _createBody(double radius, Vector2 position) {
|
||||||
|
final CircleShape shape = CircleShape();
|
||||||
|
shape.radius = radius;
|
||||||
|
|
||||||
|
final fixtureDef = FixtureDef();
|
||||||
|
// To be able to determine object in collision
|
||||||
|
fixtureDef.setUserData(this);
|
||||||
|
fixtureDef.shape = shape;
|
||||||
|
fixtureDef.restitution = 1.0;
|
||||||
|
fixtureDef.density = 1.0;
|
||||||
|
fixtureDef.friction = 0.1;
|
||||||
|
|
||||||
|
final bodyDef = BodyDef();
|
||||||
|
bodyDef.position = position;
|
||||||
|
bodyDef.type = BodyType.DYNAMIC;
|
||||||
|
|
||||||
|
body = world.createBody(bodyDef)..createFixtureFromFixtureDef(fixtureDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool destroy() {
|
||||||
|
// Implement your logic for when the component should be removed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void renderCircle(Canvas c, Offset p, double radius) {
|
||||||
|
Paint blue = PaletteEntry(Colors.blue).paint;
|
||||||
|
c.drawCircle(p, radius, currentPaint);
|
||||||
|
double angle = body.getAngle();
|
||||||
|
Offset lineRotation =
|
||||||
|
Offset(math.sin(angle) * radius, math.cos(angle) * radius);
|
||||||
|
c.drawLine(p, p + lineRotation, blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BallContactCallback implements ContactCallback {
|
||||||
|
@override
|
||||||
|
List<Type> objects = [Ball, Ball];
|
||||||
|
|
||||||
|
BallContactCallback();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void begin(Object contact1, Object contact2) {
|
||||||
|
Ball ball1 = contact1 as Ball;
|
||||||
|
Ball ball2 = contact2 as Ball;
|
||||||
|
if (ball1.currentPaint != ball1.originalPaint) {
|
||||||
|
ball1.currentPaint = ball2.currentPaint;
|
||||||
|
} else {
|
||||||
|
ball2.currentPaint = ball1.currentPaint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void end(Object ship, Object material) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyGame extends Box2DGame {
|
||||||
|
MyGame(Box2DComponent box) : super(box) {
|
||||||
|
final List<BodyComponent> boundaries = createBoundaries(box);
|
||||||
|
boundaries.forEach(add);
|
||||||
|
addContactCallback(BallContactCallback());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownDetails details) {
|
||||||
|
super.onTapDown(details);
|
||||||
|
final Vector2 position =
|
||||||
|
Vector2(details.globalPosition.dx, details.globalPosition.dy);
|
||||||
|
add(Ball(position, box));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyBox2D extends Box2DComponent {
|
||||||
|
MyBox2D() : super(scale: 4.0, gravity: -10.0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initializeWorld() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GameController {
|
||||||
|
MyGame _game;
|
||||||
|
|
||||||
|
GameController() {
|
||||||
|
final MyBox2D box = MyBox2D();
|
||||||
|
_game = MyGame(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget get widget => _game.widget;
|
||||||
|
}
|
||||||
17
doc/examples/box2d/contact_callbacks/pubspec.yaml
Normal file
17
doc/examples/box2d/contact_callbacks/pubspec.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: box2d_contact_callbacks
|
||||||
|
description: Flame sample game showcasing the structure for box2d games
|
||||||
|
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.1.0 <3.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
flame:
|
||||||
|
path: ../../../../
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
Reference in New Issue
Block a user