mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds basic support for joints in sprite physics
This commit is contained in:
parent
56ac0d9cc7
commit
95a0aceaa1
@ -230,6 +230,8 @@ class PhysicsBody {
|
||||
|
||||
box2d.Body _body;
|
||||
|
||||
List<PhysicsJoint> _joints = [];
|
||||
|
||||
bool _attached = false;
|
||||
|
||||
void applyForce(Offset force, Point worldPoint) {
|
||||
@ -338,6 +340,13 @@ class PhysicsBody {
|
||||
_node = node;
|
||||
|
||||
_attached = true;
|
||||
|
||||
// Attach any joints
|
||||
for (PhysicsJoint joint in _joints) {
|
||||
if (joint.bodyA._attached && joint.bodyB._attached) {
|
||||
joint._attach(physicsNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _detach() {
|
||||
|
||||
90
packages/flutter_sprites/lib/physics_joint.dart
Normal file
90
packages/flutter_sprites/lib/physics_joint.dart
Normal file
@ -0,0 +1,90 @@
|
||||
part of skysprites;
|
||||
|
||||
abstract class PhysicsJoint {
|
||||
PhysicsJoint(this.bodyA, this.bodyB) {
|
||||
bodyA._joints.add(this);
|
||||
bodyB._joints.add(this);
|
||||
|
||||
if (bodyA._attached && bodyB._attached) {
|
||||
_attach(bodyA._physicsNode);
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsBody bodyA;
|
||||
PhysicsBody bodyB;
|
||||
|
||||
bool _active = true;
|
||||
box2d.Joint _joint;
|
||||
|
||||
PhysicsNode _physicsNode;
|
||||
|
||||
void _attach(PhysicsNode physicsNode) {
|
||||
if (_joint == null) {
|
||||
_physicsNode = physicsNode;
|
||||
_joint = _createB2Joint(physicsNode);
|
||||
}
|
||||
}
|
||||
|
||||
void _detach() {
|
||||
if (_joint != null && _active) {
|
||||
_physicsNode.b2World.destroyJoint(_joint);
|
||||
_joint = null;
|
||||
}
|
||||
_active = false;
|
||||
}
|
||||
|
||||
box2d.Joint _createB2Joint(PhysicsNode physicsNode);
|
||||
}
|
||||
|
||||
class PhysicsJointRevolute extends PhysicsJoint {
|
||||
PhysicsJointRevolute(
|
||||
PhysicsBody bodyA,
|
||||
PhysicsBody bodyB,
|
||||
this.anchorWorld, {
|
||||
double lowerAngle: 0.0,
|
||||
double upperAngle: 0.0,
|
||||
bool enableLimit: false
|
||||
}) : super(bodyA, bodyB) {
|
||||
this.lowerAngle = lowerAngle;
|
||||
this.upperAngle = upperAngle;
|
||||
this.enableLimit = enableLimit;
|
||||
}
|
||||
|
||||
Point anchorWorld;
|
||||
double lowerAngle;
|
||||
double upperAngle;
|
||||
bool enableLimit;
|
||||
|
||||
box2d.Joint _createB2Joint(PhysicsNode physicsNode) {
|
||||
// Create Joint Definition
|
||||
Vector2 vecAnchor = new Vector2(
|
||||
anchorWorld.x / physicsNode.b2WorldToNodeConversionFactor,
|
||||
anchorWorld.y / physicsNode.b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
box2d.RevoluteJointDef b2Def = new box2d.RevoluteJointDef();
|
||||
b2Def.initialize(bodyA._body, bodyB._body, vecAnchor);
|
||||
b2Def.enableLimit = enableLimit;
|
||||
b2Def.lowerAngle = lowerAngle;
|
||||
b2Def.upperAngle = upperAngle;
|
||||
|
||||
// Create joint
|
||||
return physicsNode.b2World.createJoint(b2Def);
|
||||
}
|
||||
}
|
||||
|
||||
class PhysicsJointWeld extends PhysicsJoint {
|
||||
PhysicsJointWeld(
|
||||
PhysicsBody bodyA,
|
||||
PhysicsBody bodyB) : super(bodyA, bodyB);
|
||||
|
||||
box2d.Joint _createB2Joint(PhysicsNode physicsNode) {
|
||||
box2d.WeldJointDef b2Def = new box2d.WeldJointDef();
|
||||
Vector2 middle = new Vector2(
|
||||
(bodyA._body.position.x + bodyB._body.position.x) / 2.0,
|
||||
(bodyA._body.position.y + bodyB._body.position.y) / 2.0
|
||||
);
|
||||
b2Def.initialize(bodyA._body, bodyB._body, middle);
|
||||
return physicsNode.b2World.createJoint(b2Def);
|
||||
}
|
||||
}
|
||||
@ -83,6 +83,13 @@ class PhysicsNode extends Node {
|
||||
|
||||
void _removeBodiesScheduledForDestruction() {
|
||||
for (box2d.Body b2Body in _bodiesScheduledForDestruction) {
|
||||
// Destroy any joints before destroying the body
|
||||
PhysicsBody body = b2Body.userData;
|
||||
for (PhysicsJoint joint in body._joints) {
|
||||
joint._detach();
|
||||
}
|
||||
|
||||
// Destroy the body
|
||||
b2World.destroyBody(b2Body);
|
||||
}
|
||||
_bodiesScheduledForDestruction.clear();
|
||||
|
||||
@ -33,6 +33,7 @@ part 'node3d.dart';
|
||||
part 'node_with_size.dart';
|
||||
part 'particle_system.dart';
|
||||
part 'physics_body.dart';
|
||||
part 'physics_joint.dart';
|
||||
part 'physics_node.dart';
|
||||
part 'physics_shape.dart';
|
||||
part 'sound.dart';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user