1 /*
2  * Copyright (c) 2007-2013 Scott Lembcke and Howling Moon Software
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 module demo.PyramidStack;
23 
24 import demo.dchip;
25 
26 import demo.ChipmunkDebugDraw;
27 import demo.ChipmunkDemo;
28 import demo.types;
29 
30 void update(cpSpace* space, double dt)
31 {
32     cpSpaceStep(space, dt);
33 }
34 
35 cpSpace* init()
36 {
37     cpSpace* space = cpSpaceNew();
38     cpSpaceSetIterations(space, 30);
39     cpSpaceSetGravity(space, cpv(0, -100));
40     cpSpaceSetSleepTimeThreshold(space, 0.5f);
41     cpSpaceSetCollisionSlop(space, 0.5f);
42 
43     cpBody * body_;
44     cpBody *staticBody = cpSpaceGetStaticBody(space);
45     cpShape* shape;
46 
47     // Create segments around the edge of the screen.
48     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320, -240), cpv(-320, 240), 0.0f));
49     cpShapeSetElasticity(shape, 1.0f);
50     cpShapeSetFriction(shape, 1.0f);
51     cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
52 
53     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320, -240), cpv(320, 240), 0.0f));
54     cpShapeSetElasticity(shape, 1.0f);
55     cpShapeSetFriction(shape, 1.0f);
56     cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
57 
58     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320, -240), cpv(320, -240), 0.0f));
59     cpShapeSetElasticity(shape, 1.0f);
60     cpShapeSetFriction(shape, 1.0f);
61     cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
62 
63     // Add lots of boxes.
64     for (int i = 0; i < 14; i++)
65     {
66         for (int j = 0; j <= i; j++)
67         {
68             body_ = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForBox(1.0f, 30.0f, 30.0f)));
69             cpBodySetPos(body_, cpv(j * 32 - i * 16, 300 - i * 32));
70 
71             shape = cpSpaceAddShape(space, cpBoxShapeNew(body_, 30.0f, 30.0f));
72             cpShapeSetElasticity(shape, 0.0f);
73             cpShapeSetFriction(shape, 0.8f);
74         }
75     }
76 
77     // Add a ball to make things more interesting
78     cpFloat radius = 15.0f;
79     body_ = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero)));
80     cpBodySetPos(body_, cpv(0, -240 + radius + 5));
81 
82     shape = cpSpaceAddShape(space, cpCircleShapeNew(body_, radius, cpvzero));
83     cpShapeSetElasticity(shape, 0.0f);
84     cpShapeSetFriction(shape, 0.9f);
85 
86     return space;
87 }
88 
89 void destroy(cpSpace* space)
90 {
91     ChipmunkDemoFreeSpaceChildren(space);
92     cpSpaceFree(space);
93 }
94 
95 ChipmunkDemo PyramidStack = {
96     "Pyramid Stack",
97     1.0 / 180.0,
98     &init,
99     &update,
100     &ChipmunkDemoDefaultDrawImpl,
101     &destroy,
102 };