add level 1
This commit is contained in:
parent
681c53eb80
commit
85f8c710ac
6 changed files with 169 additions and 21 deletions
19
LICENSE
Normal file
19
LICENSE
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) Michael Zhang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
124
levels/level1.json
Normal file
124
levels/level1.json
Normal file
|
@ -0,0 +1,124 @@
|
|||
{
|
||||
"dimensions": [8, 8],
|
||||
"player1": {
|
||||
"position": [5, 5],
|
||||
"color": [66, 134, 244],
|
||||
},
|
||||
"player2": {
|
||||
"position": [5, 5],
|
||||
"color": [244, 83, 65],
|
||||
},
|
||||
"goal1": [0, 0],
|
||||
"goal2": [0, 0],
|
||||
"blocks": [
|
||||
{
|
||||
"movable": true,
|
||||
"orientation": 2,
|
||||
"color": [255, 10, 100],
|
||||
"segments": [
|
||||
[6, 4, 2, 0],
|
||||
[6, 5, 0, 0],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": true,
|
||||
"orientation": 1,
|
||||
"color": [0, 255, 100],
|
||||
"segments": [
|
||||
[4, 3, 2, 0],
|
||||
[5, 3, 0, 0],
|
||||
[6, 3, 4, 0],
|
||||
[4, 3, 2, 1],
|
||||
[5, 3, 0, 1],
|
||||
[6, 3, 4, 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": true,
|
||||
"orientation": 2,
|
||||
"color": [20, 25, 100],
|
||||
"segments": [
|
||||
[6, 2, 4, 0],
|
||||
[6, 1, 0, 0],
|
||||
[6, 2, 4, 1],
|
||||
[6, 1, 0, 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": true,
|
||||
"orientation": 1,
|
||||
"color": [110, 30, 230],
|
||||
"segments": [
|
||||
[3, 5, 4, 0],
|
||||
[2, 5, 0, 0],
|
||||
[1, 5, 0, 0],
|
||||
[3, 5, 4, 1],
|
||||
[2, 5, 0, 1],
|
||||
[1, 5, 0, 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": true,
|
||||
"orientation": 2,
|
||||
"color": [240, 50, 60],
|
||||
"segments": [
|
||||
[3, 5, 2, 0],
|
||||
[3, 6, 0, 0],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": true,
|
||||
"orientation": 2,
|
||||
"color": [120, 220, 20],
|
||||
"segments": [
|
||||
[3, 3, 4, 1],
|
||||
[3, 2, 0, 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": false,
|
||||
"orientation": 0,
|
||||
"color": [0, 0, 0],
|
||||
"segments": [
|
||||
[2, 0, 0, 0],
|
||||
[2, 1, 0, 0],
|
||||
[2, 2, 0, 0],
|
||||
[2, 3, 0, 0],
|
||||
[2, 0, 0, 1],
|
||||
[2, 1, 0, 1],
|
||||
[2, 2, 0, 1],
|
||||
[2, 3, 0, 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": false,
|
||||
"orientation": 0,
|
||||
"color": [0, 0, 0],
|
||||
"segments": [
|
||||
[4, 4, 0, 0],
|
||||
[4, 5, 0, 0],
|
||||
[4, 6, 0, 0],
|
||||
[4, 7, 0, 0],
|
||||
[4, 4, 0, 1],
|
||||
[4, 5, 0, 1],
|
||||
[4, 6, 0, 1],
|
||||
[4, 7, 0, 1],
|
||||
],
|
||||
},
|
||||
{
|
||||
"movable": false,
|
||||
"orientation": 0,
|
||||
"color": [0, 0, 0],
|
||||
"segments": [
|
||||
[7, 4, 0, 0],
|
||||
[7, 5, 0, 0],
|
||||
[7, 6, 0, 0],
|
||||
[7, 7, 0, 0],
|
||||
[7, 4, 0, 1],
|
||||
[7, 5, 0, 1],
|
||||
[7, 6, 0, 1],
|
||||
[7, 7, 0, 1],
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::enums::Board;
|
||||
|
@ -8,7 +8,7 @@ pub type MoveResult = Result<ChangeSet, FailSet>;
|
|||
pub type BlockOffsets = HashMap<Entity, (f32, f32)>;
|
||||
|
||||
// TODO: don't yeet around a HashMap all the time
|
||||
pub type AnimationFn = Box<Fn(MoveResult, BlockOffsets, f32) -> BlockOffsets>;
|
||||
pub type AnimationFn = Box<dyn Fn(MoveResult, BlockOffsets, f32) -> BlockOffsets>;
|
||||
|
||||
// in seconds
|
||||
const ANIMATION_DURATION: f32 = 1.0 / 6.0;
|
||||
|
@ -19,6 +19,7 @@ pub struct AnimationState {
|
|||
pub last_move_result: Option<MoveResult>,
|
||||
pub progress: f32,
|
||||
pub block_offsets: BlockOffsets,
|
||||
pub immovable_blocks: HashSet<usize>,
|
||||
progress_function: Option<AnimationFn>,
|
||||
}
|
||||
|
||||
|
@ -29,6 +30,7 @@ impl AnimationState {
|
|||
last_move_result: None,
|
||||
progress: 0.0,
|
||||
block_offsets: BlockOffsets::new(),
|
||||
immovable_blocks: HashSet::new(),
|
||||
progress_function: None,
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +40,7 @@ impl AnimationState {
|
|||
self.last_move_result = Some(result);
|
||||
self.is_animating = true;
|
||||
self.progress = 0.0;
|
||||
|
||||
let func = |last_move_result: MoveResult, mut offsets: BlockOffsets, progress: f32| {
|
||||
use std::f32::consts::PI;
|
||||
match last_move_result {
|
||||
|
@ -52,6 +55,7 @@ impl AnimationState {
|
|||
offsets.insert(entity, offset);
|
||||
}
|
||||
}
|
||||
|
||||
// vibrate all blocking pieces
|
||||
Err(fail_set) => {
|
||||
for index in fail_set {
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use glium::glutin::{ElementState, Event, VirtualKeyCode, WindowEvent};
|
||||
use glium::glutin::{ElementState, Event, WindowEvent};
|
||||
use glium::{Display, Frame};
|
||||
|
||||
use crate::animations::AnimationState;
|
||||
use crate::enums::{Board, PushDir};
|
||||
use crate::keymap::Keymap;
|
||||
use crate::level::Level;
|
||||
use crate::renderer::Renderer;
|
||||
use crate::resources::Resources;
|
||||
use crate::screens::{MenuScreen, Screen, ScreenStack};
|
||||
use crate::screens::{MenuScreen, ScreenStack};
|
||||
|
||||
const SEGMENT_VERT: &str = include_str!("../shaders/segment.vert");
|
||||
const SEGMENT_FRAG: &str = include_str!("../shaders/segment.frag");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
mod menu;
|
||||
mod play;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::keymap::Keymap;
|
||||
|
@ -27,7 +26,7 @@ pub struct ScreenStack(Vec<Box<dyn Screen>>);
|
|||
|
||||
impl ScreenStack {
|
||||
pub fn with<S: 'static + Screen>(screen: S) -> Self {
|
||||
let mut stack = Vec::<Box<Screen>>::new();
|
||||
let mut stack = Vec::<Box<dyn Screen>>::new();
|
||||
stack.push(Box::new(screen));
|
||||
ScreenStack(stack)
|
||||
}
|
||||
|
@ -56,7 +55,7 @@ impl ScreenStack {
|
|||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
let mut screen = self.top();
|
||||
let screen = self.top();
|
||||
let screen = screen.as_ref();
|
||||
screen.render(renderer)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use crate::screens::{Screen, ScreenAction};
|
|||
|
||||
const LEVEL_TUTORIAL: &str = include_str!("../../levels/tutorial.json");
|
||||
const LEVEL_TUTORIAL2: &str = include_str!("../../levels/tutorial2.json");
|
||||
const LEVEL_1: &str = include_str!("../../levels/level1.json");
|
||||
|
||||
pub struct PlayScreen {
|
||||
animations: AnimationState,
|
||||
|
@ -20,7 +21,7 @@ pub struct PlayScreen {
|
|||
|
||||
impl Screen for PlayScreen {
|
||||
fn update(&mut self, delta: Duration, keymap: &Keymap) -> ScreenAction {
|
||||
macro_rules! shit {
|
||||
macro_rules! btn_handler {
|
||||
($key:expr, $board:expr, $direction:expr) => {
|
||||
if keymap.is_pressed($key) {
|
||||
println!("pushed: {:?}", $key);
|
||||
|
@ -51,15 +52,15 @@ impl Screen for PlayScreen {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
shit!(VirtualKeyCode::W, Board::Left, PushDir::Up);
|
||||
shit!(VirtualKeyCode::A, Board::Left, PushDir::Left);
|
||||
shit!(VirtualKeyCode::S, Board::Left, PushDir::Down);
|
||||
shit!(VirtualKeyCode::D, Board::Left, PushDir::Right);
|
||||
btn_handler!(VirtualKeyCode::W, Board::Left, PushDir::Up);
|
||||
btn_handler!(VirtualKeyCode::A, Board::Left, PushDir::Left);
|
||||
btn_handler!(VirtualKeyCode::S, Board::Left, PushDir::Down);
|
||||
btn_handler!(VirtualKeyCode::D, Board::Left, PushDir::Right);
|
||||
|
||||
shit!(VirtualKeyCode::I, Board::Right, PushDir::Up);
|
||||
shit!(VirtualKeyCode::J, Board::Right, PushDir::Left);
|
||||
shit!(VirtualKeyCode::K, Board::Right, PushDir::Down);
|
||||
shit!(VirtualKeyCode::L, Board::Right, PushDir::Right);
|
||||
btn_handler!(VirtualKeyCode::I, Board::Right, PushDir::Up);
|
||||
btn_handler!(VirtualKeyCode::J, Board::Right, PushDir::Left);
|
||||
btn_handler!(VirtualKeyCode::K, Board::Right, PushDir::Down);
|
||||
btn_handler!(VirtualKeyCode::L, Board::Right, PushDir::Right);
|
||||
}
|
||||
|
||||
ScreenAction::None
|
||||
|
@ -82,6 +83,7 @@ impl PlayScreen {
|
|||
|
||||
pub fn new() -> PlayScreen {
|
||||
let levels = vec![
|
||||
Level::from_json(&LEVEL_1),
|
||||
Level::from_json(&LEVEL_TUTORIAL),
|
||||
Level::from_json(&LEVEL_TUTORIAL2),
|
||||
];
|
||||
|
@ -93,11 +95,15 @@ impl PlayScreen {
|
|||
}
|
||||
}
|
||||
|
||||
fn go_to_next_level(&mut self) {
|
||||
self.current_level += 1;
|
||||
}
|
||||
|
||||
fn check_win_condition(&mut self) {
|
||||
let level = self.get_current_level();
|
||||
if level.check_win_condition() {
|
||||
// go on to the next level
|
||||
self.current_level += 1;
|
||||
self.go_to_next_level();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue