//update space with the given time step, one line void core_update_space ( cpSpace *space, cpFloat time_step ) { GameInfo *info = (GameInfo *) (space->data); if ( info->gameisover == 1 || info->gameisover == 2 ) { printf ( "GAME IS OVER\n" ); core_explode_planet(space); } cpSpaceStep ( space, time_step ); cpSpaceEachBody ( space, &core_update_body, (void *) NULL ); cpSpaceEachBody ( space, &core_destroy_out_bodies, (void *) NULL ); }
void cpSpaceDestroy(cpSpace *space) { cpSpaceEachBody(space, (cpSpaceBodyIteratorFunc)cpBodyActivateWrap, NULL); cpSpatialIndexFree(space->staticShapes); cpSpatialIndexFree(space->dynamicShapes); cpArrayFree(space->dynamicBodies); cpArrayFree(space->staticBodies); cpArrayFree(space->sleepingComponents); cpArrayFree(space->rousedBodies); cpArrayFree(space->constraints); cpHashSetFree(space->cachedArbiters); cpArrayFree(space->arbiters); cpArrayFree(space->pooledArbiters); if(space->allocatedBuffers){ cpArrayFreeEach(space->allocatedBuffers, cpfree); cpArrayFree(space->allocatedBuffers); } if(space->postStepCallbacks){ cpArrayFreeEach(space->postStepCallbacks, cpfree); cpArrayFree(space->postStepCallbacks); } if(space->collisionHandlers) cpHashSetEach(space->collisionHandlers, FreeWrap, NULL); cpHashSetFree(space->collisionHandlers); }
DWORD WINAPI updateThread( LPVOID lpParam ) { clock_t spendTime; clock_t startTick; LARGE_INTEGER ticksPerSecond; LARGE_INTEGER start_ticks, end_ticks, cputime; //Tarkistetaan onko tarkempi kello käytettävissä if (!QueryPerformanceFrequency(&ticksPerSecond)) { startTick = clock(); cpSpaceStep(&mSpace,mTimeStep); spendTime = clock() - startTick; mUpdateTime = (float)spendTime/CLOCKS_PER_SEC*1000.0; } else { QueryPerformanceCounter(&start_ticks); cpSpaceStep(&mSpace,mTimeStep); QueryPerformanceCounter(&end_ticks); cputime.QuadPart = end_ticks.QuadPart- start_ticks.QuadPart; mUpdateTime = (double)cputime.QuadPart/(double)ticksPerSecond.QuadPart*1000.0; } //Nollataan voimat if (mAutoClearForces) cpSpaceEachBody(&mSpace,resetBodyForces,0); return 0; }
// Safe and future proof way to remove and free all objects that have been added to the space. void ChipmunkFreeSpaceChildren(cpSpace *space) { // Must remove these BEFORE freeing the body or you will access dangling pointers. cpSpaceEachShape(space, (cpSpaceShapeIteratorFunc)postShapeFree, space); cpSpaceEachConstraint(space, (cpSpaceConstraintIteratorFunc)postConstraintFree, space); cpSpaceEachBody(space, (cpSpaceBodyIteratorFunc)postBodyFree, space); }
static void update(int ticks) { int steps = 1; cpFloat dt = 1.0f/60.0f/(cpFloat)steps; for(int i=0; i<steps; i++){ cpSpaceStep(space, dt); cpSpaceEachBody(space, &eachBody, NULL); } }
//destroy all allocated memory of cpSpace struct void core_destroy_space ( cpSpace *space ) { //iterates through shapes and bodies and destroys them cpSpaceEachShape ( space, &core_destroy_shape, (void *) NULL ); cpSpaceEachBody ( space, &core_destroy_body, (void *) NULL ); destroy_body_info(space->staticBody->data); game_info_destroy ( (GameInfo *) space->data ); //frees space cpSpaceFree ( space ); }
// Updates all nescessary sprites, images, buttons etc. void update(void) { static _Bool called = false; GDATAPTR game = get_game_data(); update_background(); if(game->gamestarted && game->paused) { paused(score, survival_time, lives); } else if(lives == 0) { gameover(score, survival_time); } else if(game->gamestarted) { if(!called) { //cpSpaceResizeStaticHash(get_global_cpSpace(), 700.0, 4*10); cpSpaceAddCollisionHandler(get_global_cpSpace(), 1, 2, collision_begin, NULL, NULL, NULL, NULL); cpSpaceAddCollisionHandler(get_global_cpSpace(), 0, 2, collision_static_begin, NULL, NULL, NULL, NULL); cpSpaceAddCollisionHandler(get_global_cpSpace(), 0, 1, collision_static_begin, NULL, NULL, NULL, NULL); called = false; } logic(); update_clouds(); cpSpaceStep(get_global_cpSpace(), 1.0f/60.0f); cpSpaceEachBody(get_global_cpSpace(), &update_sprites, NULL); update_ground(); update_lives(); add_element_to_render_queue(NULL, 0, 0, 0, RCOLOR(0, 0, 0, 255), update_score); add_element_to_render_queue(NULL, 290, 0, 0, RCOLOR(0, 0, 0, 255), update_survivaltime); } else if(game->options) { options(); } else if(game->howtoplay) { howtoplay(); } else if(game->highscores) { highscores(); } }
static void update(cpSpace *space, double dt) { if(ChipmunkDemoRightDown){ cpShape *nearest = cpSpaceNearestPointQueryNearest(space, ChipmunkDemoMouse, 0.0, GRABABLE_MASK_BIT, CP_NO_GROUP, NULL); if(nearest){ cpBody *body = cpShapeGetBody(nearest); if(cpBodyIsStatic(body)){ cpSpaceConvertBodyToDynamic(space, body, pentagon_mass, pentagon_moment); cpSpaceAddBody(space, body); } else { cpSpaceRemoveBody(space, body); cpSpaceConvertBodyToStatic(space, body); } } } cpSpaceStep(space, dt); cpSpaceEachBody(space, &eachBody, NULL); }
inline void space_each_body(cpSpace *space, void *f) { cpSpaceEachBody(space, eachBody_space, f); }
void Space::eachBody(SpaceBodyIteratorFunc func) { cpSpaceEachBody(space,*SpaceEachBody,&func); }
void Space::eachBody(cpSpaceBodyIteratorFunc func,void *data) { cpSpaceEachBody(space,func,data); }
// core_load_level // reads contents of file, adds corresponding cpShapes to cpSpace // returns EXIT_SUCCESS if level loaded successfully // returns EXIT_FAILURE if level loaded unsuccessfully (bad syntax) static int core_load_level_parse ( cpSpace *space, FILE * fp ) { int max_line_size = 40; // maximum length of line that we want to read in // array to hold contents of each line char line [max_line_size]; char * line_place = line; // holds address of start of line fgets ( line, max_line_size, fp ); // check to see that first line has correct content if( strncmp ( line, "gravity ", 8 ) != 0 ) return EXIT_FAILURE; line_place = &line[8]; // advance line to next chars to be read double gravity = atof ( line_place ); // saves gravity input into a double core_set_gravity ( space, gravity ); // set gravity // check that next line is blank fgets ( line, max_line_size, fp ); int exit = 1; // keeps track of whether to continue reading lines while ( exit == 1 ) { if ( fgets ( line, max_line_size, fp ) == 0 ) return EXIT_SUCCESS; // get next line. If EOF, return if ( strncmp ( line, "box STATIC", 10 ) == 0 ) { // static box information to follow Box * box = box_new(); if ( parse_box ( fp, &(box->x), &(box->y), &(box->width), &(box->height), &(box->angle), (box->color), &(box->friction), &(box->elasticity), &(box->density)) == EXIT_FAILURE ) { fprintf ( stderr, "Parsing error in box STATIC\n" ); box_destroy ( box ); return EXIT_FAILURE; }; // add static box to space and destroy temporary box data core_add_static_box_shape ( space, box ); box_destroy ( box ); } else if ( strncmp ( line, "box NONSTATIC", 13 ) == 0 ) { Box * box = box_new(); if( parse_box ( fp, &(box->x), &(box->y), &(box->width), &(box->height), &(box->angle), (box->color), &(box->friction), &(box->elasticity), &(box->density) ) == EXIT_FAILURE ) { fprintf ( stderr, "Parsing error in box NONSTATIC\n" ); box_destroy ( box ); return EXIT_FAILURE; }; // need to add mass, inertia since body moves core_add_box_shape ( space, box, 0 ); box_destroy ( box ); } else if ( strncmp ( line, "ball NONSTATIC", 14 ) == 0 ) { Circle * circ = circle_new (); if ( parse_ball ( fp, &(circ->x), &(circ->y), &(circ->radius), &(circ->angle), circ->color, &(circ->friction), &(circ->elasticity), &(circ->density)) == EXIT_FAILURE ) { fprintf ( stderr, "Parsing error in ball NONSTATIC\n" ); circle_destroy ( circ ); return EXIT_FAILURE; } // need to add mass, inertia since body moves core_add_circle_shape ( space, circ, 0 ); circle_destroy ( circ ); } else if ( strncmp ( line, "ball STATIC", 11) == 0 ) { Circle * circ = circle_new(); if ( parse_ball ( fp, &(circ->x), &(circ->y), &(circ->radius), &(circ->angle), circ->color, &(circ->friction), &(circ->elasticity), &(circ->density) ) == EXIT_FAILURE ) { fprintf ( stderr, "Parsing error in ball STATIC\n" ); circle_destroy ( circ ); return EXIT_FAILURE; } core_add_static_circle_shape ( space, circ ); circle_destroy ( circ ); } else // invalid input return EXIT_FAILURE; if ( fgets ( line, max_line_size, fp ) == NULL ) exit = 0; // get next line. If EOF, get out } cpSpaceEachBody ( space, &core_update_body, (void *) NULL ); return EXIT_SUCCESS; }
static void draw_shape(cpShape* shape, SDL_Surface* screen) { cpBody* body = shape->body; struct draw_options opts = { .surface = screen, .colour = colour(200, 200, 200) }; switch (shape->CP_PRIVATE(klass)->type) { case CP_CIRCLE_SHAPE: draw_circle_shape(opts, shape, body); break; case CP_SEGMENT_SHAPE: draw_segment_shape(opts, shape, body); break; case CP_POLY_SHAPE: draw_poly_shape(opts, shape, body); break; default: debug_putsf("ignoring unrecognised shape type %d", shape->CP_PRIVATE(klass)->type); break; } } static void draw_constraint(cpConstraint* constraint, SDL_Surface *screen) { struct draw_options opts = { .surface = screen, .colour = colour(100, 100, 200) }; cpVect vect_a = cpBodyGetPos(cpConstraintGetA(constraint)); cpVect vect_b = cpBodyGetPos(cpConstraintGetB(constraint)); draw_line(opts, vect_a, vect_b); } static void draw_rotation_vector(cpBody *body, SDL_Surface *screen) { struct draw_options opts = { .surface = screen, .colour = colour(200, 100, 100) }; cpFloat rotation_vector_length = 30; cpVect pos = cpBodyGetPos(body); cpVect rotation = cpvmult(cpvforangle(cpBodyGetAngle(body)), rotation_vector_length); draw_line(opts, pos, cpvadd(pos, rotation)); } static void draw_forces(cpBody *body, SDL_Surface *screen) { struct draw_options opts = { .surface = screen, .colour = colour(100, 200, 100) }; cpVect pos = cpBodyGetPos(body); cpVect force = cpBodyGetForce(body); draw_line(opts, pos, cpvadd(pos, force)); } static void draw_body(cpBody *body, SDL_Surface *screen) { draw_rotation_vector(body, screen); draw_forces(body, screen); } void debug_draw_space(cpSpace* space, SDL_Surface* screen) { cpSpaceEachShape(space, (cpSpaceShapeIteratorFunc)draw_shape, screen); cpSpaceEachConstraint(space, (cpSpaceConstraintIteratorFunc)draw_constraint, screen); cpSpaceEachBody(space, (cpSpaceBodyIteratorFunc)draw_body, screen); }