Shadow piece + new texture for minos + lock resets

It's works weird. Also varius fixes (I hope they fix)
This commit is contained in:
dan63047 2023-11-12 00:30:00 +03:00
parent 87d2459690
commit 8c40d97d73
7 changed files with 108 additions and 47 deletions

BIN
assets/default_mino.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

BIN
skin.xcf

Binary file not shown.

View File

@ -5,5 +5,5 @@ pub struct BoardVisual{}
#[derive(Component, Clone, Copy)] #[derive(Component, Clone, Copy)]
pub struct Mino{ pub struct Mino{
pub skin_index: usize pub color: Color
} }

View File

@ -2,11 +2,12 @@ use std::mem::swap;
use bevy::prelude::*; use bevy::prelude::*;
use super::{rotation_systems::{PiecesData, ROTATION_SYSTEMS}, components::Mino, randomizers::{Randomizer, Bag}}; use super::{rotation_systems::{PiecesData, ROTATION_SYSTEMS, LockDelayMode}, components::Mino, randomizers::{Randomizer, Bag}};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Piece{ pub struct Piece{
pub id: usize, pub id: usize,
pub color: Color,
pub position: (isize, isize), pub position: (isize, isize),
pub rotation: usize pub rotation: usize
} }
@ -14,7 +15,7 @@ pub struct Piece{
impl Piece { impl Piece {
pub fn create(pieces_data: &PiecesData, id: usize) -> Piece{ pub fn create(pieces_data: &PiecesData, id: usize) -> Piece{
let final_position = (3+pieces_data.spawn_offsets[id].0, 20+pieces_data.spawn_offsets[id].1); let final_position = (3+pieces_data.spawn_offsets[id].0, 20+pieces_data.spawn_offsets[id].1);
Piece { id: id, position: final_position, rotation: 0 } Piece { id: id, color: pieces_data.colours[id], position: final_position, rotation: 0 }
} }
} }
@ -138,7 +139,8 @@ pub struct Engine {
pub lock_delay: u8, pub lock_delay: u8,
pub lock_delay_left: 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_resets_left: u8,
pub need_to_lock: bool, // when lock resets ended
} }
impl Default for Engine { impl Default for Engine {
@ -158,6 +160,7 @@ impl Default for Engine {
lock_delay_left: 30, lock_delay_left: 30,
lock_delay_resets: 15, lock_delay_resets: 15,
lock_delay_resets_left: 15, lock_delay_resets_left: 15,
need_to_lock: false,
randomizer: Box::new(Bag{}), randomizer: Box::new(Bag{}),
} }
} }
@ -165,6 +168,9 @@ impl Default for Engine {
impl Engine { impl Engine {
fn from_next_to_current(&mut self){ fn from_next_to_current(&mut self){
if self.next_queue.len() <= self.board.show_next as usize {
self.next_queue.append(&mut self.randomizer.populate_next(&self.rotation_system));
}
self.current_piece = self.next_queue.first().copied(); self.current_piece = self.next_queue.first().copied();
self.next_queue.remove(0); self.next_queue.remove(0);
} }
@ -176,9 +182,6 @@ impl Engine {
} }
pub fn spawn_sequence(&mut self) -> bool { pub fn spawn_sequence(&mut self) -> bool {
if self.next_queue.len() <= self.board.show_next as usize {
self.next_queue.append(&mut self.randomizer.populate_next(&self.rotation_system));
}
self.from_next_to_current(); self.from_next_to_current();
if !self.position_is_valid(self.current_piece.as_ref().unwrap().position, self.current_piece.as_ref().unwrap().rotation){ if !self.position_is_valid(self.current_piece.as_ref().unwrap().position, self.current_piece.as_ref().unwrap().rotation){
return false; return false;
@ -193,6 +196,7 @@ impl Engine {
return false; return false;
} }
self.current_piece.as_mut().unwrap().rotation = 0; self.current_piece.as_mut().unwrap().rotation = 0;
self.current_piece.as_mut().unwrap().position = (3+self.rotation_system.spawn_offsets[self.current_piece.as_ref().unwrap().id].0, 20+self.rotation_system.spawn_offsets[self.current_piece.as_ref().unwrap().id].1);
match self.hold { match self.hold {
Some(_) => { Some(_) => {
swap(&mut self.current_piece, &mut self.hold); swap(&mut self.current_piece, &mut self.hold);
@ -211,17 +215,20 @@ impl Engine {
return false; return false;
} }
let minos_to_write = &self.rotation_system.pieces[self.current_piece.as_ref().unwrap().id][self.current_piece.as_ref().unwrap().rotation]; let minos_to_write = &self.rotation_system.pieces[self.current_piece.as_ref().unwrap().id][self.current_piece.as_ref().unwrap().rotation];
let color_index = self.rotation_system.skin_index[self.current_piece.as_ref().unwrap().id];
for mino in minos_to_write{ for mino in minos_to_write{
let x = (self.current_piece.as_ref().unwrap().position.0 + mino.0 as isize) as usize; let x = (self.current_piece.as_ref().unwrap().position.0 + mino.0 as isize) as usize;
let y = (self.current_piece.as_ref().unwrap().position.1 + mino.1 as isize) as usize; let y = (self.current_piece.as_ref().unwrap().position.1 + mino.1 as isize) as usize;
self.board.board[y][x] = Some(Mino{ skin_index: color_index }); self.board.board[y][x] = Some(Mino{ color: self.rotation_system.colours[self.current_piece.as_ref().unwrap().id] });
} }
self.current_piece = None; self.current_piece = None;
self.need_to_lock = false;
return true; return true;
} }
pub fn sonic_drop(&mut self) -> bool { pub fn sonic_drop(&mut self) -> bool {
if self.current_piece.is_none(){
return false;
}
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) {
return false; return false;
} }
@ -237,7 +244,43 @@ impl Engine {
y y
} }
fn lock_delay_check(&mut self, shift: (i8, i8)){
match self.rotation_system.lock_delay_mode {
LockDelayMode::Disabled => {},
LockDelayMode::Gravity => {},
LockDelayMode::ResetOnYChange => {
if shift.1 < 0 {
self.lock_delay_left = self.lock_delay;
if self.lock_delay_resets_left == 0{
self.need_to_lock = true;
}else{
self.lock_delay_resets_left -= 1;
}
}
},
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){
self.lock_delay_left = self.lock_delay;
if self.lock_delay_resets_left == 0{
self.need_to_lock = true;
}else{
self.lock_delay_resets_left -= 1;
}
}
},
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){
self.lock_delay_left = self.lock_delay;
}
},
}
info!("lock resets: {}, lock delay: {}", self.lock_delay_resets_left, self.lock_delay_left);
}
pub fn rotate_current_piece(&mut self, rotation: i8) -> bool { pub fn rotate_current_piece(&mut self, rotation: i8) -> bool {
if self.current_piece.is_none(){
return false;
}
let future_rotation = (self.current_piece.as_ref().unwrap().rotation as i8 + rotation) as usize % self.rotation_system.pieces[self.current_piece.as_ref().unwrap().id].len(); let future_rotation = (self.current_piece.as_ref().unwrap().rotation as i8 + rotation) as usize % self.rotation_system.pieces[self.current_piece.as_ref().unwrap().id].len();
let id_for_kicks: usize = if rotation == 1 { let id_for_kicks: usize = if rotation == 1 {
0 0
@ -249,6 +292,7 @@ impl Engine {
if self.position_is_valid(future_position, future_rotation) { if self.position_is_valid(future_position, future_rotation) {
self.current_piece.as_mut().unwrap().rotation = future_rotation; self.current_piece.as_mut().unwrap().rotation = future_rotation;
self.current_piece.as_mut().unwrap().position = future_position; self.current_piece.as_mut().unwrap().position = future_position;
self.lock_delay_check(*test);
return true; return true;
} }
} }
@ -259,6 +303,7 @@ impl Engine {
if (shift.0 == 0 && shift.1 == 0) || self.current_piece.is_none(){ if (shift.0 == 0 && shift.1 == 0) || self.current_piece.is_none(){
return true; return true;
} }
self.lock_delay_check(shift);
let future_position = ( let future_position = (
self.current_piece.as_ref().unwrap().position.0 + shift.0 as isize, // future X self.current_piece.as_ref().unwrap().position.0 + shift.0 as isize, // future X
self.current_piece.as_ref().unwrap().position.1 + shift.1 as isize // future Y self.current_piece.as_ref().unwrap().position.1 + shift.1 as isize // future Y

View File

@ -1,4 +1,4 @@
use bevy::utils::HashMap; use bevy::{utils::HashMap, prelude::Color};
use lazy_static::lazy_static; use lazy_static::lazy_static;
#[derive(Clone)] #[derive(Clone)]
@ -16,8 +16,7 @@ pub struct PiecesData {
pub pieces: Vec<Vec<Vec<(u8, u8)>>>, pub pieces: Vec<Vec<Vec<(u8, u8)>>>,
// X and Y shifts for pieces (kicks[piece][rotation before spin][direction of rotation] = Vec of points for tests) // X and Y shifts for pieces (kicks[piece][rotation before spin][direction of rotation] = Vec of points for tests)
pub kicks: Vec<Vec<Vec<Vec<(i8, i8)>>>>, pub kicks: Vec<Vec<Vec<Vec<(i8, i8)>>>>,
// Takes 64x64 sprite fragment with this index as Mino skin (skin_index[piece]) pub colours: Vec<Color>,
pub skin_index: Vec<usize>,
// If spawn position is fucked, it fixes it // If spawn position is fucked, it fixes it
pub spawn_offsets: Vec<(isize, isize)>, pub spawn_offsets: Vec<(isize, isize)>,
pub lock_delay_mode: LockDelayMode pub lock_delay_mode: LockDelayMode
@ -199,7 +198,15 @@ lazy_static!{
] ]
], ],
], ],
skin_index: vec![0, 1, 2, 3, 4, 5, 6], colours: vec![
Color::RED, // Z
Color::Rgba { red: 0.0, green: 0.3, blue: 1.0, alpha: 1.0 }, // J
Color::CYAN, // I
Color::Rgba { red: 1.0, green: 0.0, blue: 1.0, alpha: 1.0 }, // T
Color::YELLOW, // O
Color::ORANGE, // L
Color::GREEN // Z
],
spawn_offsets: vec![ spawn_offsets: vec![
(0, 0), // Z (0, 0), // Z
(0, 0), // J (0, 0), // J

View File

@ -48,14 +48,9 @@ pub fn draw_board(
y*MINO_SIZE-(engine.board.height as f32)/2.0*MINO_SIZE+MINO_SIZE/2.0, y*MINO_SIZE-(engine.board.height as f32)/2.0*MINO_SIZE+MINO_SIZE/2.0,
0.0 0.0
), ),
texture: asset_server.load("skin.png"), texture: asset_server.load("default_mino.png"),
sprite: Sprite { sprite: Sprite {
rect: Some( color: mino.color,
Rect{
min: Vec2 { x: 0.0+(64.0*mino.skin_index as f32), y: 0.0 },
max: Vec2 { x: 63.0+(64.0*mino.skin_index as f32), y: 63.0 },
}
),
custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}), custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}),
..default() ..default()
}, },
@ -83,22 +78,17 @@ pub fn draw_board(
transform: Transform::from_xyz( transform: Transform::from_xyz(
x*MINO_SIZE - (engine.board.width as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.0 as f32 * MINO_SIZE, x*MINO_SIZE - (engine.board.width as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.0 as f32 * MINO_SIZE,
y*MINO_SIZE - (engine.board.height as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE, y*MINO_SIZE - (engine.board.height as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE,
0.0 1.0
), ),
texture: asset_server.load("skin.png"), texture: asset_server.load("default_mino.png"),
sprite: Sprite { sprite: Sprite {
rect: Some( color: engine.rotation_system.colours[piece.id],
Rect{
min: Vec2 { x: 00.0+(64.0*engine.rotation_system.skin_index[piece.id] as f32), y: 00.0 },
max: Vec2 { x: 63.0+(64.0*engine.rotation_system.skin_index[piece.id] as f32), y: 63.0 },
}
),
custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}), custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}),
..default() ..default()
}, },
..default() ..default()
}, },
Mino{skin_index: engine.rotation_system.skin_index[piece.id]}, Mino{color: engine.rotation_system.colours[piece.id]},
)); ));
} }
}, },
@ -117,20 +107,15 @@ pub fn draw_board(
y* MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE, y* MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE,
0.0 0.0
), ),
texture: asset_server.load("skin.png"), texture: asset_server.load("default_mino.png"),
sprite: Sprite { sprite: Sprite {
rect: Some( color: engine.rotation_system.colours[engine.next_queue[i].id],
Rect{
min: Vec2 { x: 00.0+(64.0*engine.rotation_system.skin_index[engine.next_queue[i].id] as f32), y: 00.0 },
max: Vec2 { x: 63.0+(64.0*engine.rotation_system.skin_index[engine.next_queue[i].id] as f32), y: 63.0 },
}
),
custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}), custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}),
..default() ..default()
}, },
..default() ..default()
}, },
Mino{skin_index: engine.rotation_system.skin_index[engine.next_queue[i].id]}, Mino{color: engine.rotation_system.colours[engine.next_queue[i].id]},
)); ));
} }
y -= 4.0; y -= 4.0;
@ -148,26 +133,50 @@ pub fn draw_board(
-2.0*MINO_SIZE + (engine.board.height as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE, -2.0*MINO_SIZE + (engine.board.height as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE,
0.0 0.0
), ),
texture: asset_server.load("skin.png"), texture: asset_server.load("default_mino.png"),
sprite: Sprite { sprite: Sprite {
rect: Some( color: piece.color,
Rect{
min: Vec2 { x: 00.0+(64.0*engine.rotation_system.skin_index[piece.id] as f32), y: 00.0 },
max: Vec2 { x: 63.0+(64.0*engine.rotation_system.skin_index[piece.id] as f32), y: 63.0 },
}
),
custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}), custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}),
..default() ..default()
}, },
..default() ..default()
}, },
Mino{skin_index: engine.rotation_system.skin_index[piece.id]}, Mino{color: piece.color},
)); ));
} }
}, },
None => {}, None => {},
} }
// draw shadow
if engine.board.show_shadow {
match engine.current_piece.as_ref() {
Some(piece) => {
x = piece.position.0 as f32;
y = engine.lowest_point_under_current_piece() as f32;
for mino in &engine.rotation_system.pieces[piece.id][piece.rotation]{
commands.spawn((
SpriteBundle {
transform: Transform::from_xyz(
x*MINO_SIZE - (engine.board.width as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.0 as f32 * MINO_SIZE,
y*MINO_SIZE - (engine.board.height as f32)/2.0*MINO_SIZE + MINO_SIZE/2.0 + mino.1 as f32 * MINO_SIZE,
0.0
),
texture: asset_server.load("default_mino.png"),
sprite: Sprite {
color: Color::Rgba { red: 1.0, green: 1.0, blue: 1.0, alpha: 0.1 },
custom_size: Some(Vec2 {x: MINO_SIZE, y: MINO_SIZE}),
..default()
},
..default()
},
Mino{color: engine.rotation_system.colours[piece.id]},
));
}
},
None => {},
}
}
} }
pub fn receive_input( pub fn receive_input(
@ -246,7 +255,7 @@ pub fn gameloop(
}else{ }else{
engine.lock_delay_left = engine.lock_delay; engine.lock_delay_left = engine.lock_delay;
} }
if engine.lock_delay_left < 1 && !engine.position_is_valid((piece.position.0, piece.position.1-1), piece.rotation){ if (engine.lock_delay_left < 1 || engine.need_to_lock) && !engine.position_is_valid((piece.position.0, piece.position.1-1), piece.rotation){
engine.lock_current_piece(); engine.lock_current_piece();
next_state.set(GameloopStates::AfterLocking); next_state.set(GameloopStates::AfterLocking);
} }