mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Merge pull request #1642 from vlidholt/master
Animated sprite physics bodies now correctly transfers energy to dynamic bodies
This commit is contained in:
commit
a3644e03b4
@ -1,5 +1,6 @@
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user