mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds sprite physics groups
This commit is contained in:
parent
e37f67dea0
commit
91b1cf9d14
@ -35,6 +35,7 @@ part 'src/node_with_size.dart';
|
||||
part 'src/particle_system.dart';
|
||||
part 'src/physics_body.dart';
|
||||
part 'src/physics_debug.dart';
|
||||
part 'src/physics_group.dart';
|
||||
part 'src/physics_joint.dart';
|
||||
part 'src/physics_shape.dart';
|
||||
part 'src/physics_world.dart';
|
||||
|
||||
@ -132,9 +132,8 @@ class Node {
|
||||
void set rotation(double rotation) {
|
||||
assert(rotation != null);
|
||||
|
||||
if (_physicsBody != null && parent is PhysicsWorld) {
|
||||
PhysicsWorld physicsNode = parent;
|
||||
physicsNode._updateRotation(this.physicsBody, rotation);
|
||||
if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
|
||||
_updatePhysicsRotation(physicsBody, rotation, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -142,6 +141,19 @@ class Node {
|
||||
invalidateTransformMatrix();
|
||||
}
|
||||
|
||||
void _updatePhysicsRotation(PhysicsBody body, double rotation, Node physicsParent) {
|
||||
if (physicsParent == null) return;
|
||||
|
||||
if (physicsParent is PhysicsWorld) {
|
||||
PhysicsWorld world = physicsParent;
|
||||
world._updateRotation(body, rotation);
|
||||
} else if (physicsParent is PhysicsGroup) {
|
||||
_updatePhysicsRotation(body, rotation + physicsParent.rotation, physicsParent.parent);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void _setRotationFromPhysics(double rotation) {
|
||||
assert(rotation != null);
|
||||
_rotation = rotation;
|
||||
@ -166,9 +178,8 @@ class Node {
|
||||
void set position(Point position) {
|
||||
assert(position != null);
|
||||
|
||||
if (_physicsBody != null && parent is PhysicsWorld) {
|
||||
PhysicsWorld physicsNode = parent;
|
||||
physicsNode._updatePosition(this.physicsBody, position);
|
||||
if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
|
||||
_updatePhysicsPosition(this.physicsBody, position, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -176,6 +187,20 @@ class Node {
|
||||
invalidateTransformMatrix();
|
||||
}
|
||||
|
||||
void _updatePhysicsPosition(PhysicsBody body, Point position, Node physicsParent) {
|
||||
if (physicsParent == null) return;
|
||||
|
||||
if (physicsParent is PhysicsWorld) {
|
||||
PhysicsWorld world = physicsParent;
|
||||
world._updatePosition(body, position);
|
||||
} else if (physicsParent is PhysicsGroup) {
|
||||
Vector4 parentPos = physicsParent.transformMatrix.transform(new Vector4(position.x, position.y, 0.0, 1.0));
|
||||
_updatePhysicsPosition(body, new Point(parentPos.x, parentPos.y), physicsParent.parent);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void _setPositionFromPhysics(Point position) {
|
||||
assert(position != null);
|
||||
_position = position;
|
||||
@ -310,6 +335,7 @@ class Node {
|
||||
void addChild(Node child) {
|
||||
assert(child != null);
|
||||
assert(child._parent == null);
|
||||
assert(!(child is PhysicsGroup) || this is PhysicsGroup || this is PhysicsWorld);
|
||||
|
||||
_childrenNeedSorting = true;
|
||||
_children.add(child);
|
||||
@ -318,6 +344,10 @@ class Node {
|
||||
_childrenLastAddedOrder += 1;
|
||||
child._addedOrder = _childrenLastAddedOrder;
|
||||
if (_spriteBox != null) _spriteBox._registerNode(child);
|
||||
|
||||
if (child is PhysicsGroup) {
|
||||
child._attachGroup(child, child._world);
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes a child from this node.
|
||||
@ -330,6 +360,10 @@ class Node {
|
||||
child._spriteBox = null;
|
||||
if (_spriteBox != null) _spriteBox._deregisterNode(child);
|
||||
}
|
||||
|
||||
if (child is PhysicsGroup) {
|
||||
child._detachGroup(child);
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes this node from its parent node.
|
||||
|
||||
107
skysprites/lib/src/physics_group.dart
Normal file
107
skysprites/lib/src/physics_group.dart
Normal file
@ -0,0 +1,107 @@
|
||||
part of flutter_sprites;
|
||||
|
||||
class PhysicsGroup extends Node {
|
||||
|
||||
set scaleX(double scaleX) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
set scaleY(double scaleX) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
set skewX(double scaleX) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
set skewY(double scaleX) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
set physicsBody(PhysicsBody body) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
set position(Point position) {
|
||||
super.position = position;
|
||||
_invalidatePhysicsBodies(this);
|
||||
}
|
||||
|
||||
set rotation(double rotation) {
|
||||
super.rotation = rotation;
|
||||
_invalidatePhysicsBodies(this);
|
||||
}
|
||||
|
||||
set scale(double scale) {
|
||||
super.scale = scale;
|
||||
_invalidatePhysicsBodies(this);
|
||||
}
|
||||
|
||||
void _invalidatePhysicsBodies(Node node) {
|
||||
if (_world == null) return;
|
||||
|
||||
if (node.physicsBody != null) {
|
||||
// TODO: Add to list
|
||||
_world._bodiesScheduledForUpdate.add(node.physicsBody);
|
||||
}
|
||||
|
||||
for (Node child in node.children) {
|
||||
_invalidatePhysicsBodies(child);
|
||||
}
|
||||
}
|
||||
|
||||
void addChild(Node node) {
|
||||
super.addChild(node);
|
||||
|
||||
PhysicsWorld world = _world;
|
||||
if (node.physicsBody != null && world != null) {
|
||||
node.physicsBody._attach(world, node);
|
||||
}
|
||||
|
||||
if (node is PhysicsGroup) {
|
||||
_attachGroup(this, world);
|
||||
}
|
||||
}
|
||||
|
||||
void _attachGroup(PhysicsGroup group, PhysicsWorld world) {
|
||||
for (Node child in group.children) {
|
||||
if (child is PhysicsGroup) {
|
||||
_attachGroup(child, world);
|
||||
} else if (child.physicsBody != null) {
|
||||
child.physicsBody._attach(world, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeChild(Node node) {
|
||||
super.removeChild(node);
|
||||
|
||||
if (node.physicsBody != null) {
|
||||
node.physicsBody._detach();
|
||||
}
|
||||
|
||||
if (node is PhysicsGroup) {
|
||||
_detachGroup(this);
|
||||
}
|
||||
}
|
||||
|
||||
void _detachGroup(PhysicsGroup group) {
|
||||
for (Node child in group.children) {
|
||||
if (child is PhysicsGroup) {
|
||||
_detachGroup(child);
|
||||
} else if (child.physicsBody != null) {
|
||||
child.physicsBody._detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsWorld get _world {
|
||||
if (this.parent is PhysicsWorld)
|
||||
return this.parent;
|
||||
if (this.parent is PhysicsGroup) {
|
||||
PhysicsGroup group = this.parent;
|
||||
return group._world;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -43,6 +43,8 @@ class PhysicsWorld extends Node {
|
||||
|
||||
List<box2d.Body> _bodiesScheduledForDestruction = [];
|
||||
|
||||
List<PhysicsBody> _bodiesScheduledForUpdate = [];
|
||||
|
||||
_PhysicsDebugDraw _debugDraw;
|
||||
|
||||
double b2WorldToNodeConversionFactor = 10.0;
|
||||
@ -71,6 +73,14 @@ class PhysicsWorld extends Node {
|
||||
}
|
||||
|
||||
void _stepPhysics(double dt) {
|
||||
// Update transformations of bodies whose groups have moved
|
||||
for (PhysicsBody body in _bodiesScheduledForUpdate) {
|
||||
Node node = body._node;
|
||||
node._updatePhysicsPosition(body, node.position, node.parent);
|
||||
node._updatePhysicsRotation(body, node.rotation, node.parent);
|
||||
}
|
||||
_bodiesScheduledForUpdate.clear();
|
||||
|
||||
// Remove bodies that were marked for destruction during the update phase
|
||||
_removeBodiesScheduledForDestruction();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user