16
|
1
|
|
2 // written in the D programming language
|
|
3
|
|
4 module samples.Tank;
|
|
5
|
|
6 import chipmunkd.chipmunk;
|
|
7
|
|
8 import samples.ChipmunkDemo;
|
|
9
|
|
10 import gameApp;
|
|
11
|
|
12 static cpSpace *space;
|
|
13
|
|
14 static cpBody *tankBody;
|
|
15 static cpBody *tankControlBody;
|
|
16
|
|
17 static void
|
|
18 update(int ticks)
|
|
19 {
|
|
20 enum int steps = 1;
|
|
21 enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
|
|
22
|
|
23 for(int i=0; i<steps; i++){
|
|
24 // turn the control _body based on the angle relative to the actual _body
|
|
25 cpVect mouseDelta = cpvsub(mousePos, tankBody.p);
|
|
26 cpFloat turn = cpvtoangle(cpvunrotate(tankBody.rot, mouseDelta));
|
|
27 cpBodySetAngle(tankControlBody, tankBody.a - turn);
|
|
28
|
|
29 // drive the tank towards the mouse
|
|
30 if(cpvnear(mousePos, tankBody.p, 30.0)){
|
|
31 tankControlBody.v = cpvzero; // stop
|
|
32 } else {
|
|
33 cpFloat direction = (cpvdot(mouseDelta, tankBody.rot) > 0.0 ? 1.0 : -1.0);
|
|
34 tankControlBody.v = cpvrotate(tankBody.rot, cpv(30.0f*direction, 0.0f));
|
|
35 }
|
|
36
|
|
37 cpSpaceStep(space, dt);
|
|
38 }
|
|
39 }
|
|
40
|
|
41 static cpBody *
|
|
42 add_box(cpFloat size, cpFloat mass)
|
|
43 {
|
|
44 cpVect verts[] = [
|
|
45 cpv(-size,-size),
|
|
46 cpv(-size, size),
|
|
47 cpv( size, size),
|
|
48 cpv( size,-size),
|
|
49 ];
|
|
50
|
|
51 cpFloat radius = cpvlength(cpv(size, size));
|
|
52
|
|
53 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts.ptr, cpvzero)));
|
|
54 _body.p = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
|
|
55
|
|
56 cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(_body, 4, verts.ptr, cpvzero));
|
|
57 shape.e = 0.0f; shape.u = 0.7f;
|
|
58
|
|
59 return _body;
|
|
60 }
|
|
61
|
|
62 static cpSpace *
|
|
63 init()
|
|
64 {
|
|
65 cpResetShapeIdCounter();
|
|
66
|
|
67 space = cpSpaceNew();
|
|
68 cpSpaceResizeActiveHash(space, 30.0f, 1000);
|
|
69 space.iterations = 10;
|
|
70 space.sleepTimeThreshold = 0.5f;
|
|
71
|
|
72 cpBody *staticBody = &space.staticBody;
|
|
73 cpShape *shape;
|
|
74
|
|
75 // Create segments around the edge of the screen.
|
|
76 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
|
|
77 shape.e = 1.0f; shape.u = 1.0f;
|
|
78 shape.layers = NOT_GRABABLE_MASK;
|
|
79
|
|
80 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
|
|
81 shape.e = 1.0f; shape.u = 1.0f;
|
|
82 shape.layers = NOT_GRABABLE_MASK;
|
|
83
|
|
84 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
|
|
85 shape.e = 1.0f; shape.u = 1.0f;
|
|
86 shape.layers = NOT_GRABABLE_MASK;
|
|
87
|
|
88 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
|
|
89 shape.e = 1.0f; shape.u = 1.0f;
|
|
90 shape.layers = NOT_GRABABLE_MASK;
|
|
91
|
|
92 for(int i=0; i<50; i++){
|
|
93 cpBody *_body = add_box(10.0, 1.0);
|
|
94
|
|
95 cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, _body, cpvzero, cpvzero));
|
|
96 pivot.biasCoef = 0.0f; // disable joint correction
|
|
97 pivot.maxForce = 1000.0f; // emulate linear friction
|
|
98
|
|
99 cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(staticBody, _body, 0.0f, 1.0f));
|
|
100 gear.biasCoef = 0.0f; // disable joint correction
|
|
101 gear.maxForce = 5000.0f; // emulate angular friction
|
|
102 }
|
|
103
|
|
104 // We joint the tank to the control _body and control the tank indirectly by modifying the control _body.
|
|
105 tankControlBody = cpBodyNew(INFINITY, INFINITY);
|
|
106 tankBody = add_box(15.0, 10.0);
|
|
107
|
|
108 cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(tankControlBody, tankBody, cpvzero, cpvzero));
|
|
109 pivot.biasCoef = 0.0f; // disable joint correction
|
|
110 pivot.maxForce = 10000.0f; // emulate linear friction
|
|
111
|
|
112 cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(tankControlBody, tankBody, 0.0f, 1.0f));
|
|
113 gear.biasCoef = 1.0f; // limit angular correction rate
|
|
114 gear.maxBias = 1.0f; // limit angular correction rate
|
|
115 gear.maxForce = 500000.0f; // emulate angular friction
|
|
116
|
|
117 return space;
|
|
118 }
|
|
119
|
|
120 static void
|
|
121 destroy()
|
|
122 {
|
|
123 cpBodyFree(tankControlBody);
|
|
124 cpSpaceFreeChildren(space);
|
|
125 cpSpaceFree(space);
|
|
126 }
|
|
127
|
|
128 chipmunkDemo Tank = {
|
|
129 "Tank",
|
|
130 null,
|
|
131 &init,
|
|
132 &update,
|
|
133 &destroy,
|
|
134 };
|