diff options
| -rw-r--r-- | Cargo.toml | 9 | ||||
| -rw-r--r-- | src/assets/introduction.png | bin | 972993 -> 972240 bytes | |||
| -rw-r--r-- | src/assets/introduction.xcf | bin | 1593413 -> 1593435 bytes | |||
| -rw-r--r-- | src/assets/loss.png | bin | 384637 -> 387827 bytes | |||
| -rw-r--r-- | src/assets/loss.xcf | bin | 1341517 -> 1347218 bytes | |||
| -rw-r--r-- | src/assets/stallman.png | bin | 4740 -> 5115 bytes | |||
| -rw-r--r-- | src/assets/stallman.xcf | bin | 6888 -> 8055 bytes | |||
| -rw-r--r-- | src/assets/victory.png | bin | 616762 -> 619939 bytes | |||
| -rw-r--r-- | src/assets/victory.xcf | bin | 1615937 -> 1619041 bytes | |||
| -rw-r--r-- | src/gates.rs | 27 | ||||
| -rw-r--r-- | src/main.rs | 151 | ||||
| -rw-r--r-- | src/music.rs | 32 | ||||
| -rw-r--r-- | src/player.rs | 4 |
13 files changed, 110 insertions, 113 deletions
@@ -5,10 +5,13 @@ authors = ["Raymond Hogenson <rhogenson@posteo.net>"] [dependencies] rand = "0.5.5" -lazy_static = "1.1.0" -tempfile = "3" [dependencies.sdl2] -version = "0.31.0" +git = "https://github.com/Rust-SDL2/rust-sdl2" +default-features = false +features = ["image"] + +[dependencies.sdl2-sys] +git = "https://github.com/Rust-SDL2/rust-sdl2" default-features = false features = ["image"] diff --git a/src/assets/introduction.png b/src/assets/introduction.png Binary files differindex 5e14519..bbc1530 100644 --- a/src/assets/introduction.png +++ b/src/assets/introduction.png diff --git a/src/assets/introduction.xcf b/src/assets/introduction.xcf Binary files differindex c12e25b..2d878fa 100644 --- a/src/assets/introduction.xcf +++ b/src/assets/introduction.xcf diff --git a/src/assets/loss.png b/src/assets/loss.png Binary files differindex ef786fa..616cfab 100644 --- a/src/assets/loss.png +++ b/src/assets/loss.png diff --git a/src/assets/loss.xcf b/src/assets/loss.xcf Binary files differindex 41578ea..1d36ed4 100644 --- a/src/assets/loss.xcf +++ b/src/assets/loss.xcf diff --git a/src/assets/stallman.png b/src/assets/stallman.png Binary files differindex 03dae08..0327a5f 100644 --- a/src/assets/stallman.png +++ b/src/assets/stallman.png diff --git a/src/assets/stallman.xcf b/src/assets/stallman.xcf Binary files differindex bb2da2f..38861af 100644 --- a/src/assets/stallman.xcf +++ b/src/assets/stallman.xcf diff --git a/src/assets/victory.png b/src/assets/victory.png Binary files differindex a02ce9d..2803a8a 100644 --- a/src/assets/victory.png +++ b/src/assets/victory.png diff --git a/src/assets/victory.xcf b/src/assets/victory.xcf Binary files differindex c019796..e5fff45 100644 --- a/src/assets/victory.xcf +++ b/src/assets/victory.xcf diff --git a/src/gates.rs b/src/gates.rs index def618a..99133c3 100644 --- a/src/gates.rs +++ b/src/gates.rs @@ -1,4 +1,4 @@ -extern crate rand; +/xtern crate rand; extern crate std; use super::state; @@ -79,7 +79,7 @@ impl state::StraightBullet for GatesBullet { } fn random_bullet<T: state::Enemy<GatesBullet>>(enemy: &T) -> GatesBullet { - let multiplier = 2. + 2.*(1. - enemy.health()); + let multiplier = 2. + 3.*(1. - enemy.health()); let theta: f64 = rand::random::<f64>()*2.*std::f64::consts::PI/3. + std::f64::consts::PI/6.; let dx = f64::cos(theta) * multiplier; let dy = f64::sin(theta) * multiplier; @@ -108,8 +108,8 @@ impl state::Enemy<GatesBullet> for Gates { Gates { x: 200., y: 40., v_x: 0., v_y: 0., a_x: 0., a_y: 0., target_x: 200., target_y: 40., health: 1. } } fn act(&mut self, count: u64) -> Vec<GatesBullet> { - let max_accel = 0.25; - let max_velocity = 5.; + let max_accel = (1. - self.health) * 0.75 + 0.25; + let max_velocity = (1. - self.health) * 5. + 5.; let dx = self.target_x - self.x; let dy = self.target_y - self.y; /* If we've arrived (close and stopped) */ @@ -149,18 +149,21 @@ impl state::Enemy<GatesBullet> for Gates { self.v_y += self.a_y; self.y += self.v_y; if count % 20 == 0 { - let num_bullets; - if self.health >= 0.8 { - num_bullets = 4; + let num_bullets = if self.health >= 0.8 { + 5 + } else if self.health >= 0.7 { + 6 } else if self.health >= 0.5 { - num_bullets = 5; + 7 + } else if self.health >= 0.4 { + 8 } else if self.health >= 0.3 { - num_bullets = 6; + 9 } else if self.health >= 0.2 { - num_bullets = 7; + 10 } else { - num_bullets = 8; - } + 11 + }; let mut result = Vec::new(); for _ in 0..num_bullets { result.push(random_bullet(&*self)); diff --git a/src/main.rs b/src/main.rs index 43c0c22..eccef92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,14 @@ extern crate sdl2; -extern crate tempfile; +extern crate sdl2_sys; mod state; mod player; mod constants; mod gates; -mod music; use state::Positioned; use state::Drawable; use state::Bullet; -use std::io::Write; enum FResult { Win, @@ -26,6 +24,8 @@ struct Textures<'a> { ebullet: sdl2::render::Texture<'a>, } +const DURATION: u32 = 1_000_000_000u32 / 60; + fn frame<T: state::Enemy<U>, U: state::Bullet>(canvas: &mut sdl2::render::WindowCanvas, state: &mut state::State<T, U>, events: &mut sdl2::event::EventPollIterator, textures: &Textures) -> FResult { let mut new_bullets = Vec::new(); let count = state.count; @@ -83,11 +83,15 @@ fn frame<T: state::Enemy<U>, U: state::Bullet>(canvas: &mut sdl2::render::Window /* Why tf do I not need a lifetime here? */ fn get_surface(bytes: &[u8]) -> sdl2::surface::Surface { - /* Wow what a risky function */ - let mut f = tempfile::NamedTempFile::new().unwrap(); - f.write(bytes).unwrap(); - f.flush().unwrap(); - sdl2::image::LoadSurface::from_file(f.path()).unwrap() + (unsafe { + let rw = sdl2_sys::SDL_RWFromMem(bytes.as_ptr() as *mut std::os::raw::c_void, bytes.len() as i32); + let raw = sdl2_sys::image::IMG_Load_RW(rw, 1); + if (raw as *mut ()).is_null() { + Err("Returned null") + } else { + Ok(sdl2::surface::Surface::from_ll(raw)) + } + }).unwrap() } fn get_player_surface() -> sdl2::surface::Surface<'static> { @@ -106,46 +110,51 @@ 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<(), ()> { +fn generic_message(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump, image: &[u8], okay: sdl2::keyboard::Keycode, error: sdl2::keyboard::Keycode) -> 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(()); + let frame_duration = std::time::Duration::new(0, DURATION); + loop { + let start = std::time::Instant::now(); + canvas.copy(&texture, None, None).unwrap(); + canvas.present(); + for event in event_pump.poll_iter() { + match event { + sdl2::event::Event::KeyDown { keycode: Some(keycode), .. } => { + if keycode == okay { + return Ok(()); + } + if keycode == error { + return Err(()); + } + } + sdl2::event::Event::Quit {..} => { + return Err(()); + } + _ => { } } - _ => { } + } + match frame_duration.checked_sub(start.elapsed()) { + Some(t) => std::thread::sleep(t), + None => (), } } - 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")); + return generic_message(canvas, event_pump, include_bytes!("assets/introduction.png"), sdl2::keyboard::Keycode::Return, sdl2::keyboard::Keycode::Escape); } fn loss(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump) -> Result<(), ()> { - return generic_message(canvas, event_pump, include_bytes!("assets/loss.png")); + return generic_message(canvas, event_pump, include_bytes!("assets/loss.png"), sdl2::keyboard::Keycode::R, sdl2::keyboard::Keycode::Escape); } fn victory(canvas: &mut sdl2::render::WindowCanvas, event_pump: &mut sdl2::EventPump) -> Result<(), ()> { - return generic_message(canvas, event_pump, include_bytes!("assets/victory.png")); + return generic_message(canvas, event_pump, include_bytes!("assets/victory.png"), sdl2::keyboard::Keycode::R, sdl2::keyboard::Keycode::Escape); } 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(); @@ -160,42 +169,56 @@ fn main() { } } - let frame_duration = std::time::Duration::new(0, 1_000_000_000u32 / 60); - let mut state: state::State<gates::Gates, gates::GatesBullet> = state::State::new(); - let player_surface = get_player_surface(); - let enemy_surface = get_enemy_surface(); - let ebullet_surface = get_ebullet_surface(); - let pbullet_surface = get_pbullet_surface(); - let texture_creator = canvas.texture_creator(); - let player_texture = texture_creator.create_texture_from_surface(player_surface).unwrap(); - let enemy_texture = texture_creator.create_texture_from_surface(enemy_surface).unwrap(); - let ebullet_texture = texture_creator.create_texture_from_surface(ebullet_surface).unwrap(); - let pbullet_texture = texture_creator.create_texture_from_surface(pbullet_surface).unwrap(); - let surfaces = Textures { player: player_texture, enemy: enemy_texture, pbullet: pbullet_texture, ebullet: ebullet_texture }; - 'running: loop { - let start = std::time::Instant::now(); - 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; + 'retry: loop { + let mut state: state::State<gates::Gates, gates::GatesBullet> = state::State::new(); + let player_surface = get_player_surface(); + let enemy_surface = get_enemy_surface(); + let ebullet_surface = get_ebullet_surface(); + let pbullet_surface = get_pbullet_surface(); + let texture_creator = canvas.texture_creator(); + let player_texture = texture_creator.create_texture_from_surface(player_surface).unwrap(); + let enemy_texture = texture_creator.create_texture_from_surface(enemy_surface).unwrap(); + let ebullet_texture = texture_creator.create_texture_from_surface(ebullet_surface).unwrap(); + let pbullet_texture = texture_creator.create_texture_from_surface(pbullet_surface).unwrap(); + let surfaces = Textures { player: player_texture, enemy: enemy_texture, pbullet: pbullet_texture, ebullet: ebullet_texture }; + let frame_duration = std::time::Duration::new(0, DURATION); + 'running: loop { + let start = std::time::Instant::now(); + 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 => { + match loss(&mut canvas, &mut event_pump) { + Ok(_) => { + break; + } + Err(_) => { + break 'retry; + } + } + } + FResult::Win => { + match victory(&mut canvas, &mut event_pump) { + Ok(_) => { + break; + } + Err(_) => { + break 'retry; + } + } + } + FResult::Exit => { + break 'retry; + } + FResult::Nothing => { + canvas.present(); + } } - FResult::Nothing => { - canvas.present(); + /* Make sure this iteration took a whole frame */ + match frame_duration.checked_sub(start.elapsed()) { + Some(t) => std::thread::sleep(t), + None => (), } } - /* Make sure this iteration took a whole frame */ - match frame_duration.checked_sub(start.elapsed()) { - Some(t) => std::thread::sleep(t), - None => (), - } } } diff --git a/src/music.rs b/src/music.rs deleted file mode 100644 index 0009479..0000000 --- a/src/music.rs +++ /dev/null @@ -1,32 +0,0 @@ -extern crate std; - -pub struct Player { - player: Option<std::process::Child>, -} - -impl Player { - pub fn play(&mut self) -> Result<(), &'static str> { - match std::process::Command::new("mpv").arg("https://www.youtube.com/watch?v=3bNITQR4Uso").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 471b2e4..7fdb7b6 100644 --- a/src/player.rs +++ b/src/player.rs @@ -113,12 +113,12 @@ impl state::Positioned for Player { self.y } fn radius() -> u32 { - 13 + 3 } } impl state::Drawable for Player { fn center() -> (u32, u32) { - (30, 19) + (33, 21) } } |
