void particle_loop(int fd, int num_particles) { struct particle *particles; int i; particles = malloc(sizeof(struct particle) * num_particles); for (i=0; i<num_particles; i++) particle_init(&particles[i]); while (1) { float dt = get_time_step(); for (i=0; i<num_particles; i++) particle_update(&particles[i], dt); rwand_update(fd, particles, num_particles, 40); } free(particles); }
static int lupdate(lua_State *L) { luaL_checktype(L,1,LUA_TUSERDATA); struct particle_system *ps = (struct particle_system *)lua_touserdata(L, 1); float dt = luaL_checknumber(L,2); struct matrix *anchor = (struct matrix*)lua_touserdata(L, 3); int edge = (int)luaL_checkinteger(L, 4); /* if (ps->config->positionType == POSITION_TYPE_GROUPED) { struct matrix *m = (struct matrix *)lua_touserdata(L, 3); ps->config->sourcePosition.x = m->m[4] / SCREEN_SCALE; ps->config->sourcePosition.y = m->m[5] / SCREEN_SCALE; } else { ps->config->sourcePosition.x = 0; ps->config->sourcePosition.y = 0; }*/ bool ok = particle_update(ps, dt, anchor); lua_pushboolean(L, ok); return 1; }
void update(void) { static int time = 0; if(SDL_GetTicks() - time > 16){ flicker = !flicker; time = SDL_GetTicks(); float pos[2] = {0.0f, 1.0f}; float vel[2] = {0.0f, 0.0f}; float ang = angle + (1.0f - 2.0f*(float)rand() / (float) RAND_MAX) * log(scale[player->state]) * - 5; float rad = 175.0f + 250 * exp(scale[player->state] / scale[elephant]); pos[0] = cos(3.0f*PI/2.0f-ang) * rad; pos[1] = sin(3.0f*PI/2.0f-ang) * rad; particle_add(pos, vel); } if(!title){ actor_update(player); particle_update(); } }
// the main game loop which will run until the game is done void game_loop() { SDL_Event event, e; SDL_TimerID timer; int last_game_update = 0; int last_particle_update = 0; int last_render = 0; int previous_level = 0; debug_print("Loading media..."); load_media(); // check if we want to show score increments game.show_score_increments = atoi(config_getValue("show_score_increments")); // setup input input_init(); // create & show menu ui_menuInit(); ui_toggleMenuVisible(); SDL_SetEventFilter(ui_handleEvents); // loop forever debug_print("Entering main game loop..."); while (1) { // see if its time to trigger an update (make sure we're not paused either) if (!game.paused && SDL_GetTicks() - last_game_update > game_getGameUpdateFreq()) { last_game_update = SDL_GetTicks(); // remember time of last update game_update(); } if (game.show_score_increments) { // at the moment we just have the one particle set // see if its time to trigger a particle update if (SDL_GetTicks() - last_particle_update > PARTICLE_UPDATE_INTERVAL) { last_particle_update = SDL_GetTicks(); particle_update(); } } // check for any events waiting while (SDL_PollEvent(&event)) { switch(event.type) { // key presses are handled in input.c case SDL_KEYDOWN: input_onKeyDown(event.key.keysym.sym); break; case LEFT_KEY: tetromino_moveLeft(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveRight(current_tetromino); } break; case RIGHT_KEY: tetromino_moveRight(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveLeft(current_tetromino); } break; case DOWN_KEY: // uses the key repeat interval to accelerate the tetromino down tetromino_moveDown(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveUp(current_tetromino); } break; case UP_KEY: // rotate to a new position tetromino_setNextPosition(current_tetromino); tetromino_setShape(current_tetromino, current_tetromino->type, current_tetromino->position); // make sure the new position doesn't cause any collisions // if it does, reverse the rotation if (grid_checkCollision(grid, current_tetromino)) { tetromino_setPrevPosition(current_tetromino); tetromino_setShape(current_tetromino, current_tetromino->type, current_tetromino->position); } break; case SPACE_KEY: tetromino_moveDown(current_tetromino); // move the tetromino down until it causes a collision while (!grid_checkCollision(grid, current_tetromino)) { tetromino_moveDown(current_tetromino); } // once we have a collision, move it back into place tetromino_moveUp(current_tetromino); break; case PAUSE_KEY: debug_print("Pausing game"); game.paused = !game.paused; // stop the game timer if (game.paused) { SDL_RemoveTimer(timer); timer = NULL; } else { // start it again timer = SDL_AddTimer(1000, game_updateTime, NULL); } break; case ESCAPE_KEY: // pause game updates debug_print("Escape key pressed."); // toggle paused game state if we're in game if (grid && current_tetromino) { game.paused = !game.paused; if (game.paused) { // stop couting time played SDL_RemoveTimer(timer); timer = NULL; } // starting timer again, only if we're still in a game else if (grid && current_tetromino) { timer = SDL_AddTimer(1000, game_updateTime, NULL); } } // show or hide the menu if (grid && current_tetromino) { ui_toggleMenuVisible(); } // enable ui message pump if its visible if (ui_isMenuVisible()) { // if we're in game, show in-game menu if (grid && current_tetromino) { ui_menuPageSetCurrentById(MENU_IN_GAME); } // otherwise show main menu else { ui_menuPageSetCurrentById(MENU_MAIN); } SDL_SetEventFilter(ui_handleEvents); } break; case GAME_START_NEW: // set some game variables game.level = 0; game.score = 0; game.lines = 0; game.paused = 0; // time variables game.hours = 0; game.minutes = 0; game.seconds = 0; // create the grid grid = grid_createNew(GRID_WIDTH, GRID_HEIGHT); // create the first tetromino current_tetromino = tetromino_createNew(); current_tetromino->x = 0; current_tetromino->y = 0; // update time SDL_Init(SDL_INIT_TIMER); if (timer) { SDL_RemoveTimer(timer); timer = NULL; } ui_toggleMenuVisible(); timer = SDL_AddTimer(1000, game_updateTime, NULL); game.paused = 0; break; case GAME_END: // called by either the menu or game over scenario // destroy timer, grid and tetromino SDL_RemoveTimer(timer); timer = NULL; grid_destroy(grid); grid = NULL; tetromino_destroy(current_tetromino); current_tetromino = NULL; // show menu if it isn't already visible ui_menuPageSetCurrentById(MENU_MAIN); if (!ui_isMenuVisible()) { SDL_SetEventFilter(ui_handleEvents); ui_toggleMenuVisible(); } break; case TETROMINO_CREATE: // assumes that the old one has already been discarded current_tetromino = tetromino_createNew(); current_tetromino->x = 0; current_tetromino->y = 0; // check if we have an immediate collision (game over) if (grid_checkCollision(grid, current_tetromino)) { SDL_RemoveTimer(timer); timer = NULL; e.type = GAME_END; SDL_PushEvent(&e); } break; case GRID_REMOVE_LINE: if (game.show_score_increments) { // animated score increment game_showScoreIncrement(event.user.code, (game.level + 1) * 10); } grid_removeLine(grid, event.user.code); // increment number of complete lines game.lines += 1; // +10 per block and x10 per level game.score += (game.level + 1) * 10 * GRID_WIDTH; // increment the game level every 10 lines previous_level = game.level; game.level = game.lines / 10; if (previous_level != game.level) { game_showLevelIncrement(); } break; case GAME_QUIT: SDL_RemoveTimer(timer); // stop gameplay timer timer = NULL; game_shutdown(); break; // unhandled events are ignored default: break; } } // update the display // without this delay gfx card tries to commit suicide by melting if (SDL_GetTicks() - last_render > 3) { display_update(); last_render= SDL_GetTicks(); } } }