void GenNextElements() { // Called every game loop, but only does work when close to next challange area if (g_current_race_pos + 2 * G_HEIGHT > g_next_challange_area) { float current_y = g_next_challange_area; LOG(("Current: %f\n", g_next_challange_area)); // Choose how many layers of rocks int nlayers = (int)CORE_URand(1, 20); LOG(("nlayers: %d\n", nlayers)); for (int i = 0; i < nlayers; i++) { LOG(("Where: %f\n", current_y)); // Choose pass point float displace = (current_y - g_last_conditioned.y) * PATH_TWIST_RATIO; float bracket_left = g_last_conditioned.x - displace; float bracket_right = g_last_conditioned.x + displace; bracket_left = MAX(bracket_left, 2.f * MAINSHIP_RADIUS); bracket_right = MIN(bracket_right, G_WIDTH - 2.f * MAINSHIP_RADIUS); g_last_conditioned.y = current_y; g_last_conditioned.x = CORE_FRand(bracket_left, bracket_right); // Choose how many rocks int nrocks = (int)CORE_URand(0, 3); LOG(("nrocks: %d\n", nrocks)); // Generate rocks for (int i = 0; i < nrocks; i++) { // Find a valid position vec2 rockpos; for (;;) { rockpos = vmake(CORE_FRand(0.f, G_WIDTH), current_y); if (rockpos.x + ROCK_RADIUS < g_last_conditioned.x - PATH_WIDTH || rockpos.x - ROCK_RADIUS > g_last_conditioned.x + PATH_WIDTH) break; } // Insert obstacle EType t = E_ROCK; int gfx = g_rock[1/*CORE_URand(0,4)*/]; if (CORE_RandChance(0.1f)) { t = E_MINE; gfx = g_mine; } // Mine? else if (CORE_RandChance(0.1f)) { t = E_DRONE; gfx = g_drone; } // Drone? vec2 vel = vmake(CORE_FRand(-0.5f, 0.5f), CORE_FRand(-0.5f, 0.5f)); // velocity InsertEntity(t, rockpos, vel, ROCK_RADIUS, gfx, true); // Insert the chosen entity } current_y += CORE_FRand(300.f, 600.f); } g_next_challange_area = current_y + CORE_FRand(.5f * G_HEIGHT, 1.5f * G_HEIGHT); } }
//---------------------------------------------------------------------------- void ResetNewGame() { // Reset everything for a new game g_next_challange_area = FIRST_CHALLANGE; g_last_conditioned = vmake(0.5f * G_WIDTH, 0.f); g_current_race_pos = 0.f; g_camera_offset = 0.f; g_rock_chance = START_ROCK_CHANCE_PER_PIXEL; g_gs = GS_STARTING; g_gs_timer = 0.f; // Start logic for (int i = 0; i < MAX_ENTITIES; i++) { g_entities[i].type = E_NULL; } // Insert main ship InsertEntity(E_MAIN, vmake(G_WIDTH / 2.0, G_HEIGHT / 8.f), vmake(0.f, SHIP_START_SPEED), MAINSHIP_RADIUS, g_ship_C, true); }
int main() { int i; ilist* list = NULL; list = CreateList(); // list = {'\0'} for(i = 0; i < 3; i++) { InsertEntity(list, i, i+1); /* * list = {1} * list = {1, 2} * list = {1, 2, 3} */ } for(i = 0; i < 3; i++) { printf("%d\n", GetEntity(list, 2)); } //printf("%d\n", GetEntity(list, 2)); // 2 /* InsertToList(list, 4, 1); // list = {1, 2, 3, '\0', 1} for(i = 0; i < GetNumberOfEntity(list); i++) { printf("%d, ", GetEntity(list, i)); * 1 * 2 * 3 * '\0' * 1 } DeleteEntity(list, 2); // list = {1, 2, '\0', 1} */ DeleteList(list); // (list) return 0; }
Entity* World::SpawnEntity( Class* pEntityClass, const Vector3f& pPosition, const Quaternionf& pOrientation, const String& pName ) { GD_ASSERT( pEntityClass && pEntityClass->IsDerivedFrom(Entity::StaticClass()) ); {Profile("Spawn"); {Profile(pEntityClass->GetName()); Entity* spawnedObject = Cast<Entity>( pEntityClass->AllocateNew() ); spawnedObject->SetOwner(this); spawnedObject->SetName( pName ); spawnedObject->SetWorld(this); spawnedObject->Init(); spawnedObject->SetPosition( pPosition ); spawnedObject->SetOrientation( pOrientation ); InsertEntity( spawnedObject ); return spawnedObject; } } }
//----------------------------------------------------------------------------- void RunGame() { // Control main ship if (g_gs == GS_VICTORY || g_gs == GS_STARTING) { if (MAIN_SHIP.vel.y < SHIP_CRUISE_SPEED) { MAIN_SHIP.vel.y = SAFEADD(MAIN_SHIP.vel.y, SHIP_INC_SPEED, SHIP_CRUISE_SPEED); } MAIN_SHIP.fuel = SAFESUB(MAIN_SHIP.fuel, FRAME_FUEL_COST); } // Heal main ship if (g_gs != GS_DYING) { if (MAIN_SHIP.energy < MAX_ENERGY && MAIN_SHIP.fuel > MIN_FUEL_FOR_HEAL) { MAIN_SHIP.energy = SAFEADD(MAIN_SHIP.energy, ENERGY_HEAL_PER_FRAME, MAX_ENERGY); MAIN_SHIP.fuel = SAFESUB(MAIN_SHIP.fuel, FUEL_HEAL_PER_FRAME); LOG(("- energy: %f, fuel: %f\n", MAIN_SHIP.energy, MAIN_SHIP.fuel)); } } // Move entities for (int i = MAX_ENTITIES - 1; i >= 0; i--) { if (g_entities[i].type != E_NULL) { g_entities[i].pos = vadd(g_entities[i].pos, g_entities[i].vel); // Remove entities that fell off screen if (g_entities[i].pos.y < g_camera_offset - G_HEIGHT) g_entities[i].type = E_NULL; } } // Advance "stars" for (int i = 0; i < MAX_ENTITIES; i++) { if (g_entities[i].type == E_STAR) g_entities[i].gfxscale *= 1.008f; } // Dont let steering off the screen if (MAIN_SHIP.pos.x < MAINSHIP_RADIUS) MAIN_SHIP.pos.x = MAINSHIP_RADIUS; if (MAIN_SHIP.pos.x > G_WIDTH - MAINSHIP_RADIUS) MAIN_SHIP.pos.x = G_WIDTH - MAINSHIP_RADIUS; // Check collisions if (g_gs == GS_PLAYING) { // Check everything against ship for (int i = 1; i < MAX_ENTITIES; i++) { // Should check against ship? if (g_entities[i].type == E_ROCK || g_entities[i].type == E_JUICE || g_entities[i].type == E_MINE || g_entities[i].type == E_DRONE) { float distance = vlen2(vsub(g_entities[i].pos, MAIN_SHIP.pos)); // Distance from object to ship float crash_distance = CORE_FSquare(g_entities[i].radius + MAIN_SHIP.radius); // Minimum allowed distance before crash if (distance < crash_distance) { switch (g_entities[i].type) { case E_ROCK: if (g_entities[i].energy > 0) { MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, ROCK_CRASH_ENERGY_LOSS); MAIN_SHIP.vel.y = SHIP_START_SPEED; // Set rock velocity vec2 vel_direction = vsub(g_entities[i].pos, MAIN_SHIP.pos); // direction of rock velocity, away from ship vec2 normalized_vel_direction = vunit(vel_direction); // normalize vec2 vel = vscale(normalized_vel_direction, CRASH_VEL); // Scale, ie give the rock correct speed. g_entities[i].vel = vel; g_entities[i].energy = 0; } break; case E_JUICE: MAIN_SHIP.fuel = SAFEADD(MAIN_SHIP.fuel, JUICE_FUEL, MAX_FUEL); g_entities[i].type = E_NULL; break; case E_MINE: MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, MINE_CRASH_ENERGY_LOSS); MAIN_SHIP.vel.y = SHIP_START_SPEED; g_entities[i].type = E_NULL; break; case E_DRONE: MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, MINE_CRASH_ENERGY_LOSS); MAIN_SHIP.vel.y = SHIP_START_SPEED; g_entities[i].type = E_NULL; break; default: break; } } } else if (g_entities[i].type == E_ROCKET) { // Check all hit-able objects against this rocket for (int j = 1; i < MAX_ENTITIES; j++) { // Should check against rocket? if (g_entities[j].type == E_ROCK || g_entities[j].type == E_MINE || g_entities[j].type == E_DRONE) { float distance = vlen2(vsub(g_entities[i].pos, g_entities[j].pos)); float crash_distance = CORE_FSquare(g_entities[i].radius + g_entities[j].radius); if (distance < crash_distance) { // Impact! g_entities[i].type = E_NULL; g_entities[j].type = E_NULL; break; } } } } } } // Generate new level elements as we advance GenNextElements(); // Possibly insert new juice if (g_gs == GS_PLAYING) { float trench = MAIN_SHIP.pos.y - g_current_race_pos; // How much advanced from previous frame if (CORE_RandChance(trench * JUICE_CHANCE_PER_PIXEL)) { vec2 pos = vmake(CORE_FRand(0.f, G_WIDTH), g_camera_offset + G_HEIGHT + GEN_IN_ADVANCE); // Random x, insert 400y above window vec2 vel = vmake(CORE_FRand(-1.f, +1.f), CORE_FRand(-1.f, +1.f)); // Random small velocity to make rocks "float" InsertEntity(E_JUICE, pos, vel, JUICE_RADIUS, g_juice, false, true); } } // Set camera to follow the main ship g_camera_offset = MAIN_SHIP.pos.y - G_HEIGHT / 8.f; g_current_race_pos = MAIN_SHIP.pos.y; if (g_gs == GS_PLAYING) { if (g_current_race_pos >= RACE_END) // Check if victory { g_gs = GS_VICTORY; g_gs_timer = 0.f; MAIN_SHIP.gfxadditive = true; } } // Advance game mode g_gs_timer += FRAMETIME; switch (g_gs) { case GS_STARTING: if (g_gs_timer >= STARTING_TIME) // Start delay before starting to play { g_gs = GS_PLAYING; g_gs_timer = 0.f; } break; case GS_DYING: if (g_gs_timer >= DYING_TIME) { ResetNewGame(); } break; case GS_PLAYING: if (MAIN_SHIP.energy <= 0.f || MAIN_SHIP.fuel <= 0.f) // No energy or fuel --> die { g_gs = GS_DYING; g_gs_timer = 0.f; MAIN_SHIP.gfx = g_ship_RR; } break; case GS_VICTORY: if (CORE_RandChance(1.f / 10.f)) { InsertEntity(E_STAR, MAIN_SHIP.pos, vadd(MAIN_SHIP.vel, vmake(CORE_FRand(-5.f, 5.f), CORE_FRand(-5.f, 5.f))), 0, g_star, false, true); } if (g_gs_timer >= 8.f) // Should use VICTORY_TIME, but stupid VS dont want me to... { ResetNewGame(); } break; } g_time_from_last_rocket += FRAMETIME; }