fix some clippy issues
This commit is contained in:
parent
0fdab97044
commit
eb3c12fc58
9 changed files with 63 additions and 196 deletions
|
@ -34,6 +34,7 @@ impl AnimationState {
|
|||
}
|
||||
|
||||
pub fn begin_move_transition(&mut self, result: MoveResult) {
|
||||
println!("result: {:?}", result);
|
||||
self.last_move_result = Some(result);
|
||||
self.is_animating = true;
|
||||
self.progress = 0.0;
|
||||
|
@ -45,12 +46,10 @@ impl AnimationState {
|
|||
for (entity, direction) in change_set {
|
||||
// TODO: implement ease-out?
|
||||
let pair = direction.as_pair();
|
||||
// cap progress at 1.0, we don't want blocks going past where they're supposed to
|
||||
let progress = progress.min(1.0);
|
||||
let offset = (pair.0 as f32 * progress, pair.1 as f32 * progress);
|
||||
println!(
|
||||
"|| entity: {:?}, direction: {:?} => {:?}",
|
||||
entity, direction, offset
|
||||
);
|
||||
offsets.insert(entity.clone(), offset);
|
||||
offsets.insert(entity, offset);
|
||||
}
|
||||
}
|
||||
// vibrate all blocking pieces
|
||||
|
@ -66,12 +65,6 @@ impl AnimationState {
|
|||
self.progress_function = Some(Box::new(func));
|
||||
}
|
||||
|
||||
pub fn begin_transition(&mut self, f: AnimationFn) {
|
||||
self.is_animating = true;
|
||||
self.progress = 0.0;
|
||||
self.progress_function = Some(f);
|
||||
}
|
||||
|
||||
pub fn make_progress(&mut self, delta: Duration) {
|
||||
let progress = self.progress + (delta.as_millis() as f32 / ANIMATION_DURATION) / 1000.0;
|
||||
|
||||
|
@ -97,10 +90,6 @@ impl AnimationState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_done(&self) -> bool {
|
||||
self.progress > 1.0
|
||||
}
|
||||
|
||||
pub fn get_block_offset(&self, index: usize) -> (f32, f32) {
|
||||
self.block_offsets
|
||||
.get(&Entity::Block(index))
|
||||
|
|
27
src/enums.rs
27
src/enums.rs
|
@ -44,7 +44,7 @@ pub enum PushDir {
|
|||
}
|
||||
|
||||
impl PushDir {
|
||||
pub fn as_pair(&self) -> (i32, i32) {
|
||||
pub fn as_pair(self) -> (i32, i32) {
|
||||
match self {
|
||||
PushDir::Up => (0, -1),
|
||||
PushDir::Down => (0, 1),
|
||||
|
@ -90,25 +90,20 @@ impl From<i32> for Shape {
|
|||
}
|
||||
|
||||
impl Shape {
|
||||
pub fn opposite(&self) -> Shape {
|
||||
pub fn get_opposite(self) -> Option<Shape> {
|
||||
use Shape::*;
|
||||
match self {
|
||||
TopRight => BottomLeft,
|
||||
BottomLeft => TopRight,
|
||||
TopLeft => BottomRight,
|
||||
BottomRight => TopLeft,
|
||||
Full => Full,
|
||||
TopRight => Some(BottomLeft),
|
||||
BottomLeft => Some(TopRight),
|
||||
TopLeft => Some(BottomRight),
|
||||
BottomRight => Some(TopLeft),
|
||||
Full => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_opposite(&self, other: &Shape) -> bool {
|
||||
use Shape::*;
|
||||
match (self, other) {
|
||||
(TopRight, BottomLeft)
|
||||
| (BottomLeft, TopRight)
|
||||
| (TopLeft, BottomRight)
|
||||
| (BottomRight, TopLeft) => true,
|
||||
_ => false,
|
||||
}
|
||||
pub fn is_opposite(self, other: Shape) -> bool {
|
||||
self.get_opposite()
|
||||
.map(|shape| shape == other)
|
||||
.unwrap_or_else(|| false)
|
||||
}
|
||||
}
|
||||
|
|
22
src/game.rs
22
src/game.rs
|
@ -19,8 +19,6 @@ 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,
|
||||
|
@ -55,8 +53,8 @@ impl<'a> Game<'a> {
|
|||
}
|
||||
|
||||
pub fn handle_event(&mut self, event: Event) {
|
||||
if let Event::WindowEvent { event, .. } = event {
|
||||
match event {
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::Resized(size) => self.resources.window_dimensions = size.into(),
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let Some(code) = &input.virtual_keycode {
|
||||
|
@ -68,8 +66,7 @@ impl<'a> Game<'a> {
|
|||
}
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,15 +75,15 @@ impl<'a> Game<'a> {
|
|||
}
|
||||
|
||||
pub fn get_current_level(&self) -> &Level {
|
||||
self.levels.iter().nth(self.current_level).unwrap()
|
||||
self.levels.get(self.current_level).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_current_level_mut(&mut self) -> &mut Level {
|
||||
self.levels.iter_mut().nth(self.current_level).unwrap()
|
||||
self.levels.get_mut(self.current_level).unwrap()
|
||||
}
|
||||
|
||||
pub fn is_pressed(&self, code: &VirtualKeyCode) -> bool {
|
||||
if let Some(true) = self.keymap.get(code) {
|
||||
pub fn is_pressed(&self, code: VirtualKeyCode) -> bool {
|
||||
if let Some(true) = self.keymap.get(&code) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -96,7 +93,7 @@ impl<'a> Game<'a> {
|
|||
pub fn update(&mut self, delta: Duration) {
|
||||
macro_rules! shit {
|
||||
($key:expr, $board:expr, $direction:expr) => {
|
||||
if self.is_pressed(&$key) {
|
||||
if self.is_pressed($key) {
|
||||
println!("pushed: {:?}", $key);
|
||||
let level = self.get_current_level_mut();
|
||||
let result = level.try_move($board, $direction);
|
||||
|
@ -107,7 +104,7 @@ impl<'a> Game<'a> {
|
|||
}
|
||||
|
||||
if self.animations.is_animating {
|
||||
println!("animating. {:?}", self.animations.progress);
|
||||
// println!("animating. {:?}", self.animations.progress);
|
||||
self.animations.make_progress(delta);
|
||||
|
||||
// we just finished!
|
||||
|
@ -134,9 +131,6 @@ impl<'a> Game<'a> {
|
|||
shit!(VirtualKeyCode::J, Board::Right, PushDir::Left);
|
||||
shit!(VirtualKeyCode::K, Board::Right, PushDir::Down);
|
||||
shit!(VirtualKeyCode::L, Board::Right, PushDir::Right);
|
||||
|
||||
// failed a move
|
||||
if let Some(Err(fail_set)) = &self.animations.last_move_result {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,13 +26,10 @@ impl Block {
|
|||
let segments = data
|
||||
.segments
|
||||
.iter()
|
||||
.map(|segment| {
|
||||
let seg = Segment {
|
||||
.map(|segment| Segment {
|
||||
position: (segment[0], segment[1]),
|
||||
shape: segment[2].into(),
|
||||
board: segment[3].into(),
|
||||
};
|
||||
seg
|
||||
})
|
||||
.collect();
|
||||
let orientation = data.orientation.into();
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::enums::Board;
|
||||
use crate::level::Segment;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CellMap(HashMap<(i32, i32, Board), CellContents>);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum CellContents {
|
||||
Empty,
|
||||
Player,
|
||||
Single((usize, Segment)),
|
||||
|
||||
// invariant: .0 < .1
|
||||
Double((usize, Segment), (usize, Segment)),
|
||||
}
|
||||
|
||||
impl CellMap {
|
||||
pub fn new() -> Self {
|
||||
CellMap(HashMap::new())
|
||||
}
|
||||
|
||||
pub fn get(&self, loc: (i32, i32, Board)) -> CellContents {
|
||||
self.0
|
||||
.get(&loc)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| CellContents::Empty)
|
||||
}
|
||||
|
||||
pub fn clear(&mut self, loc: (i32, i32, Board)) {
|
||||
self.0.remove(&loc);
|
||||
}
|
||||
|
||||
pub fn add_player(&mut self, loc: (i32, i32, Board)) -> bool {
|
||||
let contents = self.get(loc).clone();
|
||||
match contents {
|
||||
CellContents::Empty => {
|
||||
self.0.insert(loc, CellContents::Player);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, loc: (i32, i32, Board), index: usize, segment: &Segment) -> bool {
|
||||
let contents = self.get(loc).clone();
|
||||
match contents {
|
||||
CellContents::Empty => {
|
||||
// just add it like normal
|
||||
self.0.insert(loc, CellContents::Single((index, *segment)));
|
||||
true
|
||||
}
|
||||
CellContents::Single((index0, existing)) => {
|
||||
if existing.shape.is_opposite(&segment.shape) {
|
||||
self.0.insert(
|
||||
loc,
|
||||
if *segment < existing {
|
||||
CellContents::Double((index, *segment), (index0, existing))
|
||||
} else {
|
||||
CellContents::Double((index0, existing), (index, *segment))
|
||||
},
|
||||
);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
CellContents::Player | CellContents::Double(_, _) => false,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,16 +8,6 @@ macro_rules! set {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! merge {
|
||||
($(item:expr)*) => {
|
||||
{
|
||||
let mut set = std::collections::HashSet::new();
|
||||
$(set.extend($item);)*
|
||||
set
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! fail_set {
|
||||
($change_set:expr) => {
|
||||
$change_set
|
||||
|
@ -34,7 +24,7 @@ macro_rules! entity_fail {
|
|||
($item:expr) => {
|
||||
match $item {
|
||||
Some(index) => set!(index),
|
||||
None => set!(),
|
||||
None => std::collections::HashSet::new(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,25 +2,21 @@
|
|||
mod macros;
|
||||
|
||||
mod block;
|
||||
mod cell_map;
|
||||
mod player;
|
||||
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
use crate::animations::AnimationState;
|
||||
use crate::color::Color;
|
||||
use crate::data::LevelData;
|
||||
use crate::enums::{Board, Orientation, PushDir, Shape};
|
||||
use crate::renderer::Renderer;
|
||||
|
||||
use self::block::{Block, Blockish};
|
||||
use self::cell_map::{CellContents, CellMap};
|
||||
use self::player::Player;
|
||||
|
||||
pub struct Level {
|
||||
dimensions: (u32, u32),
|
||||
move_stack: VecDeque<()>,
|
||||
cell_map: CellMap,
|
||||
blocks: Vec<Block>,
|
||||
player1: Player,
|
||||
player2: Player,
|
||||
|
@ -46,25 +42,13 @@ pub type FailSet = HashSet<usize>;
|
|||
impl Level {
|
||||
pub fn from_json(data: impl AsRef<str>) -> Level {
|
||||
let data: LevelData = json5::from_str(data.as_ref()).unwrap();
|
||||
println!("{:?}", data);
|
||||
|
||||
let mut cell_map = CellMap::new();
|
||||
println!("level data: {:?}", data);
|
||||
|
||||
let blocks = data
|
||||
.blocks
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, block)| {
|
||||
let block = Block::from_data(i, block);
|
||||
for segment in block.get_segments() {
|
||||
cell_map.add(
|
||||
(segment.position.0, segment.position.1, segment.board),
|
||||
i,
|
||||
&segment,
|
||||
);
|
||||
}
|
||||
block
|
||||
})
|
||||
.map(|(i, block)| Block::from_data(i, block))
|
||||
.collect();
|
||||
|
||||
let player1 = Player {
|
||||
|
@ -75,21 +59,10 @@ impl Level {
|
|||
position: data.player2.position,
|
||||
color: data.player2.color.into(),
|
||||
};
|
||||
cell_map.add_player((
|
||||
data.player1.position.0,
|
||||
data.player1.position.1,
|
||||
Board::Left,
|
||||
));
|
||||
cell_map.add_player((
|
||||
data.player2.position.0,
|
||||
data.player2.position.1,
|
||||
Board::Right,
|
||||
));
|
||||
|
||||
Level {
|
||||
dimensions: (data.dimensions[0], data.dimensions[1]),
|
||||
move_stack: VecDeque::new(),
|
||||
cell_map,
|
||||
blocks,
|
||||
player1,
|
||||
player2,
|
||||
|
@ -152,7 +125,7 @@ impl Level {
|
|||
println!("block_can_move({:?}, {:?})", index, direction);
|
||||
let block = match self.blocks.get(index) {
|
||||
Some(block) => block,
|
||||
None => return Err(set!()),
|
||||
None => return Err(HashSet::new()),
|
||||
};
|
||||
|
||||
// is the block even movable?
|
||||
|
@ -247,8 +220,7 @@ impl Level {
|
|||
);
|
||||
|
||||
// handle special pushes
|
||||
// if-statement disguised as a loop
|
||||
while let Some((other_block, other_shape)) = current_occupant {
|
||||
if let Some((other_block, other_shape)) = current_occupant {
|
||||
// are both shapes triangles?
|
||||
let both_triangles = match (segment.shape, other_shape) {
|
||||
(Shape::Full, Shape::Full) => false,
|
||||
|
@ -256,6 +228,7 @@ impl Level {
|
|||
// TODO: enumerate them to get rid of invalid states
|
||||
};
|
||||
|
||||
if both_triangles {
|
||||
// what directions could we be pushing the other block into?
|
||||
let possible_directions = match segment.shape {
|
||||
Shape::TopRight => [PushDir::Up, PushDir::Right],
|
||||
|
@ -266,10 +239,7 @@ impl Level {
|
|||
};
|
||||
|
||||
// does the direction we're pushing appear in this list?
|
||||
if !possible_directions.contains(&direction) {
|
||||
break;
|
||||
}
|
||||
|
||||
if possible_directions.contains(&direction) {
|
||||
// the other shape goes in the other direction
|
||||
let other_direction = {
|
||||
let mut set = possible_directions.iter().collect::<HashSet<_>>();
|
||||
|
@ -279,6 +249,8 @@ impl Level {
|
|||
|
||||
return self.block_can_move(other_block, other_direction, change_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle normal pushes
|
||||
if let Some((entity, shape)) = target_occupant {
|
||||
|
@ -288,18 +260,20 @@ impl Level {
|
|||
Err(fail_set!(change_set))
|
||||
}
|
||||
Entity::Block(index) => {
|
||||
if
|
||||
// if it's part of the same block it's ok to push
|
||||
if block_index.is_some() && block_index.unwrap() == index {
|
||||
Ok(change_set)
|
||||
}
|
||||
block_index.is_some() && block_index.unwrap() == index ||
|
||||
// if the shapes are opposite, we can actually both fit into the same spot
|
||||
else if segment.shape.is_opposite(&shape) {
|
||||
segment.shape.is_opposite(shape)
|
||||
{
|
||||
Ok(change_set)
|
||||
}
|
||||
// if the block is already in the change set, it can't move
|
||||
else if change_set.contains_key(&Entity::Block(index)) {
|
||||
Err(fail_set!(change_set))
|
||||
} else {
|
||||
}
|
||||
// if the next block can move then so can this one
|
||||
else {
|
||||
self.block_can_move(index, direction, change_set)
|
||||
}
|
||||
}
|
||||
|
@ -414,7 +388,7 @@ impl Level {
|
|||
location.1 += (animation_offset.1 * scale as f32) as i32;
|
||||
renderer.render_segment(
|
||||
location,
|
||||
(scale - 8),
|
||||
scale - 8,
|
||||
player.color,
|
||||
Orientation::Both,
|
||||
Shape::Full,
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::time::Instant;
|
|||
|
||||
use glium::glutin::dpi::PhysicalSize;
|
||||
use glium::glutin::{ContextBuilder, Event, EventsLoop, WindowBuilder, WindowEvent};
|
||||
use glium::{Display, Rect, Surface};
|
||||
use glium::{Display, Surface};
|
||||
|
||||
use crate::game::Game;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||
|
||||
use glium::texture::RawImage2d;
|
||||
use glium::{Display, Program, ProgramCreationError, Texture2d};
|
||||
use image::{DynamicImage, GenericImageView, ImageBuffer, ImageError, Rgba};
|
||||
use image::{DynamicImage, GenericImageView, ImageError};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Resources {
|
||||
|
|
Loading…
Reference in a new issue