1 
2 // written in the D programming language
3 
4 module samples.OneWay;
5 
6 import dchip.all;
7 
8 import samples.ChipmunkDemo;
9 
10 static cpSpace *space;
11 
12 struct OneWayPlatform {
13     cpVect n; // direction objects may pass through
14 }
15 
16 static OneWayPlatform platformInstance;
17 
18 static cpBool
19 preSolve(cpArbiter *arb, cpSpace *space, void *ignore)
20 {
21     mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b"));
22     OneWayPlatform *platform = cast(OneWayPlatform *)a.data;
23 
24     if(cpvdot(cpArbiterGetNormal(arb, 0), platform.n) < 0){
25         cpArbiterIgnore(arb);
26         return cpFalse;
27     }
28 
29     return cpTrue;
30 }
31 
32 static void
33 update(int ticks)
34 {
35     int steps = 1;
36     cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
37 
38     for(int i=0; i<steps; i++){
39         cpSpaceStep(space, dt);
40     }
41 }
42 
43 static cpSpace *
44 init()
45 {
46     cpResetShapeIdCounter();
47 
48     space = cpSpaceNew();
49     space.iterations = 10;
50     space.gravity = cpv(0, -100);
51 
52     cpBody *_body;
53     cpBody *staticBody = space.staticBody;
54     cpShape *shape;
55 
56     // Create segments around the edge of the screen.
57     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
58     shape.e = 1.0f; shape.u = 1.0f;
59     shape.layers = NOT_GRABABLE_MASK;
60 
61     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
62     shape.e = 1.0f; shape.u = 1.0f;
63     shape.layers = NOT_GRABABLE_MASK;
64 
65     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
66     shape.e = 1.0f; shape.u = 1.0f;
67     shape.layers = NOT_GRABABLE_MASK;
68 
69     // Add our one way segment
70     shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-100), cpv(160,-100), 10.0f));
71     shape.e = 1.0f; shape.u = 1.0f;
72     shape.collision_type = 1;
73     shape.layers = NOT_GRABABLE_MASK;
74 
75     // We'll use the data pointer for the OneWayPlatform struct
76     platformInstance.n = cpv(0, 1); // let objects pass upwards
77     shape.data = &platformInstance;
78 
79 
80     // Add a ball to make things more interesting
81     cpFloat radius = 15.0f;
82     _body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero)));
83     _body.p = cpv(0, -200);
84     _body.v = cpv(0, 170);
85 
86     shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, radius, cpvzero));
87     shape.e = 0.0f; shape.u = 0.9f;
88     shape.collision_type = 2;
89 
90     cpSpaceAddCollisionHandler(space, 1, 2, null, &preSolve, null, null, null);
91 
92     return space;
93 }
94 
95 static void
96 destroy()
97 {
98     ChipmunkDemoFreeSpaceChildren(space);
99     cpSpaceFree(space);
100 }
101 
102 chipmunkDemo OneWay = {
103     "One Way Platforms",
104     null,
105     &init,
106     &update,
107     &destroy,
108 };