Commit 0ef9da85 authored by Viktor Lidholt's avatar Viktor Lidholt

Merge pull request #1672 from vlidholt/master

Makes sprite physics bodies scalable
parents 47c854b8 6f9fe7b1
...@@ -55,6 +55,7 @@ class TestBed extends NodeWithSize { ...@@ -55,6 +55,7 @@ class TestBed extends NodeWithSize {
_obstacle = new Sprite(_spriteSheet["ship.png"]); _obstacle = new Sprite(_spriteSheet["ship.png"]);
_obstacle.position = new Point(512.0, 800.0); _obstacle.position = new Point(512.0, 800.0);
_obstacle.size = new Size(64.0, 64.0); _obstacle.size = new Size(64.0, 64.0);
_obstacle.scale = 2.0;
_obstacle.physicsBody = new PhysicsBody( _obstacle.physicsBody = new PhysicsBody(
new PhysicsShapeCircle(Point.origin, 32.0), new PhysicsShapeCircle(Point.origin, 32.0),
type: PhysicsBodyType.static, type: PhysicsBodyType.static,
...@@ -71,6 +72,12 @@ class TestBed extends NodeWithSize { ...@@ -71,6 +72,12 @@ class TestBed extends NodeWithSize {
]); ]);
_obstacle.actions.run(new ActionRepeatForever(seq)); _obstacle.actions.run(new ActionRepeatForever(seq));
seq = new ActionSequence([
new ActionTween((a) => _obstacle.scale = a, 1.0, 2.0, 2.0, easeInOut),
new ActionTween((a) => _obstacle.scale = a, 2.0, 1.0, 2.0, easeInOut)
]);
_obstacle.actions.run(new ActionRepeatForever(seq));
addChild(_physicsNode); addChild(_physicsNode);
userInteractionEnabled = true; userInteractionEnabled = true;
......
...@@ -251,6 +251,12 @@ class Node { ...@@ -251,6 +251,12 @@ class Node {
void set scale(double scale) { void set scale(double scale) {
assert(scale != null); assert(scale != null);
if (_physicsBody != null && parent is PhysicsNode) {
PhysicsNode physicsNode = parent;
physicsNode._updateScale(this.physicsBody, scale);
}
_scaleX = _scaleY = scale; _scaleX = _scaleY = scale;
invalidateTransformMatrix(); invalidateTransformMatrix();
} }
...@@ -262,6 +268,8 @@ class Node { ...@@ -262,6 +268,8 @@ class Node {
void set scaleX(double scaleX) { void set scaleX(double scaleX) {
assert(scaleX != null); assert(scaleX != null);
assert(physicsBody == null);
_scaleX = scaleX; _scaleX = scaleX;
invalidateTransformMatrix(); invalidateTransformMatrix();
} }
...@@ -273,6 +281,8 @@ class Node { ...@@ -273,6 +281,8 @@ class Node {
void set scaleY(double scaleY) { void set scaleY(double scaleY) {
assert(scaleY != null); assert(scaleY != null);
assert(physicsBody == null);
_scaleY = scaleY; _scaleY = scaleY;
invalidateTransformMatrix(); invalidateTransformMatrix();
} }
......
...@@ -45,6 +45,8 @@ class PhysicsBody { ...@@ -45,6 +45,8 @@ class PhysicsBody {
Vector2 _targetPosition; Vector2 _targetPosition;
double _targetAngle; double _targetAngle;
double _scale;
Object tag; Object tag;
final PhysicsShape shape; final PhysicsShape shape;
...@@ -294,6 +296,9 @@ class PhysicsBody { ...@@ -294,6 +296,9 @@ class PhysicsBody {
void _attach(PhysicsNode physicsNode, Node node) { void _attach(PhysicsNode physicsNode, Node node) {
assert(_attached == false); assert(_attached == false);
// Update scale
_scale = node.scale;
// Create BodyDef // Create BodyDef
box2d.BodyDef bodyDef = new box2d.BodyDef(); box2d.BodyDef bodyDef = new box2d.BodyDef();
bodyDef.linearVelocity = new Vector2(linearVelocity.dx, linearVelocity.dy); bodyDef.linearVelocity = new Vector2(linearVelocity.dx, linearVelocity.dy);
...@@ -318,6 +323,24 @@ class PhysicsBody { ...@@ -318,6 +323,24 @@ class PhysicsBody {
// Create Body // Create Body
_body = physicsNode.b2World.createBody(bodyDef); _body = physicsNode.b2World.createBody(bodyDef);
_createFixtures(physicsNode);
_body.userData = this;
_physicsNode = physicsNode;
_node = node;
_attached = true;
// Attach any joints
for (PhysicsJoint joint in _joints) {
if (joint.bodyA._attached && joint.bodyB._attached) {
joint._attach(physicsNode);
}
}
}
void _createFixtures(PhysicsNode physicsNode) {
// Create FixtureDef // Create FixtureDef
box2d.FixtureDef fixtureDef = new box2d.FixtureDef(); box2d.FixtureDef fixtureDef = new box2d.FixtureDef();
fixtureDef.friction = friction; fixtureDef.friction = friction;
...@@ -339,19 +362,6 @@ class PhysicsBody { ...@@ -339,19 +362,6 @@ class PhysicsBody {
box2d.Fixture fixture = _body.createFixtureFromFixtureDef(fixtureDef); box2d.Fixture fixture = _body.createFixtureFromFixtureDef(fixtureDef);
fixture.userData = physicsShape; fixture.userData = physicsShape;
} }
_body.userData = this;
_physicsNode = physicsNode;
_node = node;
_attached = true;
// Attach any joints
for (PhysicsJoint joint in _joints) {
if (joint.bodyA._attached && joint.bodyB._attached) {
joint._attach(physicsNode);
}
}
} }
void _detach() { void _detach() {
...@@ -361,13 +371,26 @@ class PhysicsBody { ...@@ -361,13 +371,26 @@ class PhysicsBody {
} }
} }
void _updateScale(PhysicsNode physicsNode) {
// Destroy old fixtures
for (box2d.Fixture fixture = _body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
_body.destroyFixture(fixture);
}
// Make sure we create new b2Shapes
shape._invalidate();
// Create new fixtures
_createFixtures(physicsNode);
}
void _addB2Shapes(PhysicsNode physicsNode, PhysicsShape shape, List<box2d.Shape> b2Shapes, List<PhysicsShape> physicsShapes) { void _addB2Shapes(PhysicsNode physicsNode, PhysicsShape shape, List<box2d.Shape> b2Shapes, List<PhysicsShape> physicsShapes) {
if (shape is PhysicsShapeGroup) { if (shape is PhysicsShapeGroup) {
for (PhysicsShape child in shape.shapes) { for (PhysicsShape child in shape.shapes) {
_addB2Shapes(physicsNode, child, b2Shapes, physicsShapes); _addB2Shapes(physicsNode, child, b2Shapes, physicsShapes);
} }
} else { } else {
b2Shapes.add(shape.getB2Shape(physicsNode)); b2Shapes.add(shape.getB2Shape(physicsNode, _scale));
physicsShapes.add(shape); physicsShapes.add(shape);
} }
} }
......
...@@ -181,6 +181,14 @@ class PhysicsNode extends Node { ...@@ -181,6 +181,14 @@ class PhysicsNode extends Node {
body._body.setAwake(true); body._body.setAwake(true);
} }
void _updateScale(PhysicsBody body, double scale) {
body._scale = scale;
if (body._attached) {
body._updateScale(this);
}
}
void addChild(Node node) { void addChild(Node node) {
super.addChild(node); super.addChild(node);
if (node.physicsBody != null) { if (node.physicsBody != null) {
......
...@@ -6,14 +6,18 @@ abstract class PhysicsShape { ...@@ -6,14 +6,18 @@ abstract class PhysicsShape {
Object userObject; Object userObject;
box2d.Shape getB2Shape(PhysicsNode node) { box2d.Shape getB2Shape(PhysicsNode node, double scale) {
if (_b2Shape == null) { if (_b2Shape == null) {
_b2Shape = _createB2Shape(node); _b2Shape = _createB2Shape(node, scale);
} }
return _b2Shape; return _b2Shape;
} }
box2d.Shape _createB2Shape(PhysicsNode node); box2d.Shape _createB2Shape(PhysicsNode node, double scale);
void _invalidate() {
_b2Shape = null;
}
} }
class PhysicsShapeCircle extends PhysicsShape { class PhysicsShapeCircle extends PhysicsShape {
...@@ -22,11 +26,11 @@ class PhysicsShapeCircle extends PhysicsShape { ...@@ -22,11 +26,11 @@ class PhysicsShapeCircle extends PhysicsShape {
final Point point; final Point point;
final double radius; final double radius;
box2d.Shape _createB2Shape(PhysicsNode node) { box2d.Shape _createB2Shape(PhysicsNode node, double scale) {
box2d.CircleShape shape = new box2d.CircleShape(); box2d.CircleShape shape = new box2d.CircleShape();
shape.p.x = point.x / node.b2WorldToNodeConversionFactor; shape.p.x = scale * point.x / node.b2WorldToNodeConversionFactor;
shape.p.y = point.y / node.b2WorldToNodeConversionFactor; shape.p.y = scale * point.y / node.b2WorldToNodeConversionFactor;
shape.radius = radius / node.b2WorldToNodeConversionFactor; shape.radius = scale * radius / node.b2WorldToNodeConversionFactor;
return shape; return shape;
} }
} }
...@@ -36,12 +40,12 @@ class PhysicsShapePolygon extends PhysicsShape { ...@@ -36,12 +40,12 @@ class PhysicsShapePolygon extends PhysicsShape {
final List<Point> points; final List<Point> points;
box2d.Shape _createB2Shape(PhysicsNode node) { box2d.Shape _createB2Shape(PhysicsNode node, double scale) {
List<Vector2> vectors = []; List<Vector2> vectors = [];
for (Point point in points) { for (Point point in points) {
Vector2 vec = new Vector2( Vector2 vec = new Vector2(
point.x / node.b2WorldToNodeConversionFactor, scale * point.x / node.b2WorldToNodeConversionFactor,
point.y / node.b2WorldToNodeConversionFactor scale * point.y / node.b2WorldToNodeConversionFactor
); );
vectors.add(vec); vectors.add(vec);
} }
...@@ -65,14 +69,14 @@ class PhysicsShapeBox extends PhysicsShape { ...@@ -65,14 +69,14 @@ class PhysicsShapeBox extends PhysicsShape {
final Point center; final Point center;
final double rotation; final double rotation;
box2d.Shape _createB2Shape(PhysicsNode node) { box2d.Shape _createB2Shape(PhysicsNode node, double scale) {
box2d.PolygonShape shape = new box2d.PolygonShape(); box2d.PolygonShape shape = new box2d.PolygonShape();
shape.setAsBox( shape.setAsBox(
width / node.b2WorldToNodeConversionFactor, scale * width / node.b2WorldToNodeConversionFactor,
height / node.b2WorldToNodeConversionFactor, scale * height / node.b2WorldToNodeConversionFactor,
new Vector2( new Vector2(
center.x / node.b2WorldToNodeConversionFactor, scale * center.x / node.b2WorldToNodeConversionFactor,
center.y / node.b2WorldToNodeConversionFactor scale * center.y / node.b2WorldToNodeConversionFactor
), ),
radians(rotation) radians(rotation)
); );
...@@ -86,12 +90,12 @@ class PhysicsShapeChain extends PhysicsShape { ...@@ -86,12 +90,12 @@ class PhysicsShapeChain extends PhysicsShape {
final List<Point> points; final List<Point> points;
final bool loop; final bool loop;
box2d.Shape _createB2Shape(PhysicsNode node) { box2d.Shape _createB2Shape(PhysicsNode node, double scale) {
List<Vector2> vectors = []; List<Vector2> vectors = [];
for (Point point in points) { for (Point point in points) {
Vector2 vec = new Vector2( Vector2 vec = new Vector2(
point.x / node.b2WorldToNodeConversionFactor, scale * point.x / node.b2WorldToNodeConversionFactor,
point.y / node.b2WorldToNodeConversionFactor scale * point.y / node.b2WorldToNodeConversionFactor
); );
vectors.add(vec); vectors.add(vec);
} }
...@@ -111,16 +115,16 @@ class PhysicsShapeEdge extends PhysicsShape { ...@@ -111,16 +115,16 @@ class PhysicsShapeEdge extends PhysicsShape {
final Point pointA; final Point pointA;
final Point pointB; final Point pointB;
box2d.Shape _createB2Shape(PhysicsNode node) { box2d.Shape _createB2Shape(PhysicsNode node, double scale) {
box2d.EdgeShape shape = new box2d.EdgeShape(); box2d.EdgeShape shape = new box2d.EdgeShape();
shape.set( shape.set(
new Vector2( new Vector2(
pointA.x / node.b2WorldToNodeConversionFactor, scale * pointA.x / node.b2WorldToNodeConversionFactor,
pointA.y / node.b2WorldToNodeConversionFactor scale * pointA.y / node.b2WorldToNodeConversionFactor
), ),
new Vector2( new Vector2(
pointB.x / node.b2WorldToNodeConversionFactor, scale * pointB.x / node.b2WorldToNodeConversionFactor,
pointB.y / node.b2WorldToNodeConversionFactor scale * pointB.y / node.b2WorldToNodeConversionFactor
) )
); );
return shape; return shape;
...@@ -133,7 +137,13 @@ class PhysicsShapeGroup extends PhysicsShape { ...@@ -133,7 +137,13 @@ class PhysicsShapeGroup extends PhysicsShape {
final List<PhysicsShape> shapes; final List<PhysicsShape> shapes;
box2d.Shape _createB2Shape(PhysicsNode node) { box2d.Shape _createB2Shape(PhysicsNode node, double scale) {
return null; return null;
} }
void _invalidate() {
for (PhysicsShape shape in shapes) {
shape._invalidate();
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment