diff --git a/src/animations.rs b/src/animations.rs new file mode 100644 index 0000000..8ad9090 --- /dev/null +++ b/src/animations.rs @@ -0,0 +1,22 @@ +use std::collections::HashMap; + +type BlockOffsets = HashMap; +type AnimationFn = Box BlockOffsets>; + +#[derive(Default)] +pub struct AnimationState { + pub is_animating: bool, + pub last_move_success: bool, + pub progress: f32, + pub block_offsets: BlockOffsets, + + progress_function: Option, +} + +impl AnimationState { + pub fn begin_transition(&mut self, f: AnimationFn) { + self.is_animating = true; + self.progress = 0.0; + self.progress_function = Some(f); + } +} diff --git a/src/game.rs b/src/game.rs index 4548c1f..c161959 100644 --- a/src/game.rs +++ b/src/game.rs @@ -4,6 +4,7 @@ use std::time::Duration; use glium::glutin::{ElementState, Event, VirtualKeyCode, WindowEvent}; use glium::{Display, Frame}; +use crate::animations::AnimationState; use crate::enums::PushDir; use crate::level::Level; use crate::renderer::Renderer; @@ -18,12 +19,15 @@ const SEGMENT_IMAGE: &[u8] = include_bytes!("../textures/segment.png"); const LEVEL_TUTORIAL: &str = include_str!("../levels/tutorial.json"); +const ANIMATION_SPEED: f32 = 6.0; + pub struct Game<'a> { pub resources: Resources, pub display: &'a Display, levels: Vec, current_level: usize, keymap: HashMap, + animations: AnimationState, } impl<'a> Game<'a> { @@ -46,6 +50,7 @@ impl<'a> Game<'a> { levels, current_level: 0, keymap: HashMap::new(), + animations: AnimationState::default(), } } @@ -93,21 +98,37 @@ impl<'a> Game<'a> { ($key:expr, $player:expr, $movement:expr) => { if self.is_pressed(&$key) { let level = self.get_current_level_mut(); - level.handle_movement($player, $movement); + let result = level.handle_movement($player, $movement); self.keymap.insert($key, false); } }; } - shit!(VirtualKeyCode::W, true, PushDir::Up); - shit!(VirtualKeyCode::A, true, PushDir::Left); - shit!(VirtualKeyCode::S, true, PushDir::Down); - shit!(VirtualKeyCode::D, true, PushDir::Right); + if self.animations.is_animating { + let delta_ms = delta.as_millis(); + if self.animations.last_move_success { + } else { + } + } else { + shit!(VirtualKeyCode::W, true, PushDir::Up); + shit!(VirtualKeyCode::A, true, PushDir::Left); + shit!(VirtualKeyCode::S, true, PushDir::Down); + shit!(VirtualKeyCode::D, true, PushDir::Right); - shit!(VirtualKeyCode::I, false, PushDir::Up); - shit!(VirtualKeyCode::J, false, PushDir::Left); - shit!(VirtualKeyCode::K, false, PushDir::Down); - shit!(VirtualKeyCode::L, false, PushDir::Right); + shit!(VirtualKeyCode::I, false, PushDir::Up); + shit!(VirtualKeyCode::J, false, PushDir::Left); + shit!(VirtualKeyCode::K, false, PushDir::Down); + shit!(VirtualKeyCode::L, false, PushDir::Right); + + // failed a move + if !self.animations.last_move_success { + self.animations + .begin_transition(Box::new(|mut offsets, prog| { + offsets.insert(0, (0, 0)); + offsets + })); + } + } } pub fn render(&self, renderer: &mut Renderer) { diff --git a/src/level/block.rs b/src/level/block.rs index 0af1968..eaed205 100644 --- a/src/level/block.rs +++ b/src/level/block.rs @@ -13,6 +13,7 @@ pub trait Blockish { #[derive(Clone)] pub struct Block { + index: usize, movable: bool, position: (i32, i32), color: Color, @@ -39,6 +40,7 @@ impl Block { let orientation = data.orientation.into(); let color = Color::from_rgb_u32(data.color.0, data.color.1, data.color.2); Block { + index, movable, position, color, diff --git a/src/level/mod.rs b/src/level/mod.rs index 530804f..65e9591 100644 --- a/src/level/mod.rs +++ b/src/level/mod.rs @@ -114,6 +114,34 @@ impl Level { pub fn try_move(&self) {} + fn block_can_move(&self, block: impl Blockish) { + for segment in block.get_segments() {} + } + + fn segment_can_move(&self, block: Block, segment: Segment, direction: PushDir) -> Option<()> { + let triple = (segment.position.0, segment.position.1, segment.board); + let target = triple + direction; + + // is the target in the map? + if target.0 < 0 + || target.0 >= self.dimensions.0 as i32 + || target.1 < 0 + || target.1 >= self.dimensions.1 as i32 + { + return None; + } + + // check if we're sharing a triangle cell + if let CellContents::Double((ind1, block1), (ind2, block2)) = self.cell_map.get(triple) { + // figure out which one is the other block + + // check that we're pushing in the direction of the other block + + } + + Some(()) + } + // TODO: don't use a boolean here pub fn can_move(&self, player1: bool, direction: PushDir) -> Option<()> { // an absolute segment (as opposed to relative to a block) diff --git a/src/main.rs b/src/main.rs index ff62b29..5d3dcaf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ extern crate nalgebra_glm as glm; #[macro_use] extern crate serde_derive; +mod animations; mod color; mod data; mod enums;