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.OneWay; 23 24 import core.stdc.stdlib; 25 26 import std.math; 27 28 alias M_PI_2 = PI_2; 29 30 import demo.dchip; 31 32 import demo.ChipmunkDebugDraw; 33 import demo.ChipmunkDemo; 34 import demo.types; 35 36 struct OneWayPlatform 37 { 38 cpVect n; // direction objects may pass through 39 } 40 41 OneWayPlatform platformInstance; 42 43 cpBool preSolve(cpArbiter* arb, cpSpace* space, void* ignore) 44 { 45 mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); 46 OneWayPlatform* platform = cast(OneWayPlatform*)cpShapeGetUserData(a); 47 48 if (cpvdot(cpArbiterGetNormal(arb, 0), platform.n) < 0) 49 { 50 cpArbiterIgnore(arb); 51 return cpFalse; 52 } 53 54 return cpTrue; 55 } 56 57 void update(cpSpace* space, double dt) 58 { 59 cpSpaceStep(space, dt); 60 } 61 62 cpSpace* init() 63 { 64 ChipmunkDemoMessageString = "One way platforms are trivial in Chipmunk using a very simple collision callback.".dup; 65 66 cpSpace* space = cpSpaceNew(); 67 cpSpaceSetIterations(space, 10); 68 cpSpaceSetGravity(space, cpv(0, -100)); 69 70 cpBody * body_; 71 cpBody * staticBody = cpSpaceGetStaticBody(space); 72 cpShape* shape; 73 74 // Create segments around the edge of the screen. 75 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320, -240), cpv(-320, 240), 0.0f)); 76 cpShapeSetElasticity(shape, 1.0f); 77 cpShapeSetFriction(shape, 1.0f); 78 cpShapeSetLayers(shape, NOT_GRABABLE_MASK); 79 80 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320, -240), cpv(320, 240), 0.0f)); 81 cpShapeSetElasticity(shape, 1.0f); 82 cpShapeSetFriction(shape, 1.0f); 83 cpShapeSetLayers(shape, NOT_GRABABLE_MASK); 84 85 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320, -240), cpv(320, -240), 0.0f)); 86 cpShapeSetElasticity(shape, 1.0f); 87 cpShapeSetFriction(shape, 1.0f); 88 cpShapeSetLayers(shape, NOT_GRABABLE_MASK); 89 90 // Add our one way segment 91 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160, -100), cpv(160, -100), 10.0f)); 92 cpShapeSetElasticity(shape, 1.0f); 93 cpShapeSetFriction(shape, 1.0f); 94 cpShapeSetCollisionType(shape, 1); 95 cpShapeSetLayers(shape, NOT_GRABABLE_MASK); 96 97 // We'll use the data pointer for the OneWayPlatform struct 98 platformInstance.n = cpv(0, 1); // let objects pass upwards 99 cpShapeSetUserData(shape, &platformInstance); 100 101 // Add a ball to make things more interesting 102 cpFloat radius = 15.0f; 103 body_ = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); 104 cpBodySetPos(body_, cpv(0, -200)); 105 cpBodySetVel(body_, cpv(0, 170)); 106 107 shape = cpSpaceAddShape(space, cpCircleShapeNew(body_, radius, cpvzero)); 108 cpShapeSetElasticity(shape, 0.0f); 109 cpShapeSetFriction(shape, 0.9f); 110 cpShapeSetCollisionType(shape, 2); 111 112 cpSpaceAddCollisionHandler(space, 1, 2, null, &preSolve, null, null, null); 113 114 return space; 115 } 116 117 void destroy(cpSpace* space) 118 { 119 ChipmunkDemoFreeSpaceChildren(space); 120 cpSpaceFree(space); 121 } 122 123 ChipmunkDemo OneWay = { 124 "One Way Platforms", 125 1.0 / 60.0, 126 &init, 127 &update, 128 &ChipmunkDemoDefaultDrawImpl, 129 &destroy, 130 };