diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..76b7a5b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,124 @@ +extern crate sdl2; + +mod state; +mod player; +mod constants; + +use state::Positioned; +use state::Drawable; + +enum Result { + Win, + Loss, + Nothing, +} + +fn spawn(count: u64) -> Vec<state::Enemy> { + if count == 0 { + vec![state::Enemy::new()] + } else { + Vec::new() + } +} + +fn frame(canvas: &mut sdl2::render::WindowCanvas, state: &mut state::State, events: &mut sdl2::event::EventPollIterator) -> Result { + let mut new_bullets = Vec::new(); + let count = state.count; + for enemy in state.enemies.iter_mut() { + new_bullets.append(&mut enemy.act(count)); + } + for bullet in state.bullets.iter_mut() { + bullet.act(); + } + for bullet in state.player_bullets.iter_mut() { + bullet.act(); + } + state.player.act(events); + if count % state.player.fire_rate as u64 == 0 { + state.player_bullets.push(state::PBullet::new(state.player.x, 0., state.player.y, -1.)); + } + if state.bullets.iter().any(|bullet| state.player.overlaps(bullet)) || new_bullets.iter().any(|bullet| state.player.overlaps(bullet)) { + return Result::Loss; + } + for enemy in state.enemies.iter_mut() { + for bullet in state.player_bullets.iter_mut() { + if enemy.overlaps(bullet) { + bullet.delete(); + enemy.health -= 1; + } + } + } + state.enemies.retain(|enemy| state::Enemy::health(enemy) > 0); + state.enemies.append(&mut spawn(count)); + if state.enemies.len() == 0 { + return Result::Win; + } + state.bullets.retain(|bullet| !state::EBullet::outside(bullet)); + state.bullets.append(&mut new_bullets); + state.player_bullets.retain(|bullet| !state::PBullet::outside(bullet)); + for bullet in state.player_bullets.iter() { + bullet.draw(canvas); + } + for enemy in state.enemies.iter() { + enemy.draw(canvas); + } + for bullet in state.bullets.iter() { + bullet.draw(canvas); + } + state.player.draw(canvas); + state.count += 1; + Result::Nothing +} + +fn main() { + let sdl_context = sdl2::init().unwrap(); + let video_subsystem = sdl_context.video().unwrap(); + + let window = video_subsystem.window("rust-sdl2 demo", constants::X_DIM, constants::Y_DIM).position_centered().build().unwrap(); + let mut canvas = window.into_canvas().build().unwrap(); + + canvas.set_draw_color(sdl2::pixels::Color::RGB(255, 255, 255)); + canvas.clear(); + canvas.present(); + let mut event_pump = sdl_context.event_pump().unwrap(); + let start = std::time::Instant::now(); + let frame_duration = std::time::Duration::new(0, 1_000_000_000u32 / 60); + let mut frame_count = 0; + let mut state = state::State::new(); + let mut won = false; + 'running: loop { + if won { + for event in event_pump.poll_iter() { + match event { + sdl2::event::Event::Quit {..} | sdl2::event::Event::KeyDown { keycode: Some(sdl2::keyboard::Keycode::Escape), .. } => { + std::process::exit(0); + }, + _ => { }, + } + } + } else { + canvas.set_draw_color(sdl2::pixels::Color::RGB(255, 255, 255)); + canvas.clear(); + match frame(&mut canvas, &mut state, &mut event_pump.poll_iter()) { + Result::Loss => { + break; + } + Result::Win => { + canvas.set_draw_color(sdl2::pixels::Color::RGB(255, 204, 102)); + canvas.clear(); + canvas.present(); + won = true; + } + _ => { + canvas.present(); + } + } + } + let calc_time = frame_duration * frame_count; + match calc_time.checked_sub(start.elapsed()) { + Some(t) => std::thread::sleep(t), + None => (), + } + frame_count += 1; + } +} |
