From 8656df15f29ebe0900db830eb6e5d8d1f11c2e03 Mon Sep 17 00:00:00 2001 From: Raymond Hogenson Date: Wed, 22 Aug 2018 16:28:58 -0400 Subject: Add introduction and conclusion screens We're releasing version 1.0.0 baby --- Cargo.toml | 4 +- src/assets/introduction.png | Bin 0 -> 972031 bytes src/assets/introduction.xcf | Bin 0 -> 1593811 bytes src/assets/loss.png | Bin 0 -> 384637 bytes src/assets/loss.xcf | Bin 0 -> 1341517 bytes src/assets/victory.png | Bin 0 -> 616762 bytes src/assets/victory.xcf | Bin 0 -> 1615937 bytes src/main.rs | 110 ++++++++++++++++++++++++++++++-------------- src/music.rs | 32 +++++++++++++ src/player.rs | 10 ++-- 10 files changed, 114 insertions(+), 42 deletions(-) create mode 100644 src/assets/introduction.png create mode 100644 src/assets/introduction.xcf create mode 100644 src/assets/loss.png create mode 100644 src/assets/loss.xcf create mode 100644 src/assets/victory.png create mode 100644 src/assets/victory.xcf create mode 100644 src/music.rs diff --git a/Cargo.toml b/Cargo.toml index a000292..a8f749b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "bullet-hell" -version = "0.1.0" +name = "stallman-shooter" +version = "1.0.0" authors = ["Raymond Hogenson "] [dependencies] diff --git a/src/assets/introduction.png b/src/assets/introduction.png new file mode 100644 index 0000000..b087f26 Binary files /dev/null and b/src/assets/introduction.png differ diff --git a/src/assets/introduction.xcf b/src/assets/introduction.xcf new file mode 100644 index 0000000..007bd6f Binary files /dev/null and b/src/assets/introduction.xcf differ diff --git a/src/assets/loss.png b/src/assets/loss.png new file mode 100644 index 0000000..ef786fa Binary files /dev/null and b/src/assets/loss.png differ diff --git a/src/assets/loss.xcf b/src/assets/loss.xcf new file mode 100644 index 0000000..41578ea Binary files /dev/null and b/src/assets/loss.xcf differ diff --git a/src/assets/victory.png b/src/assets/victory.png new file mode 100644 index 0000000..a02ce9d Binary files /dev/null and b/src/assets/victory.png differ diff --git a/src/assets/victory.xcf b/src/assets/victory.xcf new file mode 100644 index 0000000..c019796 Binary files /dev/null and b/src/assets/victory.xcf differ diff --git a/src/main.rs b/src/main.rs index 55066a2..e2638b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,16 +5,18 @@ mod state; mod player; mod constants; mod gates; +mod music; use state::Positioned; use state::Drawable; use state::Bullet; use std::io::Write; -enum Result { +enum FResult { Win, Loss, Nothing, + Exit, } struct Textures<'a> { @@ -24,7 +26,7 @@ struct Textures<'a> { ebullet: sdl2::render::Texture<'a>, } -fn frame, U: state::Bullet>(canvas: &mut sdl2::render::WindowCanvas, state: &mut state::State, events: &mut sdl2::event::EventPollIterator, textures: &Textures) -> Result { +fn frame, U: state::Bullet>(canvas: &mut sdl2::render::WindowCanvas, state: &mut state::State, events: &mut sdl2::event::EventPollIterator, textures: &Textures) -> FResult { let mut new_bullets = Vec::new(); let count = state.count; for enemy in state.enemies.iter_mut() { @@ -36,12 +38,17 @@ fn frame, U: state::Bullet>(canvas: &mut sdl2::render::Window for bullet in state.player_bullets.iter_mut() { bullet.act(); } - state.player.act(events); + match state.player.act(events) { + Err(_) => { + return FResult::Exit; + } + Ok(_) => { } + } if count % state.player.fire_rate as u64 == 0 { state.player_bullets.push(state::PBullet::new(state.player.x, 0., state.player.y, -3.5)); } if state.bullets.iter().any(|bullet| state.player.overlaps(bullet)) || new_bullets.iter().any(|bullet| state.player.overlaps(bullet)) { - return Result::Loss; + return FResult::Loss; } for enemy in state.enemies.iter_mut() { for bullet in state.player_bullets.iter_mut() { @@ -54,7 +61,7 @@ fn frame, U: state::Bullet>(canvas: &mut sdl2::render::Window } state.enemies.retain(|enemy| state::Enemy::health(enemy) > 0.); if state.enemies.len() == 0 { - return Result::Win; + return FResult::Win; } state.bullets.retain(|bullet| !U::outside(bullet)); state.bullets.append(&mut new_bullets); @@ -72,7 +79,7 @@ fn frame, U: state::Bullet>(canvas: &mut sdl2::render::Window canvas.set_draw_color(sdl2::pixels::Color::RGB(255, 0, 0)); canvas.draw_rect(sdl2::rect::Rect::new(0, 0, (state.enemies[0].health() * constants::X_DIM as f64).round() as u32, 20)).unwrap(); state.count += 1; - Result::Nothing + FResult::Nothing } /* Why tf do I not need a lifetime here? */ @@ -100,20 +107,62 @@ fn get_pbullet_surface() -> sdl2::surface::Surface<'static> { get_surface(include_bytes!("assets/player_pepp.png")) } +fn generic_message(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump, image: &[u8]) -> Result<(), ()> { + let surface = get_surface(image); + let texture_creator = canvas.texture_creator(); + let texture = texture_creator.create_texture_from_surface(surface).unwrap(); + canvas.copy(&texture, None, None).unwrap(); + canvas.present(); + for event in event_pump.wait_iter() { + match event { + sdl2::event::Event::Quit {..} => { + return Err(()); + }, + sdl2::event::Event::KeyDown { keycode: Some(sdl2::keyboard::Keycode::Return), .. } => { + return Ok(()); + } + _ => { } + } + } + Ok(()) +} + +fn introduction(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump) -> Result<(), ()> { + return generic_message(canvas, event_pump, include_bytes!("assets/introduction.png")); +} + +fn loss(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump) -> Result<(), ()> { + return generic_message(canvas, event_pump, include_bytes!("assets/loss.png")); +} + +fn victory(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump) -> Result<(), ()> { + return generic_message(canvas, event_pump, include_bytes!("assets/victory.png")); +} + fn main() { + let mut player = music::new(); + match player.play() { + Ok(_) => { } + Err(e) => { + println!("{}", e); + } + } 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(); + + match introduction(&mut canvas, &mut event_pump) { + Ok(_) => { } + Err(_) => { + return; + } + } + let frame_duration = std::time::Duration::new(0, 1_000_000_000u32 / 60); let mut state: state::State = state::State::new(); - let mut won = false; let player_surface = get_player_surface(); let enemy_surface = get_enemy_surface(); let ebullet_surface = get_ebullet_surface(); @@ -126,31 +175,22 @@ fn main() { let surfaces = Textures { player: player_texture, enemy: enemy_texture, pbullet: pbullet_texture, ebullet: ebullet_texture }; 'running: loop { let start = std::time::Instant::now(); - 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); - }, - _ => { }, - } + canvas.set_draw_color(sdl2::pixels::Color::RGB(255, 255, 255)); + canvas.clear(); + match frame(&mut canvas, &mut state, &mut event_pump.poll_iter(), &surfaces) { + FResult::Loss => { + let _ = loss(&mut canvas, &mut event_pump); + break; + } + FResult::Win => { + let _ = victory(&mut canvas, &mut event_pump); + break; + } + FResult::Exit => { + break; } - } 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(), &surfaces) { - Result::Loss => { - break; - } - Result::Win => { - canvas.set_draw_color(sdl2::pixels::Color::RGB(255, 204, 102)); - canvas.clear(); - canvas.present(); - won = true; - } - _ => { - canvas.present(); - } + FResult::Nothing => { + canvas.present(); } } /* Make sure this iteration took a whole frame */ diff --git a/src/music.rs b/src/music.rs new file mode 100644 index 0000000..90cd276 --- /dev/null +++ b/src/music.rs @@ -0,0 +1,32 @@ +extern crate std; + +pub struct Player { + player: Option, +} + +impl Player { + pub fn play(&mut self) -> Result<(), &'static str> { + match std::process::Command::new("mpv").arg("https://www.youtube.com/watch?v=TdWd7Znz00Q").arg("--no-video").stdin(std::process::Stdio::null()).spawn() { + Ok(child) => { + self.player = Some(child); + Ok(()) + } + Err(_) => Err("Couldn't use mpv to play music") + } + } +} + +impl Drop for Player { + fn drop(&mut self) { + match self.player { + Some(ref mut x) => { + let _ = x.kill(); + } + None => { } + } + } +} + +pub fn new() -> Player { + Player { player: None } +} diff --git a/src/player.rs b/src/player.rs index fa2abfa..471b2e4 100644 --- a/src/player.rs +++ b/src/player.rs @@ -22,13 +22,12 @@ impl Player { Player { x: 400, y: 500, x_d: 0, y_d: 0, down_p: false, left_p: false, right_p: false, up_p: false, fire_rate: 15, shift_p: false } } - pub fn act(&mut self, events: &mut sdl2::event::EventPollIterator){ + pub fn act(&mut self, events: &mut sdl2::event::EventPollIterator) -> Result<(), ()> { for event in events { match event { - sdl2::event::Event::Quit {..} | - sdl2::event::Event::KeyDown { keycode: Some(sdl2::keyboard::Keycode::Escape), .. } => { - std::process::exit(0); - }, + sdl2::event::Event::Quit {..} => { + return Err(()); + } sdl2::event::Event::KeyDown { keycode: Some(sdl2::keyboard::Keycode::Down), .. } => { self.down_p = true; self.y_d = -1; @@ -102,6 +101,7 @@ impl Player { self.x += if self.shift_p { self.x_d } else { self.x_d * 3 }; self.y += if self.shift_p { self.y_d } else { self.y_d * 3 }; + return Ok(()) } } -- cgit v1.3.1