Mercurial > projects > chipmunkd
view trunk/tests/ChipmunkDemos/samples/Player.d @ 16:af2f61a96318
ported chipmunk demos
author | Extrawurst |
---|---|
date | Sat, 04 Dec 2010 02:02:29 +0100 |
parents | |
children |
line wrap: on
line source
// written in the D programming language module samples.Player; import chipmunkd.chipmunk; import samples.ChipmunkDemo; import gameApp; static cpSpace *space; struct PlayerStruct { cpFloat u; cpShape *shape; cpVect groundNormal; cpArray *groundShapes; } PlayerStruct playerInstance; static cpBool begin(cpArbiter *arb, cpSpace *space, void *ignore) { mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); PlayerStruct *player = cast(PlayerStruct *)a.data; cpVect n = cpvneg(cpArbiterGetNormal(arb, 0)); if(n.y > 0.0f){ cpArrayPush(player.groundShapes, b); } return cpTrue; } static cpBool preSolve(cpArbiter *arb, cpSpace *space, void *ignore) { mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); PlayerStruct *player = cast(PlayerStruct *)a.data; if(cpArbiterIsFirstContact(arb)){ a.u = player.u; // pick the most upright jump normal each frame cpVect n = cpvneg(cpArbiterGetNormal(arb, 0)); if(n.y >= player.groundNormal.y){ player.groundNormal = n; } } return cpTrue; } static void separate(cpArbiter *arb, cpSpace *space, void *ignore) { mixin(CP_ARBITER_GET_SHAPES!("arb", "a", "b")); PlayerStruct *player = cast(PlayerStruct *)a.data; cpArrayDeleteObj(player.groundShapes, b); if(player.groundShapes.num == 0){ a.u = 0.0f; player.groundNormal = cpvzero; } } static void playerUpdateVelocity(cpBody *_body, cpVect gravity, cpFloat damping, cpFloat dt) { cpBodyUpdateVelocity(_body, gravity, damping, dt); _body.v.y = cpfmax(_body.v.y, -700); _body.v.x = cpfclamp(_body.v.x, -400, 400); } static void update(int ticks) { static int lastJumpState = 0; int jumpState = (arrowDirection.y > 0.0f); cpBody *_body = playerInstance.shape._body; cpVect groundNormal = playerInstance.groundNormal; if(groundNormal.y > 0.0f){ playerInstance.shape.surface_v = cpvmult(cpvperp(groundNormal), 400.0f*arrowDirection.x); if(arrowDirection.x) cpBodyActivate(_body); } else { playerInstance.shape.surface_v = cpvzero; } // apply jump if(jumpState && !lastJumpState && cpvlengthsq(groundNormal)){ // body.v = cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.5f), 500.0f); _body.v = cpvadd(_body.v, cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.75f), 500.0f)); cpBodyActivate(_body); } if(playerInstance.groundShapes.num == 0){ cpFloat air_accel = _body.v.x + arrowDirection.x*(2000.0f); _body.f.x = _body.m*air_accel; // body.v.x = cpflerpconst(body.v.x, 400.0f*arrowDirection.x, 2000.0f/60.0f); } enum int steps = 3; enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps; for(int i=0; i<steps; i++){ cpSpaceStep(space, dt); } lastJumpState = jumpState; } static cpSpace * init() { cpResetShapeIdCounter(); space = cpSpaceNew(); space.iterations = 10; space.gravity = cpv(0, -1500); cpBody *_body; cpBody *staticBody = &space.staticBody; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; // add some other segments to play with shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-200), cpv(-220,240), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(320,-200), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(200,-240), cpv(320,-100), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-80), cpv(200,-80), 0.0f)); shape.e = 1.0f; shape.u = 1.0f; shape.layers = NOT_GRABABLE_MASK; shape.collision_type = 2; // Set up the player cpFloat radius = 15.0f; _body = cpSpaceAddBody(space, cpBodyNew(10.0f, INFINITY)); _body.p = cpv(0, -220); _body.velocity_func = &playerUpdateVelocity; shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, radius, cpvzero)); shape.e = 0.0f; shape.u = 2.0f; shape.collision_type = 1; playerInstance.u = shape.u; playerInstance.shape = shape; playerInstance.groundShapes = cpArrayNew(0); shape.data = &playerInstance; cpSpaceAddCollisionHandler(space, 1, 2, &begin, &preSolve, null, &separate, null); return space; } static void destroy() { cpSpaceFreeChildren(space); cpSpaceFree(space); cpArrayFree(playerInstance.groundShapes); } chipmunkDemo Player = { "Player", null, &init, &update, &destroy, };