Merge remote-tracking branch 'origin/master'

This commit is contained in:
mii
2021-12-30 23:12:19 +09:00
5 changed files with 84 additions and 33 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 mii8080
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.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# rustris
文化祭のために約 1 日で作成したテトリス風のゲーム。

View File

@ -14,7 +14,9 @@ pub struct GameData {
pub mino_rotation: MinoRotation, pub mino_rotation: MinoRotation,
pub field_size: (usize, usize), pub field_size: (usize, usize),
pub show_ghost: bool, pub show_ghost: bool,
pub hold_mino: Option<Mino> pub hold_mino: Option<Mino>,
pub score: i64,
pub game_speed: f32,
} }
impl GameData { impl GameData {
@ -91,7 +93,9 @@ impl GameData {
mino_rotation: MinoRotation::Up, mino_rotation: MinoRotation::Up,
field_size, field_size,
show_ghost, show_ghost,
hold_mino: None hold_mino: None,
score: 0,
game_speed: 0.5,
} }
} }
} }

View File

@ -5,9 +5,9 @@ mod rustris;
mod mino_rotation; mod mino_rotation;
mod game_status; mod game_status;
mod super_rotation; mod super_rotation;
use std::{io::stdout, process::exit, sync::{Arc, Mutex}, thread, time::Duration}; use std::{io::stdout, sync::{Arc, Mutex}, thread, time::Duration};
use crossterm::{cursor, event::{Event, KeyCode, KeyEvent, KeyModifiers, read}, execute, style::{Color, Print, ResetColor, SetBackgroundColor, SetForegroundColor}, terminal::{self, Clear, ClearType, enable_raw_mode}}; use crossterm::{cursor, event::{Event, KeyCode, KeyEvent, KeyModifiers, read}, execute, style::{Color, Print, ResetColor, SetBackgroundColor}, terminal::{self, Clear, ClearType, enable_raw_mode}};
use game_data::GameData; use game_data::GameData;
use game_status::GameStatus; use game_status::GameStatus;
use mino_rotation::MinoRotation; use mino_rotation::MinoRotation;
@ -150,7 +150,12 @@ fn main() {
if *exit_flag_rc.lock().unwrap() { if *exit_flag_rc.lock().unwrap() {
break; break;
} }
thread::sleep(Duration::from_secs_f32(0.5)); let mut game_speed = 0.5f32;
{
let rustris_rc = rustris_rc.lock().unwrap();
game_speed = rustris_rc.game_data.game_speed;
}
thread::sleep(Duration::from_secs_f32(game_speed));
{ {
let mut rustris_rc = rustris_rc.lock().unwrap(); let mut rustris_rc = rustris_rc.lock().unwrap();
if !rustris_rc.move_mino(1, 0) { if !rustris_rc.move_mino(1, 0) {
@ -162,6 +167,8 @@ fn main() {
} else { } else {
rustris_rc.place_control_mino(Block::Block); rustris_rc.place_control_mino(Block::Block);
rustris_rc.next_mino(); rustris_rc.next_mino();
rustris_rc.check_clear();
ground_flag = false; ground_flag = false;
*control_count_rc.lock().unwrap() = 0; *control_count_rc.lock().unwrap() = 0;
before_control_count = 0; before_control_count = 0;
@ -172,8 +179,9 @@ fn main() {
} }
} }
{ {
let mut rustris_rc = rustris_rc.lock().unwrap();
let mut stdout = stdout_rc.lock().unwrap(); let mut stdout = stdout_rc.lock().unwrap();
let buf = rustris_rc.lock().unwrap().show(); let buf = rustris_rc.show();
execute!(stdout, Print(buf)).unwrap() execute!(stdout, Print(buf)).unwrap()
} }
} }
@ -232,6 +240,7 @@ fn main() {
modifiers: KeyModifiers::NONE modifiers: KeyModifiers::NONE
}) => { }) => {
let mut rustris = rustris.lock().unwrap(); let mut rustris = rustris.lock().unwrap();
if let Some(holding) = rustris.game_data.hold_mino.clone() { if let Some(holding) = rustris.game_data.hold_mino.clone() {
let control_tmp = rustris.game_data.control_mino.clone(); let control_tmp = rustris.game_data.control_mino.clone();
rustris.game_data.control_mino = Some(holding); rustris.game_data.control_mino = Some(holding);
@ -273,29 +282,7 @@ fn main() {
{ {
let mut rustris = rustris.lock().unwrap(); let mut rustris = rustris.lock().unwrap();
for x in 0..(rustris.game_data.field_size.1) { rustris.check_clear();
let mut air = false;
for y in 0..(rustris.game_data.field_size.0) {
if let Block::Air = rustris.game_data.field[x][y] {
air = true;
}
}
if !air {
for y in 0..(rustris.game_data.field_size.0) {
rustris.game_data.field[x][y] = Block::Air;
}
for x2 in (0..(rustris.game_data.field_size.1)).rev() {
if x2 < x && x2 < 20 {
for y2 in 0..(rustris.game_data.field_size.0) {
rustris.game_data.field[x2 + 1][y2] = rustris.game_data.field[x2][y2];
rustris.game_data.field[x2][y2] = Block::Air;
}
}
}
}
}
} }
{ {
@ -317,6 +304,11 @@ fn main() {
cursor::MoveTo(console_size.0 / 2, console_size.1 / 2), cursor::MoveTo(console_size.0 / 2, console_size.1 / 2),
Print("Game Over") Print("Game Over")
).unwrap(); ).unwrap();
execute!(
stdout,
cursor::MoveTo(console_size.0 / 2, console_size.1 / 2 + 1),
Print(format!("Score : {}", rustris.game_data.score))
).unwrap();
thread::sleep(Duration::from_secs(3)); thread::sleep(Duration::from_secs(3));
@ -343,7 +335,7 @@ fn main() {
} }
*exit_flag.lock().unwrap() = true; *exit_flag.lock().unwrap() = true;
frame_thread.join(); frame_thread.join().unwrap();
main(); main();
} }

View File

@ -6,12 +6,44 @@ use crate::{block::Block, game_data::*, game_status::GameStatus, mino::Mino, min
#[derive(Debug)] #[derive(Debug)]
pub struct Rustris { pub struct Rustris {
pub game_data: GameData, pub game_data: GameData,
pub game_status: GameStatus pub game_status: GameStatus,
pub t_spin: bool,
} }
impl Rustris { impl Rustris {
pub fn new(game_data: GameData) -> Rustris { pub fn new(game_data: GameData) -> Rustris {
Rustris { game_data, game_status: GameStatus::Playing } Rustris { game_data, game_status: GameStatus::Playing, t_spin: false }
}
pub fn check_clear(&mut self) {
let mut clear_lines = 0;
for x in 0..(self.game_data.field_size.1) {
let mut air = false;
for y in 0..(self.game_data.field_size.0) {
if let Block::Air = self.game_data.field[x][y] {
air = true;
}
}
if !air {
clear_lines += 1;
for y in 0..(self.game_data.field_size.0) {
self.game_data.field[x][y] = Block::Air;
}
for x2 in (0..(self.game_data.field_size.1)).rev() {
if x2 < x && x2 < 20 {
for y2 in 0..(self.game_data.field_size.0) {
self.game_data.field[x2 + 1][y2] = self.game_data.field[x2][y2];
self.game_data.field[x2][y2] = Block::Air;
}
}
}
}
}
self.game_data.score += clear_lines * 100;
self.game_data.game_speed += 0.01 * clear_lines as f32;
} }
pub fn get_next_mino(&mut self) -> Mino { pub fn get_next_mino(&mut self) -> Mino {
@ -205,7 +237,7 @@ impl Rustris {
print_buffer += "\n"; print_buffer += "\n";
} }
} }
print_buffer += "     Z ホールド, X 左回転, C 右回転\n"; print_buffer += &format!("     Z ホールド, X 左回転, C 右回転 score: {}\n", self.game_data.score);
for _ in 0..(if (console_size.1 - print_buffer.lines().count() as u16) > 0 { console_size.1 - print_buffer.lines().count() as u16 - 1 } else { console_size.1 - print_buffer.lines().count() as u16 }) { for _ in 0..(if (console_size.1 - print_buffer.lines().count() as u16) > 0 { console_size.1 - print_buffer.lines().count() as u16 - 1 } else { console_size.1 - print_buffer.lines().count() as u16 }) {
print_buffer += "\n"; print_buffer += "\n";