Commit f77319fc authored by Viktor Lidholt's avatar Viktor Lidholt

Merge pull request #1642 from vlidholt/master

Animated sprite physics bodies now correctly transfers energy to dynamic bodies
parents 7b31d9b2 f48b88cd
import 'dart:ui';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
......@@ -52,7 +53,7 @@ class TestBed extends NodeWithSize {
_physicsNode = new PhysicsNode(new Offset(0.0, 100.0));
_obstacle = new Sprite(_spriteSheet["ship.png"]);
_obstacle.position = new Point(532.0, 800.0);
_obstacle.position = new Point(512.0, 800.0);
_obstacle.size = new Size(64.0, 64.0);
_obstacle.physicsBody = new PhysicsBody(
new PhysicsShapeCircle(Point.origin, 32.0),
......@@ -63,6 +64,13 @@ class TestBed extends NodeWithSize {
_physicsNode.addChild(_obstacle);
_physicsNode.addContactCallback(myCallback, "obstacle", "ship", PhysicsContactType.begin);
// Animate obstacle
ActionSequence seq = new ActionSequence([
new ActionTween((a) => _obstacle.position = a, new Point(256.0, 800.0), new Point(768.0, 800.0), 1.0, easeInOut),
new ActionTween((a) => _obstacle.position = a, new Point(768.0, 800.0), new Point(256.0, 800.0), 1.0, easeInOut)
]);
_obstacle.actions.run(new ActionRepeatForever(seq));
addChild(_physicsNode);
userInteractionEnabled = true;
......
......@@ -40,6 +40,11 @@ class PhysicsBody {
this.active = active;
}
Vector2 _lastPosition;
double _lastRotation;
Vector2 _targetPosition;
double _targetAngle;
Object tag;
final PhysicsShape shape;
......
......@@ -74,6 +74,37 @@ class PhysicsNode extends Node {
// Remove bodies that were marked for destruction during the update phase
_removeBodiesScheduledForDestruction();
// Assign velocities and momentum to static and kinetic bodies
for (box2d.Body b2Body = b2World.bodyList; b2Body != null; b2Body = b2Body.getNext()) {
// Fetch body
PhysicsBody body = b2Body.userData;
// Skip all dynamic bodies
if (b2Body.getType() == box2d.BodyType.DYNAMIC) {
body._lastPosition = null;
body._lastRotation = null;
continue;
}
// Update linear velocity
if (body._lastPosition == null) {
b2Body.linearVelocity.setZero();
} else {
Vector2 velocity = (body._targetPosition - body._lastPosition) / dt;
b2Body.linearVelocity = velocity;
body._lastPosition = null;
}
// Update angular velocity
if (body._lastRotation == null) {
b2Body.angularVelocity = 0.0;
} else {
double angularVelocity = (body._targetAngle - body._lastRotation) / dt;
b2Body.angularVelocity = angularVelocity;
body._lastRotation = 0.0;
}
}
// Calculate a step in the simulation
b2World.stepDt(dt, 10, 10);
......@@ -113,16 +144,30 @@ class PhysicsNode extends Node {
}
void _updatePosition(PhysicsBody body, Point position) {
if (body._lastPosition == null && body.type == PhysicsBodyType.static) {
body._lastPosition = new Vector2.copy(body._body.position);
body._body.setType(box2d.BodyType.KINEMATIC);
}
Vector2 newPos = new Vector2(
position.x / b2WorldToNodeConversionFactor,
position.y / b2WorldToNodeConversionFactor
);
double angle = body._body.getAngle();
body._body.setTransform(newPos, angle);
if (body.type == PhysicsBodyType.dynamic) {
body._body.setTransform(newPos, angle);
} else {
body._targetPosition = newPos;
body._targetAngle = angle;
}
body._body.setAwake(true);
}
void _updateRotation(PhysicsBody body, double rotation) {
if (body._lastRotation == null)
body._lastRotation = body._body.getAngle();
Vector2 pos = body._body.position;
double newAngle = radians(rotation);
body._body.setTransform(pos, newAngle);
......
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