retrying tetris
This commit is contained in:
251
src/bin/fail_tetris.rs
Normal file
251
src/bin/fail_tetris.rs
Normal file
@ -0,0 +1,251 @@
|
||||
use bevy::window::PrimaryWindow;
|
||||
use bevy::{prelude::*, window::WindowResolution};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::{Add, Sub};
|
||||
|
||||
use glite::debug_plugin;
|
||||
|
||||
#[cfg_attr(feature = "debug", derive(bevy_inspector_egui::InspectorOptions))]
|
||||
#[derive(Component, Debug, Default, Copy, Clone, Eq, PartialEq, Reflect)]
|
||||
struct Position {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub z: u32, // render order
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Reflect)]
|
||||
struct Size {
|
||||
width: f32,
|
||||
height: f32,
|
||||
}
|
||||
|
||||
impl Size {
|
||||
pub fn square(x: f32) -> Self {
|
||||
Self {
|
||||
width: x,
|
||||
height: x,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn post_scale_tiles(
|
||||
window: Single<&Window>,
|
||||
matrix: Res<Matrix>,
|
||||
mut q: Query<(&Size, &mut Transform), With<Tile>>,
|
||||
) {
|
||||
for (sprite_size, mut transform) in q.iter_mut() {
|
||||
transform.scale = Vec3::new(
|
||||
sprite_size.width / matrix.width as f32 * window.width(),
|
||||
sprite_size.height / matrix.height as f32 * window.height(),
|
||||
1.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn post_translate_tiles(
|
||||
window: Single<&Window>,
|
||||
matrix: Res<Matrix>,
|
||||
mut q: Query<(&Position, &mut Transform), With<Tile>>,
|
||||
) {
|
||||
// We subtract half the window width because our coordinate system starts at the bottom left, and
|
||||
// Translation starts from the center. We then add half the size of a single tile, because we want
|
||||
// our sprites bottom left corner to be at the bottom left of a tile, not the center.
|
||||
fn convert(pos: f32, bound_window: f32, bound_game: f32) -> f32 {
|
||||
let tile_size = bound_window / bound_game;
|
||||
pos / bound_game * bound_window - (bound_window / 2.) + (tile_size / 2.)
|
||||
}
|
||||
|
||||
for (pos, mut transform) in q.iter_mut() {
|
||||
transform.translation = Vec3::new(
|
||||
convert(pos.x as f32, window.width(), matrix.width as f32),
|
||||
convert(pos.y as f32, window.height(), matrix.height as f32),
|
||||
pos.z as f32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_tetrominos(
|
||||
tetrominos: Query<(&Tetromino, &mut Children)>,
|
||||
mut positions: Query<&mut Position, With<Tile>>,
|
||||
) {
|
||||
for (t, children) in tetrominos.iter() {
|
||||
for child in children.iter() {
|
||||
let mut p = positions.get_mut(*child).unwrap();
|
||||
p.x += t.pos.x;
|
||||
p.y += t.pos.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, Reflect)]
|
||||
struct TetrominoKind([[u32; 2]; 4]);
|
||||
|
||||
const BRICK_I: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [3, 0]]);
|
||||
const BRICK_J: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [2, 1]]);
|
||||
const BRICK_L: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [0, 1]]);
|
||||
const BRICK_O: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [0, 1], [1, 1]]);
|
||||
const BRICK_S: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [1, 1], [2, 1]]);
|
||||
const BRICK_T: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [1, 1]]);
|
||||
const BRICK_Z: TetrominoKind = TetrominoKind([[0, 1], [1, 1], [1, 0], [2, 0]]);
|
||||
|
||||
enum RenderLayer {
|
||||
Background = 0,
|
||||
Brick = 1,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
struct Tile;
|
||||
|
||||
#[derive(Bundle, Debug)]
|
||||
struct TileBundle {
|
||||
position: Position,
|
||||
size: Size,
|
||||
sprite: Sprite,
|
||||
tile: Tile,
|
||||
}
|
||||
|
||||
fn spawn_tile(commands: &mut Commands, color: Color, size: f32, position: Position) -> Entity {
|
||||
commands
|
||||
.spawn(TileBundle {
|
||||
position,
|
||||
size: Size::square(size),
|
||||
sprite: Sprite {
|
||||
color,
|
||||
..Default::default()
|
||||
},
|
||||
tile: Tile,
|
||||
})
|
||||
.id()
|
||||
}
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
struct Tetromino {
|
||||
pos: Position,
|
||||
kind: TetrominoKind,
|
||||
}
|
||||
|
||||
fn spawn_tetromino(commands: &mut Commands, kind: TetrominoKind, x: u32, y: u32) {
|
||||
let tetromino = commands
|
||||
.spawn(Tetromino {
|
||||
pos: Position { x, y, z: 0 },
|
||||
kind: kind.clone(),
|
||||
})
|
||||
.insert((Transform::default(), Visibility::default()))
|
||||
.id();
|
||||
|
||||
for coord in kind.0 {
|
||||
let e = spawn_tile(
|
||||
commands,
|
||||
Color::srgb(0.3, 0.3, 0.8),
|
||||
0.9,
|
||||
Position {
|
||||
x: x + coord[0],
|
||||
y: y + coord[1],
|
||||
z: RenderLayer::Brick as u32,
|
||||
},
|
||||
);
|
||||
commands.entity(e).set_parent(tetromino);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App::new();
|
||||
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
title: "Tetris".to_string(),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
}));
|
||||
|
||||
app.add_systems(
|
||||
Startup,
|
||||
(init_singletons, init_window, init_tile_grid).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
PostUpdate,
|
||||
(translate_tetrominos, post_scale_tiles, post_translate_tiles).chain(),
|
||||
);
|
||||
|
||||
app.add_plugins(debug_plugin::debug_plugin);
|
||||
|
||||
app.register_type::<Position>();
|
||||
app.register_type::<Tetromino>();
|
||||
app.register_type::<Size>();
|
||||
|
||||
// Run the app
|
||||
app.run();
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct Score(u32);
|
||||
|
||||
#[derive(Resource, Copy, Clone)]
|
||||
struct Matrix {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn init_singletons(mut commands: Commands) {
|
||||
let matrix = Matrix {
|
||||
height: 15,
|
||||
width: 15,
|
||||
};
|
||||
commands.insert_resource(Score(0));
|
||||
commands.insert_resource(matrix);
|
||||
|
||||
commands.spawn(Camera2d {});
|
||||
}
|
||||
|
||||
fn init_window(matrix: Res<Matrix>, mut window: Single<&mut Window>) {
|
||||
const SCALE_FACTOR: f32 = 77.;
|
||||
|
||||
window.resolution.set(
|
||||
matrix.width as f32 * SCALE_FACTOR,
|
||||
matrix.height as f32 * SCALE_FACTOR,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct Grid;
|
||||
|
||||
fn init_tile_grid(mut commands: Commands, matrix: Res<Matrix>) {
|
||||
let grid = commands
|
||||
.spawn(Grid)
|
||||
.insert(Name::new("Background Grid"))
|
||||
.insert((Transform::default(), Visibility::default()))
|
||||
.id();
|
||||
|
||||
for y in 0..matrix.height {
|
||||
for x in 0..matrix.width {
|
||||
let color = match (y + x) % 2 == 0 {
|
||||
true => Color::srgb(0.5, 0.5, 0.5),
|
||||
false => Color::srgb(0.55, 0.55, 0.55),
|
||||
};
|
||||
let e = spawn_tile(
|
||||
&mut commands,
|
||||
color,
|
||||
1.0,
|
||||
Position {
|
||||
x,
|
||||
y,
|
||||
z: RenderLayer::Background as u32,
|
||||
},
|
||||
);
|
||||
commands.entity(e).set_parent(grid);
|
||||
}
|
||||
}
|
||||
test_render_all_tetrominos(commands);
|
||||
}
|
||||
|
||||
fn test_render_all_tetrominos(mut commands: Commands) {
|
||||
spawn_tetromino(&mut commands, BRICK_I, 0, 0);
|
||||
spawn_tetromino(&mut commands, BRICK_T, 4, 0);
|
||||
spawn_tetromino(&mut commands, BRICK_J, 8, 0);
|
||||
spawn_tetromino(&mut commands, BRICK_L, 12, 0);
|
||||
|
||||
spawn_tetromino(&mut commands, BRICK_O, 0, 4);
|
||||
spawn_tetromino(&mut commands, BRICK_S, 4, 4);
|
||||
spawn_tetromino(&mut commands, BRICK_Z, 8, 4);
|
||||
spawn_tetromino(&mut commands, BRICK_J, 12, 4);
|
||||
}
|
@ -1,251 +1,3 @@
|
||||
use bevy::window::PrimaryWindow;
|
||||
use bevy::{prelude::*, window::WindowResolution};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::{Add, Sub};
|
||||
|
||||
use glite::debug_plugin;
|
||||
|
||||
#[cfg_attr(feature = "debug", derive(bevy_inspector_egui::InspectorOptions))]
|
||||
#[derive(Component, Debug, Default, Copy, Clone, Eq, PartialEq, Reflect)]
|
||||
struct Position {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub z: u32, // render order
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Reflect)]
|
||||
struct Size {
|
||||
width: f32,
|
||||
height: f32,
|
||||
}
|
||||
|
||||
impl Size {
|
||||
pub fn square(x: f32) -> Self {
|
||||
Self {
|
||||
width: x,
|
||||
height: x,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn post_scale_tiles(
|
||||
window: Single<&Window>,
|
||||
matrix: Res<Matrix>,
|
||||
mut q: Query<(&Size, &mut Transform), With<Tile>>,
|
||||
) {
|
||||
for (sprite_size, mut transform) in q.iter_mut() {
|
||||
transform.scale = Vec3::new(
|
||||
sprite_size.width / matrix.width as f32 * window.width(),
|
||||
sprite_size.height / matrix.height as f32 * window.height(),
|
||||
1.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn post_translate_tiles(
|
||||
window: Single<&Window>,
|
||||
matrix: Res<Matrix>,
|
||||
mut q: Query<(&Position, &mut Transform), With<Tile>>,
|
||||
) {
|
||||
// We subtract half the window width because our coordinate system starts at the bottom left, and
|
||||
// Translation starts from the center. We then add half the size of a single tile, because we want
|
||||
// our sprites bottom left corner to be at the bottom left of a tile, not the center.
|
||||
fn convert(pos: f32, bound_window: f32, bound_game: f32) -> f32 {
|
||||
let tile_size = bound_window / bound_game;
|
||||
pos / bound_game * bound_window - (bound_window / 2.) + (tile_size / 2.)
|
||||
}
|
||||
|
||||
for (pos, mut transform) in q.iter_mut() {
|
||||
transform.translation = Vec3::new(
|
||||
convert(pos.x as f32, window.width(), matrix.width as f32),
|
||||
convert(pos.y as f32, window.height(), matrix.height as f32),
|
||||
pos.z as f32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_tetrominos(
|
||||
tetrominos: Query<(&Tetromino, &mut Children)>,
|
||||
mut positions: Query<&mut Position, With<Tile>>,
|
||||
) {
|
||||
for (t, children) in tetrominos.iter() {
|
||||
for child in children.iter() {
|
||||
let mut p = positions.get_mut(*child).unwrap();
|
||||
p.x += t.pos.x;
|
||||
p.y += t.pos.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, Reflect)]
|
||||
struct TetrominoKind([[u32; 2]; 4]);
|
||||
|
||||
const BRICK_I: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [3, 0]]);
|
||||
const BRICK_J: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [2, 1]]);
|
||||
const BRICK_L: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [0, 1]]);
|
||||
const BRICK_O: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [0, 1], [1, 1]]);
|
||||
const BRICK_S: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [1, 1], [2, 1]]);
|
||||
const BRICK_T: TetrominoKind = TetrominoKind([[0, 0], [1, 0], [2, 0], [1, 1]]);
|
||||
const BRICK_Z: TetrominoKind = TetrominoKind([[0, 1], [1, 1], [1, 0], [2, 0]]);
|
||||
|
||||
enum RenderLayer {
|
||||
Background = 0,
|
||||
Brick = 1,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
struct Tile;
|
||||
|
||||
#[derive(Bundle, Debug)]
|
||||
struct TileBundle {
|
||||
position: Position,
|
||||
size: Size,
|
||||
sprite: Sprite,
|
||||
tile: Tile,
|
||||
}
|
||||
|
||||
fn spawn_tile(commands: &mut Commands, color: Color, size: f32, position: Position) -> Entity {
|
||||
commands
|
||||
.spawn(TileBundle {
|
||||
position,
|
||||
size: Size::square(size),
|
||||
sprite: Sprite {
|
||||
color,
|
||||
..Default::default()
|
||||
},
|
||||
tile: Tile,
|
||||
})
|
||||
.id()
|
||||
}
|
||||
|
||||
#[derive(Component, Reflect)]
|
||||
struct Tetromino {
|
||||
pos: Position,
|
||||
kind: TetrominoKind,
|
||||
}
|
||||
|
||||
fn spawn_tetromino(commands: &mut Commands, kind: TetrominoKind, x: u32, y: u32) {
|
||||
let tetromino = commands
|
||||
.spawn(Tetromino {
|
||||
pos: Position { x, y, z: 0 },
|
||||
kind: kind.clone(),
|
||||
})
|
||||
.insert((Transform::default(), Visibility::default()))
|
||||
.id();
|
||||
|
||||
for coord in kind.0 {
|
||||
let e = spawn_tile(
|
||||
commands,
|
||||
Color::srgb(0.3, 0.3, 0.8),
|
||||
0.9,
|
||||
Position {
|
||||
x: x + coord[0],
|
||||
y: y + coord[1],
|
||||
z: RenderLayer::Brick as u32,
|
||||
},
|
||||
);
|
||||
commands.entity(e).set_parent(tetromino);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = App::new();
|
||||
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
title: "Tetris".to_string(),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
}));
|
||||
|
||||
app.add_systems(
|
||||
Startup,
|
||||
(init_singletons, init_window, init_tile_grid).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
PostUpdate,
|
||||
(translate_tetrominos, post_scale_tiles, post_translate_tiles).chain(),
|
||||
);
|
||||
|
||||
app.add_plugins(debug_plugin::debug_plugin);
|
||||
|
||||
app.register_type::<Position>();
|
||||
app.register_type::<Tetromino>();
|
||||
app.register_type::<Size>();
|
||||
|
||||
// Run the app
|
||||
app.run();
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct Score(u32);
|
||||
|
||||
#[derive(Resource, Copy, Clone)]
|
||||
struct Matrix {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn init_singletons(mut commands: Commands) {
|
||||
let matrix = Matrix {
|
||||
height: 15,
|
||||
width: 15,
|
||||
};
|
||||
commands.insert_resource(Score(0));
|
||||
commands.insert_resource(matrix);
|
||||
|
||||
commands.spawn(Camera2d {});
|
||||
}
|
||||
|
||||
fn init_window(matrix: Res<Matrix>, mut window: Single<&mut Window>) {
|
||||
const SCALE_FACTOR: f32 = 77.;
|
||||
|
||||
window.resolution.set(
|
||||
matrix.width as f32 * SCALE_FACTOR,
|
||||
matrix.height as f32 * SCALE_FACTOR,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct Grid;
|
||||
|
||||
fn init_tile_grid(mut commands: Commands, matrix: Res<Matrix>) {
|
||||
let grid = commands
|
||||
.spawn(Grid)
|
||||
.insert(Name::new("Background Grid"))
|
||||
.insert((Transform::default(), Visibility::default()))
|
||||
.id();
|
||||
|
||||
for y in 0..matrix.height {
|
||||
for x in 0..matrix.width {
|
||||
let color = match (y + x) % 2 == 0 {
|
||||
true => Color::srgb(0.5, 0.5, 0.5),
|
||||
false => Color::srgb(0.55, 0.55, 0.55),
|
||||
};
|
||||
let e = spawn_tile(
|
||||
&mut commands,
|
||||
color,
|
||||
1.0,
|
||||
Position {
|
||||
x,
|
||||
y,
|
||||
z: RenderLayer::Background as u32,
|
||||
},
|
||||
);
|
||||
commands.entity(e).set_parent(grid);
|
||||
}
|
||||
}
|
||||
test_render_all_tetrominos(commands);
|
||||
}
|
||||
|
||||
fn test_render_all_tetrominos(mut commands: Commands) {
|
||||
spawn_tetromino(&mut commands, BRICK_I, 0, 0);
|
||||
spawn_tetromino(&mut commands, BRICK_T, 4, 0);
|
||||
spawn_tetromino(&mut commands, BRICK_J, 8, 0);
|
||||
spawn_tetromino(&mut commands, BRICK_L, 12, 0);
|
||||
|
||||
spawn_tetromino(&mut commands, BRICK_O, 0, 4);
|
||||
spawn_tetromino(&mut commands, BRICK_S, 4, 4);
|
||||
spawn_tetromino(&mut commands, BRICK_Z, 8, 4);
|
||||
spawn_tetromino(&mut commands, BRICK_J, 12, 4);
|
||||
todo!();
|
||||
}
|
||||
|
Reference in New Issue
Block a user