目录
- 一、项目介绍
- 二、编译运行
- 1、编译过程
- 2、所需文件
一、项目介绍
俄罗斯方块:顾名思义,俄罗斯方块自然是俄罗斯人发明的。这人叫阿列克谢·帕基特诺夫(Алексей Пажитнов 英文:Alexey Pazhitnov)。俄罗斯方块原名是俄语Тетрис(英语是Tetris),这个名字来源于希腊语tetra,意思是“四”,而游戏的作者最喜欢网球(tennis)。于是,他把两个词tetra和tennis合而为一,命名为Tetris,这也就是俄罗斯方块名字的由来。
该项目全部由c++编码实现,代码一共不到200,实现了基础的玩法,项目原地址https://github.com/taylorconor/tinytetris。
逛了一圈GitHub,突然发现了个小巧有意思的游戏,没忍住就给拉取下来编译了一把,分分钟就能玩上童年记忆!这不比博人传热血?
二、编译运行
1、编译过程
- centos环境:
第一步,安装g++编译环境
yum install gcc-c++
第二步,安装编译依赖第三方库
yum install ncurses-devel
第三步,编译生成可执行文件
make
第四步,玩
./tinytetris-commented
2、所需文件
- tinytetris-commented.cpp
#include <ctime>
#include <curses.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
// block layout is: {w-1,h-1}{x0,y0}{x1,y1}{x2,y2}{x3,y3} (two bits each)
int x = 431424, y = 598356, r = 427089, px = 247872, py = 799248, pr,
c = 348480, p = 615696, tick, board[20][10],
block[7][4] = {{x, y, x, y},
{r, p, r, p},
{c, c, c, c},
{599636, 431376, 598336, 432192},
{411985, 610832, 415808, 595540},
{px, py, px, py},
{614928, 399424, 615744, 428369}},
score = 0;
// extract a 2-bit number from a block entry
int NUM(int x, int y) { return 3 & block[p][x] >> y; }
// create a new piece, don't remove old one (it has landed and should stick)
void new_piece() {
y = py = 0;
p = rand() % 7;
r = pr = rand() % 4;
x = px = rand() % (10 - NUM(r, 16));
}
// draw the board and score
void frame() {
for (int i = 0; i < 20; i++) {
move(1 + i, 1); // otherwise the box won't draw
for (int j = 0; j < 10; j++) {
board[i][j] && attron(262176 | board[i][j] << 8);
printw(" ");
attroff(262176 | board[i][j] << 8);
}
}
move(21, 1);
printw("Score: %d", score);
refresh();
}
// set the value fo the board for a particular (x,y,r) piece
void set_piece(int x, int y, int r, int v) {
for (int i = 0; i < 8; i += 2) {
board[NUM(r, i * 2) + y][NUM(r, (i * 2) + 2) + x] = v;
}
}
// move a piece from old (p*) coords to new
int update_piece() {
set_piece(px, py, pr, 0);
set_piece(px = x, py = y, pr = r, p + 1);
}
// remove line(s) from the board if they're full
void remove_line() {
for (int row = y; row <= y + NUM(r, 18); row++) {
c = 1;
for (int i = 0; i < 10; i++) {
c *= board[row][i];
}
if (!c) {
continue;
}
for (int i = row - 1; i > 0; i--) {
memcpy(&board[i + 1][0], &board[i][0], 40);
}
memset(&board[0][0], 0, 10);
score++;
}
}
// check if placing p at (x,y,r) will be a collision
int check_hit(int x, int y, int r) {
if (y + NUM(r, 18) > 19) {
return 1;
}
set_piece(px, py, pr, 0);
c = 0;
for (int i = 0; i < 8; i += 2) {
board[y + NUM(r, i * 2)][x + NUM(r, (i * 2) + 2)] && c++;
}
set_piece(px, py, pr, p + 1);
return c;
}
// slowly tick the piece y position down so the piece falls
int do_tick() {
if (++tick > 30) {
tick = 0;
if (check_hit(x, y + 1, r)) {
if (!y) {
return 0;
}
remove_line();
new_piece();
} else {
y++;
update_piece();
}
}
return 1;
}
// main game loop with wasd input checking
void runloop() {
while (do_tick()) {
usleep(10000);
if ((c = getch()) == 'a' && x > 0 && !check_hit(x - 1, y, r)) {
x--;
}
if (c == 'd' && x + NUM(r, 16) < 9 && !check_hit(x + 1, y, r)) {
x++;
}
if (c == 's') {
while (!check_hit(x, y + 1, r)) {
y++;
update_piece();
}
remove_line();
new_piece();
}
if (c == 'w') {
++r %= 4;
while (x + NUM(r, 16) > 9) {
x--;
}
if (check_hit(x, y, r)) {
x = px;
r = pr;
}
}
if (c == 'q') {
return;
}
update_piece();
frame();
}
}
// init curses and start runloop
int main() {
srand(time(0));
initscr();
start_color();
// colours indexed by their position in the block
for (int i = 1; i < 8; i++) {
init_pair(i, i, 0);
}
new_piece();
resizeterm(22, 22);
noecho();
timeout(0);
curs_set(0);
box(stdscr, 0, 0);
runloop();
endwin();
}
- Makefile
LDFLAGS=-lcurses
all: tinytetris-commented
clean:
rm -f tinytetris tinytetris-commented
❤️❤️❤️ 如果本文有点意思,请不要忘了点赞、关注、收藏哦!灰常感谢! ❤️❤️❤️