diff --git a/Cargo.toml b/Cargo.toml index eed71c3..daf600f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ piston2d-sprite = "0.36.0" piston2d-graphics = "0.21.1" find_folder = "0.3.0" uuid = "0.1.17" +rand = "0.3" diff --git a/assets/soot.png b/assets/soot.png index 190cc8b..3179176 100644 Binary files a/assets/soot.png and b/assets/soot.png differ diff --git a/assets/soot.xcf b/assets/soot.xcf index 8bff674..ff3ad76 100644 Binary files a/assets/soot.xcf and b/assets/soot.xcf differ diff --git a/assets/star.png b/assets/star.png new file mode 100644 index 0000000..b25c3a6 Binary files /dev/null and b/assets/star.png differ diff --git a/assets/star.svg b/assets/star.svg new file mode 100644 index 0000000..fc0c008 --- /dev/null +++ b/assets/star.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/lib.rs b/src/lib.rs index 85937d7..f241e2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ extern crate find_folder; extern crate gfx_device_gl; extern crate graphics; extern crate piston_window; +extern crate rand; extern crate sprite; extern crate uuid; @@ -12,50 +13,33 @@ use gfx_device_gl::Resources; use graphics::Image; use graphics::rectangle::square; use piston_window::*; -use mobs::Hero; +use mobs::{Hero, Star}; use sprite::*; -// TODO move this into the player object -const MV_FACT: f64 = 2500.0; - pub struct Game { scene: Scene>, player: Hero, - up_d: bool, - down_d: bool, - left_d: bool, - right_d: bool, + star: Star, } impl Game { pub fn new(w: &mut PistonWindow) -> Game { let mut scene = Scene::new(); + let star = Star::new(w, &mut scene); let player = Hero::new(w, &mut scene); Game { scene: scene, player: player, - up_d: false, - down_d: false, - left_d: false, - right_d: false, + star: star, } } - pub fn on_update(&mut self, e: &Input, upd: UpdateArgs) { + pub fn on_update(&mut self, e: &Input, upd: UpdateArgs, w: &PistonWindow) { self.scene.event(e); - if self.up_d { - self.player.mov(&mut self.scene, 0.0, -MV_FACT * upd.dt); - } - if self.down_d { - self.player.mov(&mut self.scene, 0.0, MV_FACT * upd.dt); - } - if self.left_d { - self.player.mov(&mut self.scene, -MV_FACT * upd.dt, 0.0); - } - if self.right_d { - self.player.mov(&mut self.scene, MV_FACT * upd.dt, 0.0); - } + self.star.mov(w, &mut self.scene, upd.dt); + + self.player.mov(w, &mut self.scene, upd.dt); } pub fn on_draw(&mut self, e: &Input, _: RenderArgs, w: &mut PistonWindow) { @@ -72,23 +56,26 @@ impl Game { Flip::None, &TextureSettings::new()).unwrap(); w.draw_2d(e, |c, g| { - let transform = c.transform.trans(10.0, 100.0); - clear([1.0, 1.0, 1.0, 1.0], g); for number in 0..100 { let x: f64 = (number % 10 * 64).into(); let y: f64 = (number / 10 * 64).into(); image.draw(&bg, &Default::default(), c.transform.trans(x, y).zoom(0.1), g); } - if let Some(player_sprite) = self.scene.child(self.player.sprite_id) { - let (x, y) = player_sprite.get_position(); - text::Text::new_color([0.0, 1.0, 0.0, 1.0], 32).draw( - &format!("x: {}, y: {}", x.trunc(), y.trunc()), - &mut glyphs, - &c.draw_state, - transform, g - ); - } + + text::Text::new_color([0.0, 1.0, 0.0, 1.0], 10).draw( + &format!("{} x: {}, y: {}", self.player.sprite_id, self.player.x.trunc(), self.player.y.trunc()), + &mut glyphs, + &c.draw_state, + c.transform.trans(10.0, 100.0), g + ); + + text::Text::new_color([0.0, 1.0, 0.0, 1.0], 10).draw( + &format!("{} x: {}, y: {}", self.star.sprite_id, self.star.x.trunc(), self.star.y.trunc()), + &mut glyphs, + &c.draw_state, + c.transform.trans(10.0, 110.0), g + ); self.scene.draw(c.transform, g); }); @@ -100,16 +87,16 @@ impl Game { Input::Press(but) => { match but { Button::Keyboard(Key::Up) => { - self.up_d = true; + self.player.dir = (self.player.dir.0, -1.0); } Button::Keyboard(Key::Down) => { - self.down_d = true; + self.player.dir = (self.player.dir.0, 1.0); } Button::Keyboard(Key::Left) => { - self.left_d = true; + self.player.dir = (-1.0, self.player.dir.1); } Button::Keyboard(Key::Right) => { - self.right_d = true; + self.player.dir = (1.0, self.player.dir.1); } _ => {} } @@ -117,16 +104,16 @@ impl Game { Input::Release(but) => { match but { Button::Keyboard(Key::Up) => { - self.up_d = false; + self.player.dir = (self.player.dir.0, 0.0); } Button::Keyboard(Key::Down) => { - self.down_d = false; + self.player.dir = (self.player.dir.0, 0.0); } Button::Keyboard(Key::Left) => { - self.left_d = false; + self.player.dir = (0.0, self.player.dir.1); } Button::Keyboard(Key::Right) => { - self.right_d = false; + self.player.dir = (0.0, self.player.dir.1); } _ => {} } diff --git a/src/main.rs b/src/main.rs index e5e5f86..593293f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,12 +6,13 @@ use piston_window::*; fn main() { let mut window: PistonWindow = WindowSettings::new("Ghostly Adventure", [640, 480]) .exit_on_esc(true) + .resizable(false) .build() .unwrap(); let mut game = ghostly::Game::new(&mut window); while let Some(e) = window.next() { match e { - Input::Update(upd) => game.on_update(&e, upd), + Input::Update(upd) => game.on_update(&e, upd, &window), Input::Render(ren) => game.on_draw(&e, ren, &mut window), _ => game.on_input(e), } diff --git a/src/mobs.rs b/src/mobs/hero.rs similarity index 66% rename from src/mobs.rs rename to src/mobs/hero.rs index cb6dbc6..77ffc41 100644 --- a/src/mobs.rs +++ b/src/mobs/hero.rs @@ -5,13 +5,15 @@ use piston_window::*; use sprite::*; use uuid::Uuid; use std::rc::Rc; +use mobs::wrap; - -// TODO add size of player sprite for boundary checking pub struct Hero { pub sprite_id: Uuid, + pub dir: (f64, f64), pub x: f64, pub y: f64, + w: f64, + h: f64, } impl Hero { @@ -26,43 +28,34 @@ impl Hero { .unwrap()); let mut sprite = Sprite::from_texture(tex); sprite.set_position(320.0, 240.0); + let bounds = sprite.bounding_box(); let sprite_id = scene.add_child(sprite); Hero { x: 320.0, y: 240.0, + w: bounds[2], + h: bounds[3], + dir: (0.0, 0.0), sprite_id: sprite_id, } } - pub fn mov(&mut self, scene: &mut Scene>, input_x: f64, input_y: f64) { + pub fn mov(&mut self, w: &PistonWindow, scene: &mut Scene>, dt: f64) { if let Some(sprite) = scene.child(self.sprite_id) { let (sprite_x, sprite_y) = sprite.get_position(); self.x = sprite_x; self.y = sprite_y; } - let mut wrapped = false; - // TODO pass in window size - if self.x > 640.0 + 32.0 { - self.x = -32.0; - wrapped = true; - } else if self.x < -32.0 { - self.x = 640.0 + 32.0; - wrapped = true; - } - if self.y > 480.0 + 32.0 { - self.y = -32.0; - wrapped = true; - } else if self.y < -32.0 { - self.y = 480.0 + 32.0; - wrapped = true; - } - self.y += input_y; + let (wrapped, new_x, new_y) = wrap((w.size().width.into(), w.size().height.into()), (self.w, self.h), (self.x, self.y)); if wrapped { - scene.stop_all(self.sprite_id); + self.x = new_x; + self.y = new_y; if let Some(ref mut sprite) = scene.child_mut(self.sprite_id) { sprite.set_position(self.x, self.y); } } - scene.run(self.sprite_id, &Action(Ease(EaseFunction::CubicOut, Box::new(MoveBy(1.0, input_x, input_y))))); + let mov_x = self.dir.0 * 2.0; + let mov_y = self.dir.1 * 2.0; + scene.run(self.sprite_id, &Action(Ease(EaseFunction::CubicOut, Box::new(MoveBy(dt * 0.75, mov_x, mov_y))))); } } diff --git a/src/mobs/mod.rs b/src/mobs/mod.rs new file mode 100644 index 0000000..560f75c --- /dev/null +++ b/src/mobs/mod.rs @@ -0,0 +1,22 @@ +pub use self::hero::Hero; +pub use self::star::Star; + +mod hero; +mod star; + +// TODO use window::size +pub fn wrap(win: (f64, f64), bounds: (f64, f64), pos: (f64, f64)) -> (bool, f64, f64) { + let new_x = wrap_dim(win.0, bounds.0, pos.0); + let new_y = wrap_dim(win.1, bounds.1, pos.1); + (new_x != pos.0 || new_y != pos.1, new_x, new_y) +} + +fn wrap_dim(win_dim: f64, sprite_dim: f64, pos_dim: f64) -> f64 { + if pos_dim > win_dim + sprite_dim / 2.0 { + -sprite_dim / 2.0 + } else if pos_dim < -sprite_dim / 2.0 { + win_dim + sprite_dim / 2.0 + } else { + pos_dim + } +} diff --git a/src/mobs/star.rs b/src/mobs/star.rs new file mode 100644 index 0000000..ed65061 --- /dev/null +++ b/src/mobs/star.rs @@ -0,0 +1,62 @@ +use ai_behavior::Action; +use find_folder; +use gfx_device_gl::Resources; +use piston_window::*; +use sprite::*; +use uuid::Uuid; +use rand; +use std::rc::Rc; +use super::wrap; + + +pub struct Star { + pub sprite_id: Uuid, + pub x: f64, + pub y: f64, + w: f64, + h: f64, +} + +impl Star { + pub fn new(w: &mut PistonWindow, scene: &mut Scene>) -> Star { + let assets = find_folder::Search::ParentsThenKids(3, 3) + .for_folder("assets") + .unwrap(); + let tex = Rc::new(Texture::from_path(&mut w.factory, + assets.join("star.png"), + Flip::None, + &TextureSettings::new()) + .unwrap()); + let mut sprite = Sprite::from_texture(tex); + sprite.set_scale(0.5, 0.5); + sprite.set_position(30.0, 32.0); + let bounds = sprite.bounding_box(); + let sprite_id = scene.add_child(sprite); + Star { + x: 32.0, + y: 32.0, + w: bounds[2], + h: bounds[3], + sprite_id: sprite_id, + } + } + + pub fn mov(&mut self, w: &PistonWindow, scene: &mut Scene>, dt: f64) { + if let Some(sprite) = scene.child(self.sprite_id) { + let (sprite_x, sprite_y) = sprite.get_position(); + self.x = sprite_x; + self.y = sprite_y; + } + let (wrapped, new_x, new_y) = wrap((w.size().width.into(), w.size().height.into()), (self.w, self.h), (self.x, self.y)); + if wrapped { + if let Some(ref mut sprite) = scene.child_mut(self.sprite_id) { + self.x = new_x; + self.y = new_y; + sprite.set_position(self.x, self.y); + } + } + let mov_x = rand::random::() * 0.5; + let mov_y = rand::random::() * 0.5; + scene.run(self.sprite_id, &Action(Ease(EaseFunction::CubicOut, Box::new(MoveBy(dt * 0.75, mov_x, mov_y))))); + } +}