comparison trunk/tests/ChipmunkDemos/samples/Player.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.Player;
5
6 import chipmunkd.chipmunk;
7
8 import samples.ChipmunkDemo;
9
10 import gameApp;
11
12 static cpSpace *space;
13
14 struct PlayerStruct {
15 cpFloat u;
16 cpShape *shape;
17 cpVect groundNormal;
18 cpArray *groundShapes;
19 }
20
21 PlayerStruct playerInstance;
22
23 static cpBool
24 begin(cpArbiter *arb, cpSpace *space, void *ignore)
25 {
26 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b"));
27 PlayerStruct *player = cast(PlayerStruct *)a.data;
28
29 cpVect n = cpvneg(cpArbiterGetNormal(arb, 0));
30 if(n.y > 0.0f){
31 cpArrayPush(player.groundShapes, b);
32 }
33
34 return cpTrue;
35 }
36
37 static cpBool
38 preSolve(cpArbiter *arb, cpSpace *space, void *ignore)
39 {
40 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b"));
41 PlayerStruct *player = cast(PlayerStruct *)a.data;
42
43 if(cpArbiterIsFirstContact(arb)){
44 a.u = player.u;
45
46 // pick the most upright jump normal each frame
47 cpVect n = cpvneg(cpArbiterGetNormal(arb, 0));
48 if(n.y >= player.groundNormal.y){
49 player.groundNormal = n;
50 }
51 }
52
53 return cpTrue;
54 }
55
56 static void
57 separate(cpArbiter *arb, cpSpace *space, void *ignore)
58 {
59 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b"));
60 PlayerStruct *player = cast(PlayerStruct *)a.data;
61
62 cpArrayDeleteObj(player.groundShapes, b);
63
64 if(player.groundShapes.num == 0){
65 a.u = 0.0f;
66 player.groundNormal = cpvzero;
67 }
68 }
69
70 static void
71 playerUpdateVelocity(cpBody *_body, cpVect gravity, cpFloat damping, cpFloat dt)
72 {
73 cpBodyUpdateVelocity(_body, gravity, damping, dt);
74 _body.v.y = cpfmax(_body.v.y, -700);
75 _body.v.x = cpfclamp(_body.v.x, -400, 400);
76 }
77
78
79 static void
80 update(int ticks)
81 {
82 static int lastJumpState = 0;
83 int jumpState = (arrowDirection.y > 0.0f);
84
85 cpBody *_body = playerInstance.shape._body;
86
87 cpVect groundNormal = playerInstance.groundNormal;
88 if(groundNormal.y > 0.0f){
89 playerInstance.shape.surface_v = cpvmult(cpvperp(groundNormal), 400.0f*arrowDirection.x);
90 if(arrowDirection.x) cpBodyActivate(_body);
91 } else {
92 playerInstance.shape.surface_v = cpvzero;
93 }
94
95 // apply jump
96 if(jumpState && !lastJumpState && cpvlengthsq(groundNormal)){
97 // body.v = cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.5f), 500.0f);
98 _body.v = cpvadd(_body.v, cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.75f), 500.0f));
99 cpBodyActivate(_body);
100 }
101
102 if(playerInstance.groundShapes.num == 0){
103 cpFloat air_accel = _body.v.x + arrowDirection.x*(2000.0f);
104 _body.f.x = _body.m*air_accel;
105 // body.v.x = cpflerpconst(body.v.x, 400.0f*arrowDirection.x, 2000.0f/60.0f);
106 }
107
108 enum int steps = 3;
109 enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
110
111 for(int i=0; i<steps; i++){
112 cpSpaceStep(space, dt);
113 }
114
115 lastJumpState = jumpState;
116 }
117
118 static cpSpace *
119 init()
120 {
121 cpResetShapeIdCounter();
122
123 space = cpSpaceNew();
124 space.iterations = 10;
125 space.gravity = cpv(0, -1500);
126
127 cpBody *_body;
128 cpBody *staticBody = &space.staticBody;
129 cpShape *shape;
130
131 // Create segments around the edge of the screen.
132 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
133 shape.e = 1.0f; shape.u = 1.0f;
134 shape.layers = NOT_GRABABLE_MASK;
135 shape.collision_type = 2;
136
137 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
138 shape.e = 1.0f; shape.u = 1.0f;
139 shape.layers = NOT_GRABABLE_MASK;
140 shape.collision_type = 2;
141
142 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
143 shape.e = 1.0f; shape.u = 1.0f;
144 shape.layers = NOT_GRABABLE_MASK;
145 shape.collision_type = 2;
146
147 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
148 shape.e = 1.0f; shape.u = 1.0f;
149 shape.layers = NOT_GRABABLE_MASK;
150 shape.collision_type = 2;
151
152 // add some other segments to play with
153 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-200), cpv(-220,240), 0.0f));
154 shape.e = 1.0f; shape.u = 1.0f;
155 shape.layers = NOT_GRABABLE_MASK;
156 shape.collision_type = 2;
157
158 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(320,-200), 0.0f));
159 shape.e = 1.0f; shape.u = 1.0f;
160 shape.layers = NOT_GRABABLE_MASK;
161 shape.collision_type = 2;
162
163 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(200,-240), cpv(320,-100), 0.0f));
164 shape.e = 1.0f; shape.u = 1.0f;
165 shape.layers = NOT_GRABABLE_MASK;
166 shape.collision_type = 2;
167
168 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-80), cpv(200,-80), 0.0f));
169 shape.e = 1.0f; shape.u = 1.0f;
170 shape.layers = NOT_GRABABLE_MASK;
171 shape.collision_type = 2;
172
173 // Set up the player
174 cpFloat radius = 15.0f;
175 _body = cpSpaceAddBody(space, cpBodyNew(10.0f, INFINITY));
176 _body.p = cpv(0, -220);
177 _body.velocity_func = &playerUpdateVelocity;
178
179 shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, radius, cpvzero));
180 shape.e = 0.0f; shape.u = 2.0f;
181 shape.collision_type = 1;
182
183 playerInstance.u = shape.u;
184 playerInstance.shape = shape;
185 playerInstance.groundShapes = cpArrayNew(0);
186 shape.data = &playerInstance;
187
188 cpSpaceAddCollisionHandler(space, 1, 2, &begin, &preSolve, null, &separate, null);
189
190 return space;
191 }
192
193 static void
194 destroy()
195 {
196 cpSpaceFreeChildren(space);
197 cpSpaceFree(space);
198
199 cpArrayFree(playerInstance.groundShapes);
200 }
201
202 chipmunkDemo Player = {
203 "Player",
204 null,
205 &init,
206 &update,
207 &destroy,
208 };