begin work on animations

This commit is contained in:
Michael Zhang 2019-08-08 22:53:12 -05:00
parent b0ef20ff8b
commit 34e58f52d1
No known key found for this signature in database
GPG key ID: 5BAEFE5D04F0CE6C
5 changed files with 83 additions and 9 deletions

22
src/animations.rs Normal file
View file

@ -0,0 +1,22 @@
use std::collections::HashMap;
type BlockOffsets = HashMap<usize, (u32, u32)>;
type AnimationFn = Box<Fn(BlockOffsets, f32) -> 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<AnimationFn>,
}
impl AnimationState {
pub fn begin_transition(&mut self, f: AnimationFn) {
self.is_animating = true;
self.progress = 0.0;
self.progress_function = Some(f);
}
}

View file

@ -4,6 +4,7 @@ use std::time::Duration;
use glium::glutin::{ElementState, Event, VirtualKeyCode, WindowEvent}; use glium::glutin::{ElementState, Event, VirtualKeyCode, WindowEvent};
use glium::{Display, Frame}; use glium::{Display, Frame};
use crate::animations::AnimationState;
use crate::enums::PushDir; use crate::enums::PushDir;
use crate::level::Level; use crate::level::Level;
use crate::renderer::Renderer; 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 LEVEL_TUTORIAL: &str = include_str!("../levels/tutorial.json");
const ANIMATION_SPEED: f32 = 6.0;
pub struct Game<'a> { pub struct Game<'a> {
pub resources: Resources, pub resources: Resources,
pub display: &'a Display, pub display: &'a Display,
levels: Vec<Level>, levels: Vec<Level>,
current_level: usize, current_level: usize,
keymap: HashMap<VirtualKeyCode, bool>, keymap: HashMap<VirtualKeyCode, bool>,
animations: AnimationState,
} }
impl<'a> Game<'a> { impl<'a> Game<'a> {
@ -46,6 +50,7 @@ impl<'a> Game<'a> {
levels, levels,
current_level: 0, current_level: 0,
keymap: HashMap::new(), keymap: HashMap::new(),
animations: AnimationState::default(),
} }
} }
@ -93,21 +98,37 @@ impl<'a> Game<'a> {
($key:expr, $player:expr, $movement:expr) => { ($key:expr, $player:expr, $movement:expr) => {
if self.is_pressed(&$key) { if self.is_pressed(&$key) {
let level = self.get_current_level_mut(); let level = self.get_current_level_mut();
level.handle_movement($player, $movement); let result = level.handle_movement($player, $movement);
self.keymap.insert($key, false); self.keymap.insert($key, false);
} }
}; };
} }
shit!(VirtualKeyCode::W, true, PushDir::Up); if self.animations.is_animating {
shit!(VirtualKeyCode::A, true, PushDir::Left); let delta_ms = delta.as_millis();
shit!(VirtualKeyCode::S, true, PushDir::Down); if self.animations.last_move_success {
shit!(VirtualKeyCode::D, true, PushDir::Right); } 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::I, false, PushDir::Up);
shit!(VirtualKeyCode::J, false, PushDir::Left); shit!(VirtualKeyCode::J, false, PushDir::Left);
shit!(VirtualKeyCode::K, false, PushDir::Down); shit!(VirtualKeyCode::K, false, PushDir::Down);
shit!(VirtualKeyCode::L, false, PushDir::Right); 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) { pub fn render(&self, renderer: &mut Renderer) {

View file

@ -13,6 +13,7 @@ pub trait Blockish {
#[derive(Clone)] #[derive(Clone)]
pub struct Block { pub struct Block {
index: usize,
movable: bool, movable: bool,
position: (i32, i32), position: (i32, i32),
color: Color, color: Color,
@ -39,6 +40,7 @@ impl Block {
let orientation = data.orientation.into(); let orientation = data.orientation.into();
let color = Color::from_rgb_u32(data.color.0, data.color.1, data.color.2); let color = Color::from_rgb_u32(data.color.0, data.color.1, data.color.2);
Block { Block {
index,
movable, movable,
position, position,
color, color,

View file

@ -114,6 +114,34 @@ impl Level {
pub fn try_move(&self) {} 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 // TODO: don't use a boolean here
pub fn can_move(&self, player1: bool, direction: PushDir) -> Option<()> { pub fn can_move(&self, player1: bool, direction: PushDir) -> Option<()> {
// an absolute segment (as opposed to relative to a block) // an absolute segment (as opposed to relative to a block)

View file

@ -4,6 +4,7 @@ extern crate nalgebra_glm as glm;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
mod animations;
mod color; mod color;
mod data; mod data;
mod enums; mod enums;