1 
2 // written in the D programming language
3 
4 module samples.Pump;
5 
6 import dchip.all;
7 
8 import samples.ChipmunkDemo;
9 
10 import gameApp;
11 
12 import std.math;
13 
14 enum M_PI = PI;
15 enum M_PI_2 = PI*0.5f;
16 
17 static cpSpace *space;
18 static cpConstraint *motor;
19 
20 enum numBalls = 5;
21 static cpBody *balls[numBalls];
22 
23 static void
24 update(int ticks)
25 {
26     cpFloat coef = (2.0f + arrowDirection.y)/3.0f;
27     cpFloat rate = arrowDirection.x*30.0f*coef;
28 
29     cpSimpleMotorSetRate(motor, rate);
30     motor.maxForce = (rate ? 1000000.0f : 0.0f);
31 
32     enum int steps = 2;
33     enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
34 
35     for(int i=0; i<steps; i++){
36         cpSpaceStep(space, dt);
37 
38         for(int j=0; j<numBalls; j++){
39             cpBody *ball = balls[j];
40             if(ball.p.x > 320.0f){
41                 ball.v = cpvzero;
42                 ball.p = cpv(-224.0f, 200.0f);
43             }
44         }
45     }
46 }
47 
48 static cpBody *
49 add_ball(cpVect pos)
50 {
51     cpBody *_body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 30, 0, cpvzero)));
52     _body.p = pos;
53 
54     cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, 30, cpvzero));
55     shape.e = 0.0f; shape.u = 0.5f;
56 
57     return _body;
58 }
59 
60 static cpSpace *
61 init()
62 {
63     space = cpSpaceNew();
64     space.gravity = cpv(0, -600);
65 
66     cpBody *staticBody = space.staticBody;
67     cpShape *shape;
68 
69     // beveling all of the line segments slightly helps prevent things from getting stuck on cracks
70     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-256,300), 2.0f));
71     shape.e = 0.0f; shape.u = 0.5f; shape.layers = 1;
72     shape.layers = NOT_GRABABLE_MASK;
73 
74     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-192,0), 2.0f));
75     shape.e = 0.0f; shape.u = 0.5f; shape.layers = 1;
76     shape.layers = NOT_GRABABLE_MASK;
77 
78     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,0), cpv(-192, -64), 2.0f));
79     shape.e = 0.0f; shape.u = 0.5f; shape.layers = 1;
80     shape.layers = NOT_GRABABLE_MASK;
81 
82     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,-64), cpv(-128,144), 2.0f));
83     shape.e = 0.0f; shape.u = 0.5f; shape.layers = 1;
84     shape.layers = NOT_GRABABLE_MASK;
85 
86     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,80), cpv(-192,176), 2.0f));
87     shape.e = 0.0f; shape.u = 0.5f; shape.layers = 1;
88     shape.layers = NOT_GRABABLE_MASK;
89 
90     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,176), cpv(-128,240), 2.0f));
91     shape.e = 0.0f; shape.u = 0.0f; shape.layers = 1;
92     shape.layers = NOT_GRABABLE_MASK;
93 
94     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,144), cpv(192,64), 2.0f));
95     shape.e = 0.0f; shape.u = 0.5f; shape.layers = 1;
96     shape.layers = NOT_GRABABLE_MASK;
97 
98     cpVect verts[] = [
99         cpv(-30,-80),
100         cpv(-30, 80),
101         cpv( 30, 64),
102         cpv( 30,-80),
103     ];
104 
105     cpBody *plunger = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY));
106     plunger.p = cpv(-160,-80);
107 
108     shape = cpSpaceAddShape(space, cpPolyShapeNew(plunger, 4, verts.ptr, cpvzero));
109     shape.e = 1.0f; shape.u = 0.5f; shape.layers = 1;
110 
111     // add balls to hopper
112     for(int i=0; i<numBalls; i++)
113         balls[i] = add_ball(cpv(-224 + i,80 + 64*i));
114 
115     // add small gear
116     cpBody *smallGear = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 80, 0, cpvzero)));
117     smallGear.p = cpv(-160,-160);
118     cpBodySetAngle(smallGear, cast(float)-M_PI_2);
119 
120     shape = cpSpaceAddShape(space, cpCircleShapeNew(smallGear, 80.0f, cpvzero));
121     shape.layers = 0;
122 
123     cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, smallGear, cpv(-160,-160), cpvzero));
124 
125     // add big gear
126     cpBody *bigGear = cpSpaceAddBody(space, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 160, 0, cpvzero)));
127     bigGear.p = cpv(80,-160);
128     cpBodySetAngle(bigGear, cast(float)M_PI_2);
129 
130     shape = cpSpaceAddShape(space, cpCircleShapeNew(bigGear, 160.0f, cpvzero));
131     shape.layers = 0;
132 
133     cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, bigGear, cpv(80,-160), cpvzero));
134 
135     // connect the plunger to the small gear.
136     cpSpaceAddConstraint(space, cpPinJointNew(smallGear, plunger, cpv(80,0), cpv(0,0)));
137     // connect the gears.
138     cpSpaceAddConstraint(space, cpGearJointNew(smallGear, bigGear, -M_PI_2, -2.0f));
139 
140 
141     // feeder mechanism
142     cpFloat bottom = -300.0f;
143     cpFloat top = 32.0f;
144     cpBody *feeder = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForSegment(1.0f, cpv(-224.0f, bottom), cpv(-224.0f, top))));
145     feeder.p = cpv(-224, (bottom + top)/2.0f);
146 
147     cpFloat len = top - bottom;
148     cpSpaceAddShape(space, cpSegmentShapeNew(feeder, cpv(0.0f, len/2.0f), cpv(0.0f, -len/2.0f), 20.0f));
149 
150     cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, feeder, cpv(-224.0f, bottom), cpv(0.0f, -len/2.0f)));
151     cpVect anchr = cpBodyWorld2Local(feeder, cpv(-224.0f, -160.0f));
152     cpSpaceAddConstraint(space, cpPinJointNew(feeder, smallGear, anchr, cpv(0.0f, 80.0f)));
153 
154     // motorize the second gear
155     motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(staticBody, bigGear, 3.0f));
156 
157     return space;
158 }
159 
160 static void
161 destroy()
162 {
163     ChipmunkDemoFreeSpaceChildren(space);
164     cpSpaceFree(space);
165 }
166 
167 chipmunkDemo Pump = {
168     "Pump",
169     null,
170     &init,
171     &update,
172     &destroy,
173 };