restarting on tetris

main
Elijah Voigt 2 weeks ago
parent 6b2370c6a5
commit b576de94e4

50
Cargo.lock generated

@ -741,6 +741,35 @@ dependencies = [
"encase_derive_impl",
]
[[package]]
name = "bevy_feathers"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6a75a7f32e355d9232a92b3bca9f90af18f3c81232d26d1baed77f1326863ec"
dependencies = [
"accesskit",
"bevy_a11y",
"bevy_app",
"bevy_asset",
"bevy_camera",
"bevy_color",
"bevy_ecs",
"bevy_input_focus",
"bevy_log",
"bevy_math",
"bevy_picking",
"bevy_platform",
"bevy_reflect",
"bevy_render",
"bevy_shader",
"bevy_text",
"bevy_ui",
"bevy_ui_render",
"bevy_ui_widgets",
"bevy_window",
"smol_str",
]
[[package]]
name = "bevy_gilrs"
version = "0.17.2"
@ -925,6 +954,7 @@ dependencies = [
"bevy_derive",
"bevy_diagnostic",
"bevy_ecs",
"bevy_feathers",
"bevy_gilrs",
"bevy_gizmos",
"bevy_gltf",
@ -953,6 +983,7 @@ dependencies = [
"bevy_transform",
"bevy_ui",
"bevy_ui_render",
"bevy_ui_widgets",
"bevy_utils",
"bevy_window",
"bevy_winit",
@ -1554,6 +1585,25 @@ dependencies = [
"tracing",
]
[[package]]
name = "bevy_ui_widgets"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f131e13aa2ea9f8fa9af92aadfd6cf7f47d561d21510cf76854b46808c9b9bf"
dependencies = [
"accesskit",
"bevy_a11y",
"bevy_app",
"bevy_ecs",
"bevy_input",
"bevy_input_focus",
"bevy_log",
"bevy_math",
"bevy_picking",
"bevy_reflect",
"bevy_ui",
]
[[package]]
name = "bevy_utils"
version = "0.17.2"

@ -30,7 +30,7 @@ version = "0.4.1"
[dependencies.bevy]
version = "0.17.2"
features = ["wayland", "dynamic_linking", "track_location"]
features = ["wayland", "dynamic_linking", "track_location", "experimental_bevy_feathers", "experimental_bevy_ui_widgets"]
[dev-dependencies]
lipsum = "*"

@ -1,45 +0,0 @@
# Design
## Tetris
Matrix Multiplication for rotating pieces.
Each piece (shape) contains a Mat4 containing a representation of it's shape.
For example:
```
0 1 0 0
0 1 0 0
0 1 0 0
0 1 0 0
```
This is the classic `line` piece.
And here it is on it's `up` side
```
0 0 0 0
1 1 1 1
0 0 0 0
0 0 0 0
```
And here is the `t` piece
```
0 1 0
1 1 1
0 0 0
```
A matrix multiplication is applied to this Mat6 to achieve a piece rotation.
When that matrix is updated, the 4 blocks parented to the shape are moved to reflect this new shape.
This matrix also allows us to do checks to see if any of the blocks in the shape would intersect with another piece on the board.
We can also check if a piece would go out of bounds during a move or rotation.
We can use this to "plan -> validate -> commit" changes based on user input.
Question: How the fuck do matrix multiplications work??

@ -1,7 +0,0 @@
# Falling Blocks RPG
This game is inspired by both Tetris and Peglin.
Your goal is to play Tetris (or a similar falling block game) but while that is happening you are carrying out a 2d real-time combat RPG battle.
Between battles/levels you choose a different level to go to in an overworld, choose upgrades, perks, and maybe some other stuff!

@ -1,15 +0,0 @@
# Tetris Battle
- Recognize finishing a level successfully
- Recognize failing a level
- Art pass
- Nicer preview for "Next" and "Swap" Shapes
- Use a timer resource for next step
## Bugs
- Two blocks in the same position
- Skipping doesn't work 100% of the time
- A little delay after skipping
## Nice to haves
- Fix tests after Shape -> ShapeLayout refactor

File diff suppressed because it is too large Load Diff

@ -1,209 +0,0 @@
use super::*;
#[test]
fn test_shape_t() {
let mut shape = Shape::new_t();
let expected_up = "010\n\
111\n\
000\n";
let expected_right = "010\n\
011\n\
010\n";
let expected_down = "000\n\
111\n\
010\n";
let expected_left = "010\n\
110\n\
010\n";
assert_eq!(shape.as_ascii(), expected_up);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_right);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_down);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_left);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_up);
}
#[test]
fn test_shape_i() {
let mut shape = Shape::new_i();
let expected_up = "1\n\
1\n\
1\n\
1\n";
let expected_right = "1111\n";
let expected_down = "1\n\
1\n\
1\n\
1\n";
let expected_left = "1111\n";
assert_eq!(shape.as_ascii(), expected_up);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_right);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_down);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_left);
shape = shape.rotated();
assert_eq!(shape.as_ascii(), expected_up);
}
#[test]
fn test_coordinates() {
let shape = Shape::new_t();
let center = GridPosition { x: 5, y: 5 };
let actual: Vec<Result<GridPosition, OutOfBoundsError>> = shape.coordinates(&center).collect();
let expected: Vec<Result<GridPosition, OutOfBoundsError>> = vec![
Ok((4, 5).into()),
Ok((5, 5).into()),
Ok((6, 5).into()),
Ok((5, 6).into()),
];
assert_eq!(shape.layout.center(), (1, 1));
assert_eq!(actual, expected);
}
#[test]
fn test_height() {
// todo: should be 2 for t piece
assert_eq!(Shape::new_t().height(), 3);
assert_eq!(Shape::new_i().height(), 4);
assert_eq!(Shape::new_l().height(), 3);
}
#[test]
fn test_shape_block_layout_rotation() {
{
let actual = ShapeBlockLayout {
inner: vec![vec![0, 0, 1]],
}
.rotated();
let expected = ShapeBlockLayout {
inner: vec![vec![0], vec![0], vec![1]],
};
assert_eq!(expected, actual);
}
{
let actual = ShapeBlockLayout {
inner: vec![vec![1, 2, 3], vec![4, 5, 6]],
}
.rotated();
let expected = ShapeBlockLayout {
inner: vec![vec![4, 1], vec![5, 2], vec![6, 3]],
};
assert_eq!(expected, actual);
}
{
let actual = ShapeBlockLayout {
inner: vec![vec![1, 2, 3], vec![4, 5, 6]],
}
.rotated();
let expected = ShapeBlockLayout {
inner: vec![vec![4, 1], vec![5, 2], vec![6, 3]],
};
assert_eq!(expected, actual);
}
{
let actual = ShapeBlockLayout {
inner: vec![
vec![1, 2, 3, 4],
vec![5, 6, 7, 8],
vec![9, 10, 11, 12],
vec![13, 14, 15, 16],
],
}
.rotated();
let expected = ShapeBlockLayout {
inner: vec![
vec![13, 9, 5, 1],
vec![14, 10, 6, 2],
vec![15, 11, 7, 3],
vec![16, 12, 8, 4],
],
};
assert_eq!(expected, actual);
}
}
#[test]
fn test_shape_block_center() {
{
let actual = ShapeBlockLayout {
inner: vec![vec![0], vec![0], vec![0]],
}
.center();
let expected = (0, 1);
assert_eq!(actual, expected);
}
{
let actual = ShapeBlockLayout {
inner: vec![vec![0], vec![0], vec![0], vec![0]],
}
.center();
let expected = (0, 2);
assert_eq!(actual, expected);
}
{
let actual = ShapeBlockLayout {
inner: vec![vec![0, 0], vec![0, 0]],
}
.center();
let expected = (0, 1);
assert_eq!(actual, expected);
}
{
let actual = ShapeBlockLayout {
inner: vec![vec![0, 0, 0], vec![0, 0, 0], vec![0, 0, 0]],
}
.center();
let expected = (1, 1);
assert_eq!(actual, expected);
}
{
let actual = ShapeBlockLayout {
inner: vec![
vec![0, 0, 0, 0],
vec![0, 0, 0, 0],
vec![0, 0, 0, 0],
vec![0, 0, 0, 0],
],
}
.center();
let expected = (1, 2);
assert_eq!(actual, expected);
}
}

@ -35,12 +35,15 @@ pub use bevy::{
math::FloatOrd,
pbr::wireframe::{WireframeConfig, WireframePlugin},
platform::{collections::HashMap, hash::RandomState},
prelude::*,
prelude::{State, *},
reflect::TypePath,
render::render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages},
sprite_render::*,
time::common_conditions::*,
window::{WindowResized, WindowResolution},
ui_widgets::{Button, *},
ui::*,
feathers::controls::*,
};
pub use itertools::Itertools;
pub use serde::Deserialize;

Loading…
Cancel
Save