mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Merge pull request #1623 from vlidholt/master
Fixes touch handling and refactors sprite physics
This commit is contained in:
commit
6e91cfa49a
@ -14,6 +14,7 @@ import 'package:box2d/box2d.dart' as box2d;
|
||||
import 'package:mojo/core.dart';
|
||||
import 'package:sky_services/media/media.mojom.dart';
|
||||
import 'package:flutter/animation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -33,6 +34,7 @@ part 'src/node3d.dart';
|
||||
part 'src/node_with_size.dart';
|
||||
part 'src/particle_system.dart';
|
||||
part 'src/physics_body.dart';
|
||||
part 'src/physics_debug.dart';
|
||||
part 'src/physics_joint.dart';
|
||||
part 'src/physics_node.dart';
|
||||
part 'src/physics_shape.dart';
|
||||
|
97
packages/flutter_sprites/lib/src/physics_debug.dart
Normal file
97
packages/flutter_sprites/lib/src/physics_debug.dart
Normal file
@ -0,0 +1,97 @@
|
||||
part of flutter_sprites;
|
||||
|
||||
class _PhysicsDebugDraw extends box2d.DebugDraw {
|
||||
_PhysicsDebugDraw(
|
||||
box2d.ViewportTransform transform,
|
||||
this.physicsNode
|
||||
) : super(transform);
|
||||
|
||||
PhysicsNode physicsNode;
|
||||
|
||||
PaintingCanvas canvas;
|
||||
|
||||
void drawSegment(Vector2 p1, Vector2 p2, box2d.Color3i color) {
|
||||
Paint paint = new Paint()..color = _toColor(color);
|
||||
canvas.drawLine(_toPoint(p1), _toPoint(p2), paint);
|
||||
}
|
||||
|
||||
void drawSolidPolygon(
|
||||
List<Vector2> vertices,
|
||||
int vertexCount,
|
||||
box2d.Color3i color
|
||||
) {
|
||||
Path path = new Path();
|
||||
Point pt = _toPoint(vertices[0]);
|
||||
path.moveTo(pt.x, pt.y);
|
||||
for (int i = 1; i < vertexCount; i++) {
|
||||
pt = _toPoint(vertices[i]);
|
||||
path.lineTo(pt.x, pt.y);
|
||||
}
|
||||
|
||||
Paint paint = new Paint()..color = _toColor(color);
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
|
||||
void drawCircle(Vector2 center, num radius, box2d.Color3i color, [Vector2 axis]) {
|
||||
print("drawCircle: $center");
|
||||
Paint paint = new Paint()
|
||||
..color = _toColor(color)
|
||||
..setStyle(ui.PaintingStyle.stroke)
|
||||
..strokeWidth = 1.0;
|
||||
|
||||
canvas.drawCircle(_toPoint(center), _scale(radius), paint);
|
||||
}
|
||||
|
||||
void drawSolidCircle(Vector2 center, num radius, Vector2 axis, box2d.Color3i color) {
|
||||
Paint paint = new Paint()
|
||||
..color = _toColor(color);
|
||||
|
||||
canvas.drawCircle(_toPoint(center), _scale(radius), paint);
|
||||
}
|
||||
|
||||
void drawPoint(Vector2 point, num radiusOnScreen, box2d.Color3i color) {
|
||||
drawSolidCircle(point, radiusOnScreen, null, color);
|
||||
}
|
||||
|
||||
void drawParticles(
|
||||
List<Vector2> centers,
|
||||
double radius,
|
||||
List<box2d.ParticleColor> colors,
|
||||
int count
|
||||
) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
void drawParticlesWireframe(
|
||||
List<Vector2> centers,
|
||||
double radius,
|
||||
List<box2d.ParticleColor> colors,
|
||||
int count
|
||||
) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
void drawTransform(box2d.Transform xf, box2d.Color3i color) {
|
||||
drawCircle(xf.p, 0.1, color);
|
||||
// TODO: Improve
|
||||
}
|
||||
|
||||
void drawStringXY(num x, num y, String s, box2d.Color3i color) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
Color _toColor(box2d.Color3i color) {
|
||||
return new Color.fromARGB(255, color.x, color.y, color.z);
|
||||
}
|
||||
|
||||
Point _toPoint(Vector2 vec) {
|
||||
return new Point(
|
||||
vec.x * physicsNode.b2WorldToNodeConversionFactor,
|
||||
vec.y * physicsNode.b2WorldToNodeConversionFactor
|
||||
);
|
||||
}
|
||||
|
||||
double _scale(double value) {
|
||||
return value * physicsNode.b2WorldToNodeConversionFactor;
|
||||
}
|
||||
}
|
@ -25,6 +25,14 @@ class PhysicsNode extends Node {
|
||||
void _init() {
|
||||
_contactHandler = new _ContactHandler(this);
|
||||
b2World.setContactListener(_contactHandler);
|
||||
|
||||
box2d.ViewportTransform transform = new box2d.ViewportTransform(
|
||||
new Vector2.zero(),
|
||||
new Vector2.zero(),
|
||||
1.0
|
||||
);
|
||||
_debugDraw = new _PhysicsDebugDraw(transform, this);
|
||||
b2World.debugDraw = _debugDraw;
|
||||
}
|
||||
|
||||
box2d.World b2World;
|
||||
@ -35,6 +43,8 @@ class PhysicsNode extends Node {
|
||||
|
||||
List<box2d.Body> _bodiesScheduledForDestruction = [];
|
||||
|
||||
_PhysicsDebugDraw _debugDraw;
|
||||
|
||||
double b2WorldToNodeConversionFactor = 10.0;
|
||||
|
||||
Offset get gravity {
|
||||
@ -143,161 +153,8 @@ class PhysicsNode extends Node {
|
||||
}
|
||||
|
||||
void paintDebug(PaintingCanvas canvas) {
|
||||
Paint shapePaint = new Paint();
|
||||
shapePaint.setStyle(ui.PaintingStyle.stroke);
|
||||
shapePaint.strokeWidth = 1.0;
|
||||
|
||||
for (box2d.Body body = b2World.bodyList; body != null; body = body.getNext()) {
|
||||
canvas.save();
|
||||
|
||||
Point point = new Point(
|
||||
body.position.x * b2WorldToNodeConversionFactor,
|
||||
body.position.y * b2WorldToNodeConversionFactor);
|
||||
|
||||
canvas.translate(point.x, point.y);
|
||||
canvas.rotate(body.getAngle());
|
||||
|
||||
if (body.getType() == box2d.BodyType.DYNAMIC) {
|
||||
if (body.isAwake())
|
||||
shapePaint.color = new Color(0xff00ff00);
|
||||
else
|
||||
shapePaint.color = new Color(0xff666666);
|
||||
}
|
||||
else if (body.getType() == box2d.BodyType.STATIC)
|
||||
shapePaint.color = new Color(0xffff0000);
|
||||
else if (body.getType() == box2d.BodyType.KINEMATIC)
|
||||
shapePaint.color = new Color(0xffff9900);
|
||||
|
||||
for (box2d.Fixture fixture = body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
|
||||
box2d.Shape shape = fixture.getShape();
|
||||
|
||||
if (shape.shapeType == box2d.ShapeType.CIRCLE) {
|
||||
box2d.CircleShape circle = shape;
|
||||
Point cp = new Point(
|
||||
circle.p.x * b2WorldToNodeConversionFactor,
|
||||
circle.p.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
double radius = circle.radius * b2WorldToNodeConversionFactor;
|
||||
canvas.drawCircle(cp, radius, shapePaint);
|
||||
} else if (shape.shapeType == box2d.ShapeType.POLYGON) {
|
||||
box2d.PolygonShape poly = shape;
|
||||
List<Point> points = [];
|
||||
for (int i = 0; i < poly.getVertexCount(); i++) {
|
||||
Vector2 vertex = poly.getVertex(i);
|
||||
Point pt = new Point(
|
||||
vertex.x * b2WorldToNodeConversionFactor,
|
||||
vertex.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
points.add(pt);
|
||||
}
|
||||
if (points.length >= 2) {
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
canvas.drawLine(points[i], points[(i + 1) % points.length], shapePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
|
||||
// Draw contacts
|
||||
for (box2d.ContactEdge edge = body.getContactList(); edge != null; edge = edge.next) {
|
||||
box2d.Contact contact = edge.contact;
|
||||
Vector2 cA = new Vector2.zero();
|
||||
Vector2 cB = new Vector2.zero();
|
||||
|
||||
box2d.Fixture fixtureA = contact.fixtureA;
|
||||
box2d.Fixture fixtureB = contact.fixtureB;
|
||||
|
||||
fixtureA.getAABB(contact.getChildIndexA()).getCenterToOut(cA);
|
||||
fixtureB.getAABB(contact.getChildIndexB()).getCenterToOut(cB);
|
||||
|
||||
Point p1 = new Point(
|
||||
cA.x * b2WorldToNodeConversionFactor,
|
||||
cA.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
Point p2 = new Point(
|
||||
cB.x * b2WorldToNodeConversionFactor,
|
||||
cB.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
shapePaint.color = new Color(0x33ffffff);
|
||||
canvas.drawLine(p1, p2, shapePaint);
|
||||
|
||||
box2d.WorldManifold worldManifold = new box2d.WorldManifold();
|
||||
contact.getWorldManifold(worldManifold);
|
||||
|
||||
shapePaint.color = new Color(0xffffffff);
|
||||
|
||||
for (Vector2 pt in worldManifold.points) {
|
||||
Point pCenter = new Point(
|
||||
pt.x * b2WorldToNodeConversionFactor,
|
||||
pt.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
Offset offset = new Offset(
|
||||
worldManifold.normal.x * 5.0,
|
||||
worldManifold.normal.y * 5.0
|
||||
);
|
||||
|
||||
Point p2 = pCenter + offset;
|
||||
Point p1 = new Point(pCenter.x - offset.dx, pCenter.y - offset.dy);
|
||||
canvas.drawLine(p1, p2, shapePaint);
|
||||
canvas.drawCircle(pCenter, 5.0, shapePaint);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw joints
|
||||
shapePaint.color = new Color(0xff0000ff);
|
||||
|
||||
for (box2d.JointEdge edge = body.getJointList(); edge != null; edge = edge.next) {
|
||||
box2d.Joint joint = edge.joint;
|
||||
|
||||
// Make sure we only draw each joint once
|
||||
if (joint.getBodyB() == body)
|
||||
continue;
|
||||
|
||||
// Get anchor A
|
||||
Vector2 anchorA = new Vector2.zero();
|
||||
joint.getAnchorA(anchorA);
|
||||
|
||||
Point ptAnchorA = new Point(
|
||||
anchorA.x * b2WorldToNodeConversionFactor,
|
||||
anchorA.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
// Get anchor B
|
||||
Vector2 anchorB = new Vector2.zero();
|
||||
joint.getAnchorB(anchorB);
|
||||
|
||||
Point ptAnchorB = new Point(
|
||||
anchorB.x * b2WorldToNodeConversionFactor,
|
||||
anchorB.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
// Get body A position
|
||||
Point ptBodyA = new Point(
|
||||
joint.getBodyA().position.x * b2WorldToNodeConversionFactor,
|
||||
joint.getBodyA().position.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
Point ptBodyB = new Point(
|
||||
joint.getBodyB().position.x * b2WorldToNodeConversionFactor,
|
||||
joint.getBodyB().position.y * b2WorldToNodeConversionFactor
|
||||
);
|
||||
|
||||
// Draw the joint depending on type
|
||||
box2d.JointType type = joint.getType();
|
||||
|
||||
if (type == box2d.JointType.WELD || type == box2d.JointType.REVOLUTE) {
|
||||
// Draw weld joint
|
||||
canvas.drawCircle(ptAnchorA, 5.0, shapePaint);
|
||||
|
||||
canvas.drawLine(ptBodyA, ptAnchorA, shapePaint);
|
||||
canvas.drawLine(ptAnchorB, ptBodyB, shapePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
_debugDraw.canvas = canvas;
|
||||
b2World.drawDebugData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,11 +185,11 @@ class SpriteBox extends RenderBox {
|
||||
}
|
||||
}
|
||||
|
||||
void handleEvent(ui.Event event, _SpriteBoxHitTestEntry entry) {
|
||||
void handleEvent(InputEvent event, _SpriteBoxHitTestEntry entry) {
|
||||
if (!attached)
|
||||
return;
|
||||
|
||||
if (event is ui.PointerEvent) {
|
||||
if (event is PointerInputEvent) {
|
||||
|
||||
if (event.type == 'pointerdown') {
|
||||
// Build list of event targets
|
||||
|
Loading…
Reference in New Issue
Block a user