void update_brickwall(SPRITESPTR brickwall) { int nflags = 0; brickwall->shape->body->v = cpv(-180, 0); add_element_to_render_queue(brickwall->sdata.currentimg->image, brickwall->sdata.x, brickwall->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); brickwall->sdata.x = brickwall->shape->body->p.x-brickwall->sdata.currentimg->width/2; brickwall->sdata.y = brickwall->shape->body->p.y-brickwall->sdata.currentimg->height/2; if((brickwall->sdata.animflags & MDOWN)) { ALLEGRO_MOUSE_STATE mouse; al_get_mouse_state(&mouse); float x = brickwall->sdata.x; float y = brickwall->sdata.y; float width = brickwall->sdata.currentimg->width; float height = brickwall->sdata.currentimg->height; if((mouse.x >= x && mouse.x <= x+width) && (mouse.y >= y && mouse.y <= y+height)) { cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, brickwall, NULL); score += 2; } remove_anim_flags_on_sprite(brickwall, MDOWN); } if(brickwall->sdata.x+brickwall->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, brickwall, NULL); }
// collision arbiter function static int core_begin_collision ( cpArbiter *arb, cpSpace *space, void *unused ) { CP_ARBITER_GET_SHAPES ( arb, a, b ); ((GameInfo *)space->data)->destroyed_planet = ((BodyInfo *)(b->body->data))->index; cpSpaceAddPostStepCallback (space, (cpPostStepFunc)postStepRemoveBody, b->body, NULL); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc)post_step_game_over, NULL, NULL ); return 0; }
// adds a freestyle shape given a pointer to a an array of vertices and the number of vertices //returns a cpbody due to the many shapes associated with one body cpBody *core_add_freestyle_shape ( cpSpace * space, cpVect* verts , const int num_verts, Color *color, const double friction, const double elasticity, const double density, const int index ) { if ( num_verts <= 1 ) return NULL; // first determine center of mass of object cpVect center; core_freestyle_center ( verts, num_verts, ¢er ); // calculate mass and moment cpFloat mass = core_freestyle_mass ( verts, num_verts, density ); // dummy moment calculation cpFloat moment = core_freestyle_moment ( verts, num_verts, center, density ); cpBody *body = cpBodyNew ( mass, moment ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc)postStepAddBody, body, NULL ); cpBodySetPos ( body, center ); // set index of body // add body info to body BodyInfo * bi = body_info_new(num_verts); bi->index = index; bi->type = FREESTYLE_TYPE; bi->num_verts = num_verts; for ( int i = 0; i < num_verts; i++ ) { (bi->verts[i]).x = verts[i].x; (bi->verts[i]).y = verts[i].y; } bi->color->r = color->r; bi->color->g = color->g; bi->color->b = color->b; bi->friction = friction; bi->density = density; bi->elasticity = elasticity; body->data = bi; // add line segment collision shapes to body for ( int i = 0; i < num_verts - 1; i++ ) { cpVect offset_a = cpvmult ( cpvsub ( verts[i], center), 1.0 ); cpVect offset_b = cpvmult ( cpvsub ( verts[i+1], center), 1.0 ); cpShape * segment = cpSegmentShapeNew ( body, offset_a, offset_b, 0.1 ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddShape, segment, NULL); segment->u = friction; DrawShapeInfo *info = draw_shape_info_new (); info->color->r = color->r; info->color->g = color->g; info->color->b = color->b; segment->data = ( cpDataPointer ) info; } return body; }
// adds nonstatic box shape to space // currently does not roate box static cpShape *core_add_box_shape ( cpSpace *space, Box *box, const int index ) { // calculate mass and moment of a box cpFloat mass = box->density * box->width * box->height; cpFloat moment = cpMomentForBox ( mass, box->width, box->height ); // add body with mass and moment of a square to space cpBody *body = cpBodyNew ( mass, moment ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddBody, body, NULL ); cpBodySetPos ( body, cpv ( box->x, box->y ) ); // set index of body BodyInfo * bi = body_info_new(0); bi->index = index; bi->type = BOX_TYPE; bi->p1x = box->x - (box->width) / 2.0; bi->p1y = box->y + (box->height) / 2.0; bi->p2x = box->x + (box->width) / 2.0;; bi->p2y = box->y - (box->height) / 2.0; bi->color->r = box->color->r; bi->color->g = box->color->g; bi->color->b = box->color->b; bi->friction = box->friction; bi->density = box->density; bi->elasticity = box->elasticity; body->data = bi; double hw = ( box->width ) / 2.0; double hh = ( box->height ) / 2.0; cpVect cpv1 = cpv ( -hw,-hh ); cpVect cpv2 = cpv ( -hw, hh ); cpVect cpv3 = cpv ( hw, hh ); cpVect cpv4 = cpv ( hw, -hh ); cpVect verts [4]= { cpv1, cpv2, cpv3, cpv4 }; // add box collision shape to body cpShape *boxShape = cpPolyShapeNew ( body, 4, verts, cpv ( 0, 0 ) ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddShape, boxShape, NULL ); cpShapeSetFriction ( boxShape, box->friction ); cpShapeSetElasticity ( boxShape, box->elasticity ); cpBodySetAngle ( body, box->angle); DrawShapeInfo *info = add_box_draw_shape_info ( box ); boxShape->data= ( cpDataPointer ) info; return boxShape; }
void update_clamp(SPRITESPTR clamp) { int nflags = 0; SIMAGEPTR arm = search_image_list_for_element(&(clamp->ifirstptr), "ARM"); if(clamp->sdata.x <= 200) { if(clamp->sdata.y+clamp->sdata.currentimg->height >= 470) clamp->shape->body->v = cpv(-180, 0); else clamp->shape->body->v = cpv(-180, 500); } else clamp->shape->body->v = cpv(-180, 0); if((clamp->sdata.animflags & MATTACK)) clamp->sdata.currentimg = search_image_list_for_element(&clamp->ifirstptr, "CLAMP_CLOSE"); add_element_to_render_queue(clamp->sdata.currentimg->image, clamp->sdata.x, clamp->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); add_element_to_render_queue(arm->image, clamp->sdata.x, clamp->sdata.y-arm->height, nflags, RCOLOR(255, 255, 255, 255), NULL); add_element_to_render_queue(arm->image, clamp->sdata.x, clamp->sdata.y-arm->height-arm->height, nflags, RCOLOR(255, 255, 255, 255), NULL); clamp->sdata.x = clamp->shape->body->p.x-clamp->sdata.currentimg->width/2; clamp->sdata.y = clamp->shape->body->p.y-clamp->sdata.currentimg->height/2; if(clamp->sdata.x+clamp->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, clamp, NULL); }
void update_plant(SPRITESPTR plant) { int nflags = 0; SIMAGEPTR stem = search_image_list_for_element(&(plant->ifirstptr), "STEM"); if(plant->sdata.x <= res_width/4) { if(plant->sdata.y+plant->sdata.currentimg->height <= 440) { plant->shape->body->v = cpv(-180, 0); plant->sdata.currentimg = search_image_list_for_element(&(plant->ifirstptr), "PLANT_1"); } else plant->shape->body->v = cpv(-180, -200); } else plant->shape->body->v = cpv(-180, 0); add_element_to_render_queue(plant->sdata.currentimg->image, plant->sdata.x, plant->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); add_element_to_render_queue(stem->image, plant->sdata.x, plant->sdata.y+plant->sdata.currentimg->height, nflags, RCOLOR(255, 255, 255, 255), NULL); plant->sdata.x = plant->shape->body->p.x-plant->sdata.currentimg->width/2; plant->sdata.y = plant->shape->body->p.y-plant->sdata.currentimg->height/2; if(plant->sdata.x+plant->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, plant, NULL); }
void update_ameans(SPRITESPTR amean) { int nflags = 0; amean->shape->body->v = cpv(-180, 0); amean->sdata.anim_counter++; if(amean->sdata.anim_counter < 7) { amean->sdata.currentimg = search_image_list_for_element(&amean->ifirstptr, "AMEAN_1"); } else if(amean->sdata.anim_counter > 7 && amean->sdata.anim_counter < 14) { amean->sdata.currentimg = search_image_list_for_element(&amean->ifirstptr, "AMEAN_2"); } else if(amean->sdata.anim_counter > 14 && amean->sdata.anim_counter < 21) { amean->sdata.currentimg = search_image_list_for_element(&amean->ifirstptr, "AMEAN_3"); } else if(amean->sdata.anim_counter > 21 && amean->sdata.anim_counter < 28) { amean->sdata.currentimg = search_image_list_for_element(&amean->ifirstptr, "AMEAN_2"); } else if(amean->sdata.anim_counter > 28) amean->sdata.anim_counter = 0; add_element_to_render_queue(amean->sdata.currentimg->image, amean->sdata.x, amean->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); amean->sdata.x = amean->shape->body->p.x-amean->sdata.currentimg->width/2; amean->sdata.y = amean->shape->body->p.y-amean->sdata.currentimg->height/2; if(amean->sdata.x+amean->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, amean, NULL); }
// adds static box shape to space static void core_add_static_box_shape ( cpSpace * space, Box * box ) { // add box collision shape to body cpFloat hw = box->width / 2.0; cpFloat hh = box->height / 2.0; double x = box->x; double y = box->y; cpVect verts[] = { cpv ( x - hw, y - hh ), cpv ( x - hw, y + hh ), cpv ( x + hw, y + hh ), cpv ( x + hw, y - hh ), }; cpShape * box_shape = cpPolyShapeNew ( space->staticBody, 4, verts, cpvzero ); cpShapeSetFriction ( (cpShape *) box_shape, box->friction ); cpShapeSetElasticity ( (cpShape *) box_shape, box->elasticity ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddShape, box_shape, NULL ); DrawShapeInfo *info = add_box_draw_shape_info ( box ); box_shape->data= ( cpDataPointer ) info; }
//destroy bodies out of bound static void core_destroy_out_bodies ( cpBody *body, void *data ) { cpVect pos = cpBodyGetPos ( body ); if ( pos.y < -50 || pos.y > (CORE_MAX_HEIGHT + 50) || pos.x < - 50 || pos.x > 200) { cpSpaceAddPostStepCallback( cpBodyGetSpace(body), (cpPostStepFunc)postStepRemoveBody, body, NULL ); } else return; }
static cpBool catcherBarBegin(cpArbiter *arb, cpSpace *space, void *unused) { cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b); Emitter *emitter = (Emitter *) a->data; emitter->queue++; cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, b, NULL); return cpFalse; }
int fff::explosive::Begin(cpArbiter *arb, cpSpace *space, void *pengine){ CP_ARBITER_GET_SHAPES(arb, explosiveshape, kittyshape); fff::explosive *explosive = static_cast<fff::explosive *>( cpShapeGetUserData(explosiveshape) ); fff::kitty *kitty = static_cast<fff::kitty *>( cpShapeGetUserData(kittyshape) ); kitty->applyImpulse(explosive->impulse); explosive->setExploding(); game.playExplosion(explosive->soundbuffer, explosive->sprite.GetPosition() ); cpSpaceAddPostStepCallback(space, fff::explosive::postStep, explosiveshape, NULL); game.startTheme(); return 0; }
static cpBool StickyPreSolve(cpArbiter *arb, cpSpace *space, void *data) { // We want to fudge the collisions a bit to allow shapes to overlap more. // This simulates their squishy sticky surface, and more importantly // keeps them from separating and destroying the joint. // Track the deepest collision point and use that to determine if a rigid collision should occur. cpFloat deepest = INFINITY; // Grab the contact set and iterate over them. cpContactPointSet contacts = cpArbiterGetContactPointSet(arb); for(int i=0; i<contacts.count; i++){ // Increase the distance (negative means overlaping) of the // collision to allow them to overlap more. // This value is used only for fixing the positions of overlapping shapes. cpFloat dist = contacts.points[i].dist + 2.0f*STICK_SENSOR_THICKNESS; contacts.points[i].dist = cpfmin(0.0f, dist); deepest = cpfmin(deepest, dist); } // Set the new contact point data. cpArbiterSetContactPointSet(arb, &contacts); // If the shapes are overlapping enough, then create a // joint that sticks them together at the first contact point. if(!cpArbiterGetUserData(arb) && deepest <= 0.0f){ CP_ARBITER_GET_BODIES(arb, bodyA, bodyB); // Create a joint at the contact point to hold the body in place. cpConstraint *joint = cpPivotJointNew(bodyA, bodyB, contacts.points[0].point); // Give it a finite force for the stickyness. cpConstraintSetMaxForce(joint, 3e3); // Schedule a post-step() callback to add the joint. cpSpaceAddPostStepCallback(space, PostStepAddJoint, joint, NULL); // Store the joint on the arbiter so we can remove it later. cpArbiterSetUserData(arb, joint); } // Position correction and velocity are handled separately so changing // the overlap distance alone won't prevent the collision from occuring. // Explicitly the collision for this frame if the shapes don't overlap using the new distance. return (deepest <= 0.0f); // Lots more that you could improve upon here as well: // * Modify the joint over time to make it plastic. // * Modify the joint in the post-step to make it conditionally plastic (like clay). // * Track a joint for the deepest contact point instead of the first. // * Track a joint for each contact point. (more complicated since you only get one data pointer). }
void Slice::SliceQuery(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha, struct SliceContext *context) { cpVect a = context->a; cpVect b = context->b; // Check that the slice was complete by checking that the endpoints aren't in the sliced shape. if(cpShapePointQuery(shape, a, NULL) > 0.0f && cpShapePointQuery(shape, b, NULL) > 0.0f){ // Can't modify the space during a query. // Must make a post-step callback to do the actual slicing. cpSpaceAddPostStepCallback(context->space, (cpPostStepFunc)SliceShapePostStep, shape, context); } }
// adds nonstatic circle shape to space // currently does not rotate static cpShape *core_add_circle_shape ( cpSpace *space, Circle * circ, const int index ) { // calculate mass and moment of circle cpFloat mass = circ->density * M_PI * circ->radius * circ->radius; cpFloat moment = cpMomentForCircle ( mass, 0, circ->radius, cpvzero ); // add body with mass and moment of a circle to space cpBody *body = cpBodyNew ( mass, moment ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddBody, body, NULL ); cpBodySetPos ( body, cpv ( circ->x, circ->y ) ); // set index of body BodyInfo * bi = body_info_new(0); bi->index = index; bi->type = CIRCLE_TYPE; bi->p1x = circ->x - (circ->radius); bi->p1y = circ->y + (circ->radius); bi->p2x = circ->x + (circ->radius); bi->p2y = circ->y - (circ->radius); bi->color->r = circ->color->r; bi->color->g = circ->color->g; bi->color->b = circ->color->b; bi->friction = circ->friction; bi->density = circ->density; bi->elasticity = circ->elasticity; body->data = bi; // adds circle collision shape to body cpShape *circShape = cpCircleShapeNew ( body, circ->radius, cpvzero ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddShape, circShape, NULL ); cpShapeSetFriction ( circShape, circ->friction ); cpShapeSetElasticity ( circShape, circ->elasticity ); //cpShapeSetCollisionType ( circShape , TARGET_COLLISION_TYPE ); DrawShapeInfo *info = add_circle_draw_shape_info ( circ ); circShape->data= ( cpDataPointer ) info; return circShape; }
void Chains::BreakableJointPostSolve(cpConstraint *joint, cpSpace *space) { cpFloat dt = cpSpaceGetCurrentTimeStep(space); // Convert the impulse to a force by dividing it by the timestep. cpFloat force = cpConstraintGetImpulse(joint)/dt; cpFloat maxForce = cpConstraintGetMaxForce(joint); // If the force is almost as big as the joint's max force, break it. if(force > 0.9*maxForce){ cpSpaceAddPostStepCallback(space, (cpPostStepFunc)BreakablejointPostStepRemove, joint, NULL); } }
// adds static circle shape to space static void core_add_static_circle_shape ( cpSpace * space, Circle * circ ) { cpVect offset = cpv ( circ->x, circ->y ); // add circle collision shape to space cpShape * circ_shape = cpCircleShapeNew ( space->staticBody, circ->radius, offset ); cpShapeSetFriction ( (cpShape *) circ_shape, circ->friction ); cpShapeSetElasticity ( (cpShape *) circ_shape, circ->elasticity ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddShape, circ_shape, NULL ); DrawShapeInfo *info = add_circle_draw_shape_info ( circ ); circ_shape->data= ( cpDataPointer ) info; }
void update_fist(SPRITESPTR fist) { int nflags = 0; fist->shape->body->v = cpv(-180, 0); add_element_to_render_queue(fist->sdata.currentimg->image, fist->sdata.x, fist->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); fist->sdata.x = fist->shape->body->p.x-fist->sdata.currentimg->width/2; fist->sdata.y = fist->shape->body->p.y-fist->sdata.currentimg->height/2; if(fist->sdata.x+fist->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, fist, NULL); }
void update_spikes(SPRITESPTR spikes) { int nflags = 0; spikes->shape->body->v = cpv(-180, 0); add_element_to_render_queue(spikes->sdata.currentimg->image, spikes->sdata.x, spikes->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); spikes->sdata.x = spikes->shape->body->p.x-spikes->sdata.currentimg->width/2; spikes->sdata.y = spikes->shape->body->p.y-spikes->sdata.currentimg->height/2; if(spikes->sdata.x+spikes->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, spikes, NULL); }
void update_raw(SPRITESPTR raw) { int nflags = 0; raw->shape->body->v = cpv(-180, 0); if(raw->sdata.x <= 600 && raw->sdata.x >= 550) { set_anim_flags_on_sprite(raw, MATTACK); } add_element_to_render_queue(raw->sdata.currentimg->image, raw->sdata.x, raw->sdata.y, nflags, RCOLOR(255, 255, 255, 255), NULL); if((raw->sdata.animflags & MATTACK)) { int x = raw->sdata.x-5*raw->sdata.anim_counter; int y = raw->sdata.y+30; SIMAGEPTR lazer = search_image_list_for_element(&(raw->ifirstptr), "LAZER"); raw->sdata.anim_counter++; raw->sdata.currentimg = search_image_list_for_element(&(raw->ifirstptr), "RAW_2"); if(x+lazer->width <= raw->sdata.x) { raw->sdata.currentimg = search_image_list_for_element(&(raw->ifirstptr), "RAW_1"); } if(x+lazer->width <= 0) { raw->sdata.anim_counter = 0; remove_anim_flags_on_sprite(raw, MATTACK); } SPRITESPTR stman = search_sprite_list_for_element("STICKMAN"); if((x >= stman->sdata.x && x <= stman->sdata.x+stman->sdata.currentimg->width) && (y >= stman->sdata.y && y <= stman->sdata.y+stman->sdata.currentimg->height) && !(stman->sdata.animflags & MDAMAGED) && !(stman->sdata.animflags & MRECOVER)) { lives--; set_anim_flags_on_sprite(stman, MDAMAGED); raw->sdata.anim_counter = 0; remove_anim_flags_on_sprite(raw, MATTACK); } add_element_to_render_queue(lazer->image, x, y, nflags, RCOLOR(255, 255, 255, 255), NULL); } raw->sdata.x = raw->shape->body->p.x-raw->sdata.currentimg->width/2; raw->sdata.y = raw->shape->body->p.y-raw->sdata.currentimg->height/2; if(raw->sdata.x+raw->sdata.currentimg->width <= 0) cpSpaceAddPostStepCallback(get_global_cpSpace(), &remove_enemy, raw, NULL); }
static cpBool bulletPlaneBeginFunc(cpArbiter *arb, cpSpace *space, void*) { cpShape *a,*b; cpArbiterGetShapes(arb, &a,&b); cpBody *targetBody = cpShapeGetBody(b); if (((Bullet *)cpBodyGetUserData(cpShapeGetBody(a)))->player()->body() != targetBody) { printf("Hit plane\n"); Player * player = (Player *)(cpBodyGetUserData(targetBody)); player->hurt(200); cpSpaceAddPostStepCallback( space, (cpPostStepFunc)ammoFree, a, NULL); return true; } return false; }
static cpBool HookCrate(cpArbiter *arb, cpSpace *space, void *data) { if(hookJoint == NULL){ // Get pointers to the two bodies in the collision pair and define local variables for them. // Their order matches the order of the collision types passed // to the collision handler this function was defined for CP_ARBITER_GET_BODIES(arb, hook, crate); // additions and removals can't be done in a normal callback. // Schedule a post step callback to do it. // Use the hook as the key and pass along the arbiter. cpSpaceAddPostStepCallback(space, (cpPostStepFunc)AttachHook, hook, crate); } return cpTrue; // return value is ignored for sensor callbacks anyway }
static void StickySeparate(cpArbiter *arb, cpSpace *space, void *data) { cpConstraint *joint = (cpConstraint *)cpArbiterGetUserData(arb); if(joint){ // The joint won't be removed until the step is done. // Need to disable it so that it won't apply itself. // Setting the force to 0 will do just that cpConstraintSetMaxForce(joint, 0.0f); // Perform the removal in a post-step() callback. cpSpaceAddPostStepCallback(space, PostStepRemoveJoint, joint, NULL); // NULL out the reference to the joint. // Not required, but it's a good practice. cpArbiterSetUserData(arb, NULL); } }
inline cpBool space_add_poststep(cpSpace *space, cpDataPointer key, cpDataPointer data) { return cpSpaceAddPostStepCallback(space, (void *)postStep, key, data); }
void Neoshooter::Shoot(void) { cpSpaceAddPostStepCallback(this->m_World->GetSpace(), ShootP, this, this->m_Owner); }
void cpSpacePostStepRemoveAndFreeShapeAndBody(cpSpace *space, cpShape *shape) { cpSpaceAddPostStepCallback(space, (cpPostStepFunc)removeAndFreeShapeAndBody, shape, space); }
static void postShapeFree(cpShape *shape, cpSpace *space){ cpSpaceAddPostStepCallback(space, (cpPostStepFunc)shapeFreeWrap, shape, NULL); }
static void postBodyFree(cpBody *body, cpSpace *space){ cpSpaceAddPostStepCallback(space, (cpPostStepFunc)bodyFreeWrap, body, NULL); }
static void postConstraintFree(cpConstraint *constraint, cpSpace *space){ cpSpaceAddPostStepCallback(space, (cpPostStepFunc)constraintFreeWrap, constraint, NULL); }
cpBool Space::addPostStepCallback(cpPostStepFunc func,void *key,void *data) { return cpSpaceAddPostStepCallback(space,func,key,data); }
cpBool Space::addPostStepCallback(PostStepFunc func,void *key) { return cpSpaceAddPostStepCallback(space,*SpaceAddPostStepCallback,key,&func); }