1 2 // written in the D programming language 3 4 module samples.Player; 5 6 import dchip.all; 7 8 import samples.ChipmunkDemo; 9 10 import gameApp; 11 12 static cpSpace *space; 13 14 struct PlayerStruct { 15 cpFloat u; 16 cpShape *shape; 17 } 18 19 PlayerStruct playerInstance; 20 21 static void 22 playerUpdateVelocity(cpBody *body_, cpVect gravity, cpFloat damping, cpFloat dt) 23 { 24 cpBodyUpdateVelocity(body_, gravity, damping, dt); 25 body_.v.y = cpfmax(body_.v.y, -700); 26 body_.v.x = cpfclamp(body_.v.x, -400, 400); 27 } 28 29 static void 30 SelectPlayerGroundNormal(cpBody *body_, cpArbiter *arb, cpVect *groundNormal){ 31 cpVect n = cpArbiterGetNormal(arb, 0); 32 33 if(n.y > groundNormal.y){ 34 *groundNormal = n; 35 } 36 } 37 38 static void 39 update(int ticks) 40 { 41 static int lastJumpState = 0; 42 int jumpState = (arrowDirection.y > 0.0f); 43 44 cpBody *body_ = playerInstance.shape.body_; 45 46 cpVect groundNormal = cpvzero; 47 cpBodyEachArbiter(body_, cast(cpBodyArbiterIteratorFunc)&SelectPlayerGroundNormal, &groundNormal); 48 49 if(groundNormal.y > 0.0f){ 50 playerInstance.shape.surface_v = cpv(400.0f*arrowDirection.x, 0.0f);//cpvmult(cpvperp(groundNormal), 400.0f*arrowDirection.x); 51 if(arrowDirection.x) cpBodyActivate(body_); 52 } else { 53 playerInstance.shape.surface_v = cpvzero; 54 } 55 56 // apply jump 57 if(jumpState && !lastJumpState && cpvlengthsq(groundNormal)){ 58 // body.v = cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.5f), 500.0f); 59 body_.v = cpvadd(body_.v, cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.75f), 500.0f)); 60 cpBodyActivate(body_); 61 } 62 63 if(cpvlengthsq(groundNormal)){ 64 cpFloat air_accel = body_.v.x + arrowDirection.x*(2000.0f); 65 body_.f.x = body_.m*air_accel; 66 // body.v.x = cpflerpconst(body.v.x, 400.0f*arrowDirection.x, 2000.0f/60.0f); 67 } 68 69 int steps = 3; 70 cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps; 71 72 for(int i=0; i<steps; i++){ 73 cpSpaceStep(space, dt); 74 } 75 76 lastJumpState = jumpState; 77 } 78 79 80 static cpSpace * 81 init() 82 { 83 cpResetShapeIdCounter(); 84 85 space = cpSpaceNew(); 86 space.iterations = 10; 87 space.gravity = cpv(0, -1500); 88 space.sleepTimeThreshold = 9999999; 89 90 cpBody *body_; 91 cpBody *staticBody = space.staticBody; 92 cpShape *shape; 93 94 // Create segments around the edge of the screen. 95 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); 96 shape.e = 1.0f; shape.u = 1.0f; 97 shape.layers = NOT_GRABABLE_MASK; 98 shape.collision_type = 2; 99 100 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); 101 shape.e = 1.0f; shape.u = 1.0f; 102 shape.layers = NOT_GRABABLE_MASK; 103 shape.collision_type = 2; 104 105 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); 106 shape.e = 1.0f; shape.u = 1.0f; 107 shape.layers = NOT_GRABABLE_MASK; 108 shape.collision_type = 2; 109 110 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); 111 shape.e = 1.0f; shape.u = 1.0f; 112 shape.layers = NOT_GRABABLE_MASK; 113 shape.collision_type = 2; 114 115 // add some other segments to play with 116 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-200), cpv(-220,240), 0.0f)); 117 shape.e = 1.0f; shape.u = 1.0f; 118 shape.layers = NOT_GRABABLE_MASK; 119 shape.collision_type = 2; 120 121 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(320,-200), 0.0f)); 122 shape.e = 1.0f; shape.u = 1.0f; 123 shape.layers = NOT_GRABABLE_MASK; 124 shape.collision_type = 2; 125 126 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(200,-240), cpv(320,-100), 0.0f)); 127 shape.e = 1.0f; shape.u = 1.0f; 128 shape.layers = NOT_GRABABLE_MASK; 129 shape.collision_type = 2; 130 131 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-80), cpv(200,-80), 0.0f)); 132 shape.e = 1.0f; shape.u = 1.0f; 133 shape.layers = NOT_GRABABLE_MASK; 134 shape.collision_type = 2; 135 136 // Set up the player 137 cpFloat radius = 15.0f; 138 body_ = cpSpaceAddBody(space, cpBodyNew(10.0f, INFINITY)); 139 body_.p = cpv(0, -220); 140 body_.velocity_func = &playerUpdateVelocity; 141 142 shape = cpSpaceAddShape(space, cpCircleShapeNew(body_, radius, cpvzero)); 143 shape.e = 0.0f; shape.u = 2.0f; 144 shape.collision_type = 1; 145 146 playerInstance.u = shape.u; 147 playerInstance.shape = shape; 148 shape.data = &playerInstance; 149 150 return space; 151 } 152 153 static void 154 destroy() 155 { 156 ChipmunkDemoFreeSpaceChildren(space); 157 cpSpaceFree(space); 158 } 159 160 chipmunkDemo Player = { 161 "Player", 162 null, 163 &init, 164 &update, 165 &destroy, 166 };