spawn_delay implemented + new dead code

Not sure will i use this
This commit is contained in:
dan63047 2023-12-06 01:25:00 +03:00
parent 5c1f814cbb
commit bc49013f21
3 changed files with 127 additions and 34 deletions

View File

@ -22,10 +22,10 @@ impl Plugin for UBSGEngine{
add_systems(Update, receive_input.run_if(in_state(GameStates::Gameplay))). add_systems(Update, receive_input.run_if(in_state(GameStates::Gameplay))).
add_systems(Update, das_and_arr.run_if(in_state(GameStates::Gameplay))). add_systems(Update, das_and_arr.run_if(in_state(GameStates::Gameplay))).
add_systems(FixedUpdate, gameloop.run_if(in_state(GameStates::Gameplay)).run_if(in_state(GameloopStates::Falling))). add_systems(FixedUpdate, gameloop.run_if(in_state(GameStates::Gameplay)).run_if(in_state(GameloopStates::Falling))).
add_systems(FixedUpdate, run_spawn_delay.run_if(in_state(GameStates::Gameplay)).run_if(in_state(GameloopStates::Spawn))).
add_systems(OnEnter(GameloopStates::AfterLocking), after_locking_routine). add_systems(OnEnter(GameloopStates::AfterLocking), after_locking_routine).
add_systems(OnEnter(GameloopStates::Spawn), spawn_routine). add_systems(OnEnter(GameloopStates::Falling), draw_next).
add_systems(OnEnter(GameStates::Gameplay), draw_next). add_systems(OnExit(GameloopStates::Spawn), spawn_routine).
add_systems(OnExit(GameloopStates::Spawn), draw_next).
add_systems(Update, draw_board.run_if(in_state(GameStates::Gameplay))). add_systems(Update, draw_board.run_if(in_state(GameStates::Gameplay))).
add_systems(Update, receive_input_on_game_over.run_if(in_state(GameStates::GameOver))); add_systems(Update, receive_input_on_game_over.run_if(in_state(GameStates::GameOver)));
} }

View File

@ -22,6 +22,87 @@ impl Piece {
} }
} }
pub struct Difficulty { // that struct pretty much describes rules
pub gravity: f32, // G
pub lock_delay: u8, // frames
pub lock_delay_resets: u8, // times
pub spawn_delay: u8, // frames
pub line_clear_delay: u8, // frames
pub stack_invis: bool,
pub stack_invis_delay: u8, // frames
pub next_allowed: u8, // num of next pieces to preview
pub hold_allowed: bool
}
pub struct DelayMilliseconds {
value: f32,
left: f32,
pub active: bool
}
impl DelayMilliseconds {
fn get_delay(&self) -> f32 {
self.value
}
fn get_delay_left(&self) -> f32 {
self.left
}
fn create(delay: f32) -> DelayMilliseconds{
DelayMilliseconds { value: delay, left: delay, active: false }
}
fn reset(&mut self) {
self.left = self.value;
}
fn tick(&mut self, delta: f32) {
if self.active && self.left > 0.0 {
self.left -= delta;
if self.left < 0.0 { self.left = 0.0; }
}
}
fn is_done(&self) -> bool {
self.left == 0.0
}
}
pub struct DelayFrames {
value: u8,
left: u8,
pub active: bool
}
impl DelayFrames {
fn get_delay(&self) -> u8 {
self.value
}
fn get_delay_left(&self) -> u8 {
self.left
}
fn create(delay: u8) -> DelayFrames{
DelayFrames { value: delay, left: delay, active: false }
}
fn reset(&mut self) {
self.left = self.value;
}
fn tick(&mut self) {
if self.active && self.left > 0 {
self.left -= 1;
}
}
fn is_done(&self) -> bool {
self.left == 0
}
}
pub struct Board{ pub struct Board{
pub width: u8, pub width: u8,
pub height: u8, pub height: u8,
@ -131,19 +212,17 @@ pub struct Engine {
pub current_piece: Option<Piece>, pub current_piece: Option<Piece>,
pub board: Board, pub board: Board,
pub handling: Handling, pub handling: Handling,
pub difficulty: Difficulty,
pub rotation_system: PiecesData, pub rotation_system: PiecesData,
pub randomizer: Box<dyn Randomizer + Sync + Send>, pub randomizer: Box<dyn Randomizer + Sync + Send>,
pub next_queue: Vec<Piece>, pub next_queue: Vec<Piece>,
pub hold: Option<Piece>, pub hold: Option<Piece>,
pub can_hold: bool, // anti-abuse pub can_hold: bool,
pub hold_enabled: bool, // game rule
pub g: f32, pub g: f32,
pub g_bucket: f32,
pub lock_delay: u8, pub lock_delay: u8,
pub lock_delay_left: u8,
pub lock_delay_resets: u8, pub lock_delay_resets: u8,
pub lock_delay_resets_left: u8,
pub lock_delay_active: bool, pub lock_delay_active: bool,
pub spawn_delay: u8,
pub need_to_lock: bool, // when lock resets ended pub need_to_lock: bool, // when lock resets ended
} }
@ -153,18 +232,16 @@ impl Default for Engine {
current_piece: None, current_piece: None,
board: Board::create(10, 20, 20, true, true, 3), board: Board::create(10, 20, 20, true, true, 3),
handling: Handling::create(200.0, 33.0, 20.0), handling: Handling::create(200.0, 33.0, 20.0),
difficulty: Difficulty { gravity: 1.0/60.0, lock_delay: 30, lock_delay_resets: 15, spawn_delay: 30, line_clear_delay: 20, stack_invis: false, stack_invis_delay: 240, next_allowed: 3, hold_allowed: true },
rotation_system: ROTATION_SYSTEMS["SRS"].clone(), rotation_system: ROTATION_SYSTEMS["SRS"].clone(),
next_queue: vec![], next_queue: vec![],
hold: None, hold: None,
can_hold: true, can_hold: true,
hold_enabled: true, g: 0.0,
g: 1.0/60.0,
g_bucket: 0.0,
lock_delay: 30, lock_delay: 30,
lock_delay_left: 30,
lock_delay_resets: 15, lock_delay_resets: 15,
lock_delay_resets_left: 15,
lock_delay_active: false, lock_delay_active: false,
spawn_delay: 0,
need_to_lock: false, need_to_lock: false,
randomizer: Box::new(Bag{}), randomizer: Box::new(Bag{}),
} }
@ -183,6 +260,7 @@ impl Engine {
pub fn init(&mut self, rotation_system: &str, randomizer: Box<dyn Randomizer + Sync + Send>){ pub fn init(&mut self, rotation_system: &str, randomizer: Box<dyn Randomizer + Sync + Send>){
self.rotation_system = ROTATION_SYSTEMS[rotation_system].clone(); self.rotation_system = ROTATION_SYSTEMS[rotation_system].clone();
self.randomizer = randomizer; self.randomizer = randomizer;
self.spawn_delay = self.difficulty.spawn_delay;
while self.next_queue.len() <= self.board.show_next as usize { while self.next_queue.len() <= self.board.show_next as usize {
self.next_queue.append(&mut self.randomizer.populate_next(&self.rotation_system, self.board.width as isize, self.board.height as isize)); self.next_queue.append(&mut self.randomizer.populate_next(&self.rotation_system, self.board.width as isize, self.board.height as isize));
} }
@ -200,7 +278,7 @@ impl Engine {
} }
pub fn hold_current_piece(&mut self) -> bool { pub fn hold_current_piece(&mut self) -> bool {
if !self.hold_enabled || !self.can_hold { if !self.difficulty.hold_allowed || !self.can_hold {
return false; return false;
} }
self.current_piece.as_mut().unwrap().rotation = 0; self.current_piece.as_mut().unwrap().rotation = 0;
@ -263,18 +341,18 @@ impl Engine {
LockDelayMode::ResetOnYChange => {}, LockDelayMode::ResetOnYChange => {},
LockDelayMode::ResetOnMovementLimited => { LockDelayMode::ResetOnMovementLimited => {
if !self.position_is_valid((self.current_piece.as_ref().unwrap().position.0, self.current_piece.as_ref().unwrap().position.1-1), self.current_piece.as_ref().unwrap().rotation){ if !self.position_is_valid((self.current_piece.as_ref().unwrap().position.0, self.current_piece.as_ref().unwrap().position.1-1), self.current_piece.as_ref().unwrap().rotation){
self.lock_delay_left = self.lock_delay; self.lock_delay = self.difficulty.lock_delay;
if self.lock_delay_resets_left == 0{ if self.lock_delay_resets == 0{
self.need_to_lock = true; self.need_to_lock = true;
}else{ }else{
self.lock_delay_resets_left -= 1; self.lock_delay_resets -= 1;
self.lock_delay_active = false; self.lock_delay_active = false;
} }
} }
}, },
LockDelayMode::ResetOnMovement => { LockDelayMode::ResetOnMovement => {
if !self.position_is_valid((self.current_piece.as_ref().unwrap().position.0, self.current_piece.as_ref().unwrap().position.1-1), self.current_piece.as_ref().unwrap().rotation){ if !self.position_is_valid((self.current_piece.as_ref().unwrap().position.0, self.current_piece.as_ref().unwrap().position.1-1), self.current_piece.as_ref().unwrap().rotation){
self.lock_delay_left = self.lock_delay; self.lock_delay = self.difficulty.lock_delay;
self.lock_delay_active = false; self.lock_delay_active = false;
} }
}, },

View File

@ -1,3 +1,5 @@
use std::{thread, time::Duration};
use super::{resources::Engine, rotation_systems::LockDelayMode, GameStates, GameloopStates, randomizers::*}; use super::{resources::Engine, rotation_systems::LockDelayMode, GameStates, GameloopStates, randomizers::*};
use crate::engine::components::*; use crate::engine::components::*;
use bevy::{prelude::*, sprite::MaterialMesh2dBundle, render::view::ColorGrading}; use bevy::{prelude::*, sprite::MaterialMesh2dBundle, render::view::ColorGrading};
@ -390,14 +392,14 @@ pub fn gameloop(
match engine.current_piece { match engine.current_piece {
Some(piece) => { Some(piece) => {
if engine.handling.sdf_active { if engine.handling.sdf_active {
engine.g_bucket += engine.g * engine.handling.sdf; engine.g += engine.difficulty.gravity * engine.handling.sdf;
} else { } else {
engine.g_bucket += engine.g; engine.g += engine.difficulty.gravity;
} }
let mut gravity_tick_happend = false; let mut gravity_tick_happend = false;
while engine.g_bucket >= 1.0 { while engine.g >= 1.0 {
engine.move_current_piece((0, -1)); engine.move_current_piece((0, -1));
engine.g_bucket -= 1.0; engine.g -= 1.0;
gravity_tick_happend = true; gravity_tick_happend = true;
} }
let previos_lock_delay_active = engine.lock_delay_active; let previos_lock_delay_active = engine.lock_delay_active;
@ -414,13 +416,13 @@ pub fn gameloop(
} }
} }
LockDelayMode::ResetOnYChange => { LockDelayMode::ResetOnYChange => {
engine.lock_delay_left -= 1; engine.lock_delay -= 1;
} }
LockDelayMode::ResetOnMovementLimited => { LockDelayMode::ResetOnMovementLimited => {
engine.lock_delay_left -= 1; engine.lock_delay -= 1;
} }
LockDelayMode::ResetOnMovement => { LockDelayMode::ResetOnMovement => {
engine.lock_delay_left -= 1; engine.lock_delay -= 1;
} }
} }
} else { } else {
@ -429,23 +431,23 @@ pub fn gameloop(
LockDelayMode::Disabled => {} LockDelayMode::Disabled => {}
LockDelayMode::Gravity => {} LockDelayMode::Gravity => {}
LockDelayMode::ResetOnYChange => { LockDelayMode::ResetOnYChange => {
engine.lock_delay_left = engine.lock_delay; engine.lock_delay = engine.difficulty.lock_delay;
if engine.lock_delay_resets == 0 { if engine.lock_delay_resets == 0 {
engine.need_to_lock = true; engine.need_to_lock = true;
} else { } else {
engine.lock_delay_resets_left -= 1; engine.lock_delay_resets -= 1;
} }
} }
LockDelayMode::ResetOnMovementLimited => { LockDelayMode::ResetOnMovementLimited => {
engine.lock_delay_left = engine.lock_delay; engine.lock_delay = engine.difficulty.lock_delay;
} }
LockDelayMode::ResetOnMovement => { LockDelayMode::ResetOnMovement => {
engine.lock_delay_left = engine.lock_delay; engine.lock_delay = engine.difficulty.lock_delay;
} }
} }
} }
} }
if (engine.lock_delay_left < 1 || engine.need_to_lock) if (engine.lock_delay < 1 || engine.need_to_lock)
&& !engine && !engine
.position_is_valid((piece.position.0, piece.position.1 - 1), piece.rotation) .position_is_valid((piece.position.0, piece.position.1 - 1), piece.rotation)
{ {
@ -458,7 +460,7 @@ pub fn gameloop(
for mut text in lock_delay_text.iter_mut() { for mut text in lock_delay_text.iter_mut() {
text.sections[0].value = format!( text.sections[0].value = format!(
"{}; {}", "{}; {}",
engine.lock_delay_resets_left, engine.lock_delay_left engine.lock_delay_resets, engine.lock_delay
); );
} }
} }
@ -468,10 +470,20 @@ pub fn after_locking_routine(
mut next_state: ResMut<NextState<GameloopStates>>, mut next_state: ResMut<NextState<GameloopStates>>,
) { ) {
engine.board.clear_full_lines(); engine.board.clear_full_lines();
engine.lock_delay_left = engine.lock_delay;
engine.lock_delay_resets_left = engine.lock_delay_resets;
engine.lock_delay_active = false;
next_state.set(GameloopStates::Spawn); next_state.set(GameloopStates::Spawn);
}
pub fn run_spawn_delay(
mut engine: ResMut<Engine>,
mut next_state: ResMut<NextState<GameloopStates>>,
){
if engine.spawn_delay > 0 {
engine.spawn_delay -= 1;
}else{
engine.spawn_delay = engine.difficulty.spawn_delay;
next_state.set(GameloopStates::Falling);
}
} }
pub fn spawn_routine( pub fn spawn_routine(
@ -479,6 +491,9 @@ pub fn spawn_routine(
mut next_state: ResMut<NextState<GameloopStates>>, mut next_state: ResMut<NextState<GameloopStates>>,
mut game_next_state: ResMut<NextState<GameStates>>, mut game_next_state: ResMut<NextState<GameStates>>,
) { ) {
engine.lock_delay = engine.difficulty.lock_delay;
engine.lock_delay_resets = engine.difficulty.lock_delay_resets;
engine.lock_delay_active = false;
if engine.spawn_sequence() { if engine.spawn_sequence() {
next_state.set(GameloopStates::Falling); next_state.set(GameloopStates::Falling);
} else { } else {