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);
|
||||
}
|
||||
}
|
23
src/game.rs
23
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<Level>,
|
||||
current_level: usize,
|
||||
keymap: HashMap<VirtualKeyCode, bool>,
|
||||
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,12 +98,18 @@ 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -108,6 +119,16 @@ impl<'a> Game<'a> {
|
|||
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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -4,6 +4,7 @@ extern crate nalgebra_glm as glm;
|
|||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
mod animations;
|
||||
mod color;
|
||||
mod data;
|
||||
mod enums;
|
||||
|
|
Loading…
Reference in a new issue