Mercurial > projects > chipmunkd
comparison trunk/tests/ChipmunkDemos/samples/Sensors.d @ 16:af2f61a96318
ported chipmunk demos
author | Extrawurst |
---|---|
date | Sat, 04 Dec 2010 02:02:29 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:df4ebc8add66 | 16:af2f61a96318 |
---|---|
1 | |
2 // written in the D programming language | |
3 | |
4 module samples.Sensors; | |
5 | |
6 import chipmunkd.chipmunk; | |
7 | |
8 import samples.ChipmunkDemo; | |
9 | |
10 static cpSpace *space; | |
11 | |
12 enum CollisionTypes { | |
13 BALL_TYPE, | |
14 BLOCKING_SENSOR_TYPE, | |
15 CATCH_SENSOR_TYPE, | |
16 }; | |
17 | |
18 struct Emitter { | |
19 int queue; | |
20 int blocked; | |
21 cpVect position; | |
22 } | |
23 | |
24 static Emitter emitterInstance; | |
25 | |
26 static cpBool | |
27 blockerBegin(cpArbiter *arb, cpSpace *space, void *unused) | |
28 { | |
29 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); | |
30 Emitter *emitter = cast(Emitter *) a.data; | |
31 | |
32 emitter.blocked++; | |
33 | |
34 return cpFalse; // Return values from sensors callbacks are ignored, | |
35 } | |
36 | |
37 static void | |
38 blockerSeparate(cpArbiter *arb, cpSpace *space, void *unused) | |
39 { | |
40 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); | |
41 Emitter *emitter = cast(Emitter *)a.data; | |
42 | |
43 emitter.blocked--; | |
44 } | |
45 | |
46 static void | |
47 postStepRemove(cpSpace *space, cpShape *shape, void *unused) | |
48 { | |
49 cpSpaceRemoveBody(space, shape._body); | |
50 cpSpaceRemoveShape(space, shape); | |
51 | |
52 cpBodyFree(shape._body); | |
53 cpShapeFree(shape); | |
54 } | |
55 | |
56 static cpBool | |
57 catcherBarBegin(cpArbiter *arb, cpSpace *space, void *unused) | |
58 { | |
59 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); | |
60 Emitter *emitter = cast(Emitter *) a.data; | |
61 | |
62 emitter.queue++; | |
63 cpSpaceAddPostStepCallback(space, cast(cpPostStepFunc)&postStepRemove, b, null); | |
64 | |
65 return cpFalse; | |
66 } | |
67 | |
68 static cpFloat frand_unit(){return 2.0f*(frand()) - 1.0f;} | |
69 | |
70 static void | |
71 update(int ticks) | |
72 { | |
73 int steps = 1; | |
74 cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps; | |
75 | |
76 if(!emitterInstance.blocked && emitterInstance.queue){ | |
77 emitterInstance.queue--; | |
78 | |
79 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 15.0f, 0.0f, cpvzero))); | |
80 _body.p = emitterInstance.position; | |
81 _body.v = cpvmult(cpv(frand_unit(), frand_unit()), 100.0f); | |
82 | |
83 cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, 15.0f, cpvzero)); | |
84 shape.collision_type = CollisionTypes.BALL_TYPE; | |
85 } | |
86 | |
87 for(int i=0; i<steps; i++){ | |
88 cpSpaceStep(space, dt); | |
89 } | |
90 } | |
91 | |
92 static cpSpace * | |
93 init() | |
94 { | |
95 cpResetShapeIdCounter(); | |
96 | |
97 space = cpSpaceNew(); | |
98 space.iterations = 10; | |
99 space.gravity = cpv(0, -100); | |
100 | |
101 cpBody *staticBody = &space.staticBody; | |
102 cpShape *shape; | |
103 | |
104 // Data structure for our ball emitter | |
105 // We'll use two sensors for it, one to see if the emitter is blocked | |
106 // a second to catch the balls and add them back to the emitter | |
107 emitterInstance.queue = 5; | |
108 emitterInstance.blocked = 0; | |
109 emitterInstance.position = cpv(0, 150); | |
110 | |
111 // Create our blocking sensor, so we know when the emitter is clear to emit another ball | |
112 shape = cpSpaceAddShape(space, cpCircleShapeNew(staticBody, 15.0f, emitterInstance.position)); | |
113 shape.sensor = 1; | |
114 shape.collision_type = CollisionTypes.BLOCKING_SENSOR_TYPE; | |
115 shape.data = &emitterInstance; | |
116 | |
117 // Create our catch sensor to requeue the balls when they reach the bottom of the screen | |
118 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-2000, -200), cpv(2000, -200), 15.0f)); | |
119 shape.sensor = 1; | |
120 shape.collision_type = CollisionTypes.CATCH_SENSOR_TYPE; | |
121 shape.data = &emitterInstance; | |
122 | |
123 cpSpaceAddCollisionHandler(space, CollisionTypes.BLOCKING_SENSOR_TYPE, CollisionTypes.BALL_TYPE, &blockerBegin, null, null, &blockerSeparate, null); | |
124 cpSpaceAddCollisionHandler(space, CollisionTypes.CATCH_SENSOR_TYPE, CollisionTypes.BALL_TYPE, &catcherBarBegin, null, null, null, null); | |
125 | |
126 return space; | |
127 } | |
128 | |
129 static void | |
130 destroy() | |
131 { | |
132 cpSpaceFreeChildren(space); | |
133 cpSpaceFree(space); | |
134 } | |
135 | |
136 chipmunkDemo Sensors = { | |
137 "Sensors", | |
138 null, | |
139 &init, | |
140 &update, | |
141 &destroy, | |
142 }; |