Tetris(俄罗斯方块)

news/2024/10/18 22:35:13/

一天有个小朋友问我OpenGL俄罗斯方块怎么写。
俄罗斯方块分成两部分游戏逻辑和画面渲染.

1. 游戏逻辑

一个简单的俄罗斯方块的逻辑部分需要考虑的情况如下:

1. 方块的表示(坐标, 旋转, 上下左右移动) 
2. 格子的状态记录, 移动中的方块和边界的碰撞检测和已固定的方块的碰撞检测
3. 行满检测与消除

具体的面向对象实现如下:

class Game{
public:int tiles[20][10] = {0};void new_tile() {tile << 5, 0, random()%7, random()%4;}void write_tile() {if(!running || !started) return ;for(int i = 0 ; i < 4; i++) {tiles[tile[1]+tileMap[tile[2]][tile[3]][i][1]][tile[0]+tileMap[tile[2]][tile[3]][i][0]] = tile[2] + 1;}}void wipe_tile() {if(!running || !started) return ;for(int i = 0 ; i < 4; i++) {tiles[tile[1]+tileMap[tile[2]][tile[3]][i][1]][tile[0]+tileMap[tile[2]][tile[3]][i][0]]  = 0;}}void rotation() {if(!running || !started) return ;tile[3] = (tile[3]+1)%4;for(int i = 0 ; i < 4; i++) {std::pair<int,int> pos= {tile[0]+tileMap[tile[2]][tile[3]][i][0],tile[1]+tileMap[tile[2]][tile[3]][i][1],};if(pos.first < 0 || pos.first >= 10 || pos.second >= 20 || tiles[pos.second][pos.first]) {tile[3] = (tile[3]+3)%4;break;}}}bool move(int x, int y, bool passive = false) {if(!running || !started) return true;tile[0] += x;tile[1] += y;for(int i = 0 ; i < 4; i++) {std::pair<int,int> pos= {tile[0]+tileMap[tile[2]][tile[3]][i][0],tile[1]+tileMap[tile[2]][tile[3]][i][1],};if(pos.first < 0 || pos.first >= 10 || pos.second >= 20 || tiles[pos.second][pos.first]) {tile[0] -= x; tile[1] -= y;if(passive) {write_tile();if(tile[1] != 0) new_tile();else {started = false; write_end(8);}}return false;}}check_row();return true;}void update() {if(!running || !started) return ;if(frame_cnt++ == 24) {wipe_tile();move(0,1,true);write_tile();frame_cnt = 0;}}void restart() {memset(tiles, 0, sizeof(int)*200);new_tile();started = true;running = true;}void resume_or_pause() {running = !running;}void write_end(int i = 8) {memset(tiles[std::max(i-1,0)], 0, 4*10*7);tiles[i+1][0] = tiles[i+3][0] = 1;tiles[i+0][0] = tiles[i+0][1] = tiles[i+0][2] = 1;tiles[i+2][0] = tiles[i+2][1] = tiles[i+2][2] = 1;tiles[i+4][0] = tiles[i+4][1] = tiles[i+4][2] = 1;tiles[i+0][3] = tiles[i+1][3] = tiles[i+2][3] = tiles[i+3][3] = tiles[i+4][3] = 2;tiles[i+0][6] = tiles[i+1][6] = tiles[i+2][6] = tiles[i+3][6] = tiles[i+4][6] = 2;tiles[i+1][4] = tiles[i+2][4] = tiles[i+2][5] = tiles[i+3][5] = 2;tiles[i+0][7] = tiles[i+1][7] = tiles[i+2][7] = tiles[i+3][7] = tiles[i+4][7] = 3;tiles[i+0][8] = tiles[i+4][8] = tiles[i+1][9] = tiles[i+2][9] = tiles[i+3][9] = 3;}Eigen::Vector4i tile; // (x, y, type, rotation)private:// 一个二维数组表示所有可能出现的方块和方向。static int tileMap[7][4][4][2];void check_row() {for(int i = 19, ii = 19; i >= 0; i--) {int tile_cnt = 0;for(int j = 0; j < 10; j++) tile_cnt += tiles[i][j] > 0;for(int j = 0; j < 10; j++) tiles[ii][j] = tiles[i][j] ;if(tile_cnt != 10) ii--;}}int frame_cnt = 0;bool running = false, started = false;
} game;int Game::tileMap[7][4][4][2] = {
{   0, 0, -1, 0,  1,  0,  -1, -1,    // "L"0, 1,  0,  0,  0,  -1, 1, -1,1, 1, -1, 0,  0,  0,  1,  0,-1, 1,  0,  1,  0,  0,  0,  -1},
{   0, 0, -1, -1, -1, 0,  0,  -1,    //"O"0, 0,  -1, -1, -1, 0,  0, -1,0, 0, -1, -1, -1, 0,  0,  -1,0,  0,  -1, -1, -1, 0,  0,  -1},
{   0, 0, 1,  0,  -1, 0,  -2, 0,    //"I"0, 0,  0,  -2, 0,  -1, 0, 1,0, 0, 1,  0,  -1, 0,  -2, 0,0,  0,  0,  -2, 0,  -1, 0,  1},
{   0, 0, 1,  0,  -1, -1, 0,  -1,    //"S"0, 0,  0,  1,  1,  0,  1, -1,0, 0, 1,  0,  -1, -1, 0,  -1,0,  0,  0,  1,  1,  0,  1,  -1},
{   0, 0, -1, 0,  1,  0,  1,  -1,    //"J"0, 0,  0,  1,  0,  -1, 1, 1,0, 0, 1,  0,  -1, 0,  -1, 1,0,  0,  0,  1,  0,  -1, -1, -1},
{   0, 0, -1, 0,  0,  -1, 1,  -1,    //"Z"0, -1, 0,  0,  1,  0,  1, 1,0, 0, -1, 0,  0,  -1, 1,  -1,0,  -1, 0,  0,  1,  0,  1,  1},
{   0, 0, 1,  0,  -1, 0,  0,  -1,    //"T"0, 0,  0,  1,  0,  -1, 1, 0,0, 0, 0,  1,  -1, 0,  1,  0,-1, 0,  0,  1,  0,  -1, 0,  0}
};

2. 渲染实现

对于渲染的要求,只使用一组着色器实现,即通过Uniform传所有格子的状态,具体如下:

// vertex shader
#version 330 core
in vec2 position;
out vec2 pos;
void main()
{pos = vec2(position.x*1.14,position.y*-1.09);gl_Position = vec4(position, 0.0, 1.0);
} ;// fragment shader
#version 330 core
out vec4 outColor;
in vec2 pos;
uniform int tile[200];
uniform sampler2D tileTex;
void main()
{vec2 border = smoothstep(-0.1, 0.0, -abs(sin(3.1415926*pos*vec2(5.0,10.0))));if(max(abs(pos.x),abs(pos.y))>1.002) {outColor.xyz = texture(tileTex,vec2(pos.x/2.28 + 0.5, 360.0/393.0*(pos.y/2.18 + 0.5 )) ).xyz;return;}int tile_id = int(floor(10.0*pos.y+10.0)/*xiconxi.github.io*/*10)+int(floor(5.0*pos.x+5.0));tile_id     = tile[tile_id<200&&tile_id>=0?tile_id:0];vec3 tile_color = texture(tileTex,vec2( (tile_id-1+mod(abs(pos.x*5),1.0))/7.0,360.0/393.0+33.0/393.0*mod(abs(pos.y*10.0), 1.0))).xyz;tile_color = tile_id == 0 ? vec3(0.55)*length(tile_color): tile_color;outColor.xyz = mix(tile_color ,vec3(0.0),max(border.x,border.y));
} ;  

总体渲染效果如下:

890213-20181129232659281-747041958.jpg

具体代码在Github::Tetris

转载于:https://www.cnblogs.com/xiconxi/p/10081377.html


http://www.ppmy.cn/news/394756.html

相关文章

俄罗斯方块进阶--AI俄罗斯方块

前文回顾&#xff1a; 致青春--Python实现俄罗斯方块 人工智能大火的今天&#xff0c;如果还是自己玩俄罗斯方块未免显得太LOW&#xff0c;为什么不对游戏升级&#xff0c;让机器自己去玩俄罗斯方块呢&#xff1f;有了这个想法之后利用周六周日两天的时间去搜集了大量的资料&…

俄罗斯方块代码

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include "pch.h" #include <iostream> #include <easyx.h> #include <conio.h> #include <time.h>/ // 定义常量、枚举量、结构体、全局变…

【牛掰】日本人制作汉字俄罗斯方块游戏,看哭一票中国人

俄罗斯方块对于各位玩家来说一定是童年难忘的记忆&#xff0c;一位日本大学生ARAMA在社交媒体发布了一段演示视频“汉字版俄罗斯方块”&#xff0c;在这个视频中&#xff0c;经典俄罗斯方块中的图形全部都替换成了汉字&#xff0c;游戏难度更加变态......公众号后台回复&#x…

Mac终端好玩的事情俄罗斯方块

很有儿时上学时候玩的味道&#xff1a;

俄罗斯方块(Tetris)

《俄罗斯方块》&#xff08;Tetris&#xff0c; 俄文&#xff1a;Тетрис&#xff09;是一款由俄罗斯人阿列克谢帕基特诺夫于1984年6月发明的休闲游戏。 我将其作为我课程设计的题目&#xff0c;重温程序设计的基础。由于课设时间有限&#xff0c;本想用OpenGL弄个3D效果的…

学生用计算机怎么玩俄罗斯方块,回忆小霸王童年 如何在电脑上玩俄罗斯方块环游记...

《俄罗斯方块环游记》11月3日最后一次开启远航测试&#xff0c;这是中国首款正版俄罗斯方块手游。很多小伙伴小时候应该都玩过俄罗斯方块&#xff0c;那么要如何在电脑上体验俄罗斯方块环游记呢&#xff1f;接下来小编就给大家带来俄罗斯方块环游记电脑版模拟器下载的教程&…

51 nod 1851 俄罗斯方块

1851 俄罗斯方块 基准时间限制&#xff1a;1 秒 空间限制&#xff1a;131072 KB 分值: 160 难度&#xff1a;6级算法题 玩过俄罗斯方块&#xff1f;那你知道俄罗斯方块共有七种吧&#xff08;其实只有五种&#xff09; 给一个黑白图&#xff0c;每次能将某些区域的格子黑白反转…

基于51单片机的俄罗斯方块游戏

俄罗斯方块游戏算法 请参考俄罗斯方块游戏的算法 1.概述 俄罗斯方块是一款风靡全球的益智游戏。它规则简单&#xff0c;容易上手&#xff0c;且游戏过程变化无穷&#xff0c;使用户在游戏中得到乐趣。  本设计是采用单片机来实现的智能俄罗斯方块游戏&#xff0c;该设计选用的…