begin work on animations
This commit is contained in:
parent
b0ef20ff8b
commit
34e58f52d1
5 changed files with 83 additions and 9 deletions
22
src/animations.rs
Normal file
22
src/animations.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
39
src/game.rs
39
src/game.rs
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue