summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs124
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;
+ }
+}