❤️ 硬核玩游戏:200行代码给你整个俄罗斯方块 ❤️

Posted 哪吒要进厂啦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❤️ 硬核玩游戏:200行代码给你整个俄罗斯方块 ❤️相关的知识,希望对你有一定的参考价值。

一、项目介绍

俄罗斯方块:顾名思义,俄罗斯方块自然是俄罗斯人发明的。这人叫阿列克谢·帕基特诺夫(Алексей Пажитнов 英文: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

❤️❤️❤️ 如果本文有点意思,请不要忘了点赞、关注、收藏哦!灰常感谢! ❤️❤️❤️

以上是关于❤️ 硬核玩游戏:200行代码给你整个俄罗斯方块 ❤️的主要内容,如果未能解决你的问题,请参考以下文章

“恶意版”俄罗斯方块游戏火了,永远给你不想要的方块,世界纪录才消掉31行...

“恶意版”俄罗斯方块游戏火了,永远给你不想要的方块,世界纪录才消掉31行...

60行JavaScript代码俄罗斯方块

❤️俄罗斯方块游戏❤️,重温经典(C++详解版)

软件设计实战:基于Java的俄罗斯方块游戏完整版

1000行Python代码实现俄罗斯方块/扫雷/五子棋/贪吃蛇