// calculates and adds forces triggered by holding the movement keys down. // it also has to stop the forces applied by the prev call to this function void blastengines(struct objnode *player) { struct movement *thrust; cpFloat force, tforce; struct forces newf; cpVect rotv; cpFloat angvel; thrust = &player->pinfo->thrust; rotv = cpBodyGetRot(player->b); force = 0; // these test cases are to enforce soft limits on the rate of movement if (thrust->up && !thrust->down) { if (cpvunrotate(cpBodyGetVel(player->b), rotv).y < MAXVEL) force = FORCE; } else if (!thrust->up && thrust->down) { if (cpvunrotate(cpBodyGetVel(player->b), rotv).y > -MAXVEL) force = -FORCE; } tforce = 0; angvel = cpBodyGetAngVel(player->b); if (thrust->ccw && !thrust->cw) { if (angvel < MAXANGVEL) tforce += TFORCE; } else if (thrust->cw && !thrust->ccw) { if (angvel > -MAXANGVEL) tforce += -TFORCE; } newf.force = cpvrotate(cpv(0, force), rotv); newf.tforce = cpv(0, tforce); applyforces(player, thrust->prevf); applyforces(player, newf); thrust->prevf.force = cpvneg(newf.force); thrust->prevf.tforce = cpvneg(newf.tforce); }
static void update(int ticks) { int steps = 1; cpFloat dt = 1.0f/60.0f/(cpFloat)steps; for(int i=0; i<steps; i++){ // turn the control body based on the angle relative to the actual body cpVect mouseDelta = cpvsub(mousePoint, tankBody->p); cpFloat turn = cpvtoangle(cpvunrotate(tankBody->rot, mouseDelta)); cpBodySetAngle(tankControlBody, tankBody->a - turn); // drive the tank towards the mouse if(cpvnear(mousePoint, tankBody->p, 30.0)){ tankControlBody->v = cpvzero; // stop } else { cpFloat direction = (cpvdot(mouseDelta, tankBody->rot) > 0.0 ? 1.0 : -1.0); tankControlBody->v = cpvrotate(tankBody->rot, cpv(30.0f*direction, 0.0f)); } cpSpaceStep(space, dt); } }
cpVect * bmx_cpvect_unrotate(cpVect * vec, cpVect * vec1) { return bmx_cpvect_new(cpvunrotate(*vec, *vec1)); }