Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
ecd20b6f
Commit
ecd20b6f
authored
Oct 08, 2015
by
Viktor Lidholt
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1541 from vlidholt/master
Adds support for keeping track of contact points in physics
parents
8945e011
333c8f5f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
214 additions
and
26 deletions
+214
-26
test_physics.dart
examples/game/test_physics.dart
+31
-20
physics_body.dart
packages/flutter_sprites/lib/physics_body.dart
+9
-0
physics_joint.dart
packages/flutter_sprites/lib/physics_joint.dart
+90
-0
physics_node.dart
packages/flutter_sprites/lib/physics_node.dart
+83
-6
skysprites.dart
packages/flutter_sprites/lib/skysprites.dart
+1
-0
No files found.
examples/game/test_physics.dart
View file @
ecd20b6f
...
...
@@ -45,24 +45,11 @@ main() async {
}
class
TestBed
extends
NodeWithSize
{
Sprite
_ship
;
Sprite
_obstacle
;
PhysicsNode
_physicsNode
;
TestBed
()
:
super
(
new
Size
(
1024.0
,
1024.0
))
{
PhysicsNode
physicsNode
=
new
PhysicsNode
(
new
Offset
(
0.0
,
100.0
));
_ship
=
new
Sprite
(
_spriteSheet
[
"ship.png"
]);
_ship
.
position
=
new
Point
(
512.0
,
512.0
);
_ship
.
size
=
new
Size
(
64.0
,
64.0
);
_ship
.
physicsBody
=
new
PhysicsBody
(
new
PhysicsShapeGroup
([
new
PhysicsShapeCircle
(
Point
.
origin
,
32.0
),
new
PhysicsShapePolygon
([
new
Point
(
0.0
,
0.0
),
new
Point
(
50.0
,
0.0
),
new
Point
(
50.0
,
50.0
),
new
Point
(
0.0
,
50.0
)])
]),
friction:
0.5
,
tag:
"ship"
);
physicsNode
.
addChild
(
_ship
);
_physicsNode
=
new
PhysicsNode
(
new
Offset
(
0.0
,
100.0
));
_obstacle
=
new
Sprite
(
_spriteSheet
[
"ship.png"
]);
_obstacle
.
position
=
new
Point
(
532.0
,
800.0
);
...
...
@@ -73,23 +60,47 @@ class TestBed extends NodeWithSize {
friction:
0.5
,
tag:
"obstacle"
);
physicsNode
.
addChild
(
_obstacle
);
physicsNode
.
addContactCallback
(
myCallback
,
"obstacle"
,
"ship"
,
PhysicsContactType
.
begin
);
_
physicsNode
.
addChild
(
_obstacle
);
_
physicsNode
.
addContactCallback
(
myCallback
,
"obstacle"
,
"ship"
,
PhysicsContactType
.
begin
);
addChild
(
physicsNode
);
addChild
(
_
physicsNode
);
userInteractionEnabled
=
true
;
}
void
myCallback
(
PhysicsContactType
type
,
PhysicsContact
contact
)
{
print
(
"CONTACT type:
$type
"
);
contact
.
nodeB
.
removeFromParent
();
}
bool
handleEvent
(
SpriteBoxEvent
event
)
{
if
(
event
.
type
==
"pointerdown"
)
{
Point
pos
=
convertPointToNodeSpace
(
event
.
boxPosition
);
_ship
.
position
=
pos
;
Sprite
shipA
;
shipA
=
new
Sprite
(
_spriteSheet
[
"ship.png"
]);
shipA
.
position
=
new
Point
(
pos
.
x
-
40.0
,
pos
.
y
);
shipA
.
size
=
new
Size
(
64.0
,
64.0
);
shipA
.
physicsBody
=
new
PhysicsBody
(
new
PhysicsShapeCircle
(
Point
.
origin
,
32.0
),
friction:
0.5
,
tag:
"ship"
);
_physicsNode
.
addChild
(
shipA
);
shipA
.
physicsBody
.
applyLinearImpulse
(
new
Offset
(
randomSignedDouble
()
*
5.0
,
randomSignedDouble
()
*
5.0
),
shipA
.
position
);
Sprite
shipB
;
shipB
=
new
Sprite
(
_spriteSheet
[
"ship.png"
]);
shipB
.
position
=
new
Point
(
pos
.
x
+
40.0
,
pos
.
y
);
shipB
.
size
=
new
Size
(
64.0
,
64.0
);
shipB
.
physicsBody
=
new
PhysicsBody
(
new
PhysicsShapePolygon
([
new
Point
(-
25.0
,
-
25.0
),
new
Point
(
25.0
,
-
25.0
),
new
Point
(
25.0
,
25.0
),
new
Point
(-
25.0
,
25.0
)]),
friction:
0.5
,
tag:
"ship"
);
_physicsNode
.
addChild
(
shipB
);
new
PhysicsJointWeld
(
shipA
.
physicsBody
,
shipB
.
physicsBody
);
}
return
true
;
}
...
...
packages/flutter_sprites/lib/physics_body.dart
View file @
ecd20b6f
...
...
@@ -230,6 +230,8 @@ class PhysicsBody {
box2d
.
Body
_body
;
List
<
PhysicsJoint
>
_joints
=
[];
bool
_attached
=
false
;
void
applyForce
(
Offset
force
,
Point
worldPoint
)
{
...
...
@@ -338,6 +340,13 @@ class PhysicsBody {
_node
=
node
;
_attached
=
true
;
// Attach any joints
for
(
PhysicsJoint
joint
in
_joints
)
{
if
(
joint
.
bodyA
.
_attached
&&
joint
.
bodyB
.
_attached
)
{
joint
.
_attach
(
physicsNode
);
}
}
}
void
_detach
()
{
...
...
packages/flutter_sprites/lib/physics_joint.dart
0 → 100644
View file @
ecd20b6f
part of
skysprites
;
abstract
class
PhysicsJoint
{
PhysicsJoint
(
this
.
bodyA
,
this
.
bodyB
)
{
bodyA
.
_joints
.
add
(
this
);
bodyB
.
_joints
.
add
(
this
);
if
(
bodyA
.
_attached
&&
bodyB
.
_attached
)
{
_attach
(
bodyA
.
_physicsNode
);
}
}
PhysicsBody
bodyA
;
PhysicsBody
bodyB
;
bool
_active
=
true
;
box2d
.
Joint
_joint
;
PhysicsNode
_physicsNode
;
void
_attach
(
PhysicsNode
physicsNode
)
{
if
(
_joint
==
null
)
{
_physicsNode
=
physicsNode
;
_joint
=
_createB2Joint
(
physicsNode
);
}
}
void
_detach
()
{
if
(
_joint
!=
null
&&
_active
)
{
_physicsNode
.
b2World
.
destroyJoint
(
_joint
);
_joint
=
null
;
}
_active
=
false
;
}
box2d
.
Joint
_createB2Joint
(
PhysicsNode
physicsNode
);
}
class
PhysicsJointRevolute
extends
PhysicsJoint
{
PhysicsJointRevolute
(
PhysicsBody
bodyA
,
PhysicsBody
bodyB
,
this
.
anchorWorld
,
{
double
lowerAngle:
0.0
,
double
upperAngle:
0.0
,
bool
enableLimit:
false
})
:
super
(
bodyA
,
bodyB
)
{
this
.
lowerAngle
=
lowerAngle
;
this
.
upperAngle
=
upperAngle
;
this
.
enableLimit
=
enableLimit
;
}
Point
anchorWorld
;
double
lowerAngle
;
double
upperAngle
;
bool
enableLimit
;
box2d
.
Joint
_createB2Joint
(
PhysicsNode
physicsNode
)
{
// Create Joint Definition
Vector2
vecAnchor
=
new
Vector2
(
anchorWorld
.
x
/
physicsNode
.
b2WorldToNodeConversionFactor
,
anchorWorld
.
y
/
physicsNode
.
b2WorldToNodeConversionFactor
);
box2d
.
RevoluteJointDef
b2Def
=
new
box2d
.
RevoluteJointDef
();
b2Def
.
initialize
(
bodyA
.
_body
,
bodyB
.
_body
,
vecAnchor
);
b2Def
.
enableLimit
=
enableLimit
;
b2Def
.
lowerAngle
=
lowerAngle
;
b2Def
.
upperAngle
=
upperAngle
;
// Create joint
return
physicsNode
.
b2World
.
createJoint
(
b2Def
);
}
}
class
PhysicsJointWeld
extends
PhysicsJoint
{
PhysicsJointWeld
(
PhysicsBody
bodyA
,
PhysicsBody
bodyB
)
:
super
(
bodyA
,
bodyB
);
box2d
.
Joint
_createB2Joint
(
PhysicsNode
physicsNode
)
{
box2d
.
WeldJointDef
b2Def
=
new
box2d
.
WeldJointDef
();
Vector2
middle
=
new
Vector2
(
(
bodyA
.
_body
.
position
.
x
+
bodyB
.
_body
.
position
.
x
)
/
2.0
,
(
bodyA
.
_body
.
position
.
y
+
bodyB
.
_body
.
position
.
y
)
/
2.0
);
b2Def
.
initialize
(
bodyA
.
_body
,
bodyB
.
_body
,
middle
);
return
physicsNode
.
b2World
.
createJoint
(
b2Def
);
}
}
packages/flutter_sprites/lib/physics_node.dart
View file @
ecd20b6f
...
...
@@ -83,6 +83,13 @@ class PhysicsNode extends Node {
void
_removeBodiesScheduledForDestruction
()
{
for
(
box2d
.
Body
b2Body
in
_bodiesScheduledForDestruction
)
{
// Destroy any joints before destroying the body
PhysicsBody
body
=
b2Body
.
userData
;
for
(
PhysicsJoint
joint
in
body
.
_joints
)
{
joint
.
_detach
();
}
// Destroy the body
b2World
.
destroyBody
(
b2Body
);
}
_bodiesScheduledForDestruction
.
clear
();
...
...
@@ -183,7 +190,57 @@ class PhysicsNode extends Node {
}
}
}
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
);
}
}
}
}
}
...
...
@@ -195,7 +252,9 @@ class PhysicsContact {
this
.
shapeA
,
this
.
shapeB
,
this
.
isTouching
,
this
.
isEnabled
this
.
isEnabled
,
this
.
touchingPoints
,
this
.
touchingNormal
);
final
Node
nodeA
;
...
...
@@ -204,6 +263,8 @@ class PhysicsContact {
final
PhysicsShape
shapeB
;
final
isTouching
;
bool
isEnabled
;
final
List
<
Point
>
touchingPoints
;
final
Offset
touchingNormal
;
}
class
_ContactCallbackInfo
{
...
...
@@ -264,19 +325,35 @@ class _ContactHandler extends box2d.ContactListener {
if
(
match
)
{
// We have contact and a matched callback, setup contact info
List
<
Point
>
touchingPoints
=
null
;
Offset
touchingNormal
=
null
;
// Fetch touching points, if any
if
(
b2Contact
.
isTouching
())
{
box2d
.
WorldManifold
manifold
=
new
box2d
.
WorldManifold
();
b2Contact
.
getWorldManifold
(
manifold
);
touchingNormal
=
new
Offset
(
manifold
.
normal
.
x
,
manifold
.
normal
.
y
);
touchingPoints
=
[];
for
(
Vector2
vec
in
manifold
.
points
)
{
touchingPoints
.
add
(
new
Point
(
vec
.
x
*
physicsNode
.
b2WorldToNodeConversionFactor
,
vec
.
y
*
physicsNode
.
b2WorldToNodeConversionFactor
));
}
}
// Create the contact
PhysicsContact
contact
=
new
PhysicsContact
(
bodyA
.
_node
,
bodyB
.
_node
,
fixtureA
.
userData
,
fixtureB
.
userData
,
b2Contact
.
isTouching
(),
b2Contact
.
isEnabled
()
b2Contact
.
isEnabled
(),
touchingPoints
,
touchingNormal
);
if
(
type
==
PhysicsContactType
.
postSolve
)
{
}
// Make callback
info
.
callback
(
type
,
contact
);
...
...
packages/flutter_sprites/lib/skysprites.dart
View file @
ecd20b6f
...
...
@@ -33,6 +33,7 @@ part 'node3d.dart';
part
'node_with_size.dart'
;
part
'particle_system.dart'
;
part
'physics_body.dart'
;
part
'physics_joint.dart'
;
part
'physics_node.dart'
;
part
'physics_shape.dart'
;
part
'sound.dart'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment