俄罗斯方块----Ubuntu终端游戏
来源:互联网 发布:网络格斗游戏排行 编辑:程序博客网 时间:2024/05/16 06:08
我最近在看C++和linux,为了能够更加牢靠的掌握自己的学到的知识,所以采用写小游戏的方法来帮助自己巩固学习。在这篇代码中我用到的C++和linux知识有:
C++知识:
1. 类的创建
2. 内联函数
3. pthread线程
linux知识:
1. 进入root模式
2. 给文件增加权限
3. 查看和使用系统的外设
有三点要特别说明:
1. 本代码不适用于所有linux系统,如果照搬的话可能会运行失败。如果要保证此代码编译的程序能在另一台机器上运行,需要先查看该机器的键盘是对应哪一个event文件,并将代码中的打开event文件的名称改掉。
2. 因为打开event文件需要很高的权限,所以需要在root模式下运行
3. 要编译此程序需要在链接是加入pthread库,即编译时需要g++ -lpthread *.cpp
具体代码如下:
RussiaBlock.h#ifndef RUSSIA_BLOCK_H#define RUSSIA_BLOCK_H#include <iostream>#include <ctime>#include <stdexcept>#include <unistd.h>#include <pthread.h>#include <cstdlib>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/select.h>#include <errno.h>#include <linux/input.h>using namespace std;typedef struct Pos{ unsigned char x; unsigned char y;} Pos;typedef struct Block{ Pos pos[4]; bool Droping; short shape;} Block;class RussiaBlock{ private: enum {TIAN_BLOCK=0,L_BLOCK,T_BLOCK,FL_BLOCK,I_BLOCK,HI_BLOCK,Z_BLOCK,FZ_BLOCK}; bool gameFail; bool dropToEnd; bool Rotating; unsigned int score; unsigned char screenWidth; unsigned char screenHeight; Block currentBlock; Block nextBlock; unsigned char map[100][100]; public: void GameStart(void); //开始游戏 RussiaBlock(unsigned char, unsigned char = 80); private: Block TianBlock(void); //田型方块 void FailNotice(void); //游戏失败提示 Block LBlock(void); //L型方块 void KeyOperate(void); //按键操作 void ShowScreen(void); //显示游戏区域 Block CreatNewBlock(void); //创建一个新的方块 void ShowNextBlock(void); //显示下一个方块提示 private: Block TBlock(); //T型方块 Block FLBlock(); //反L型方块 Block IBlock(); //I型方块 Block HIBlock(); //横I型方块 Block ZBlock(); //Z型方块 Block FZBlock(); //反Z型方块 void AutoDrop(void *); //自动下降线程 static void *Thread_func(void *); static void *Thread_Key(void *); void MoveRight(); //右移 void MoveLeft(); //左移 void DropEnd(); //下降到底 void RotateBlock(); //旋转方块 void DeleteLines(); //清除游戏区域内多行内容 bool DropOneLine(); //下降一行 void DeleteOneLine(); //删除一行 bool AtTheEnd(); //判断是否在可降落的最低点 inline bool ThisLineIsFull(int index) { for(int i=0;i<screenWidth;i++) { if(map[i][index] == 0) return false; } return true; } inline void DeleteOneLine(int index) { for(int i=index;i>0;i--) { for(int j=0;j<screenWidth;j++) { map[j][i] = map[j][i-1]; } } for(int j=0;j<screenWidth;j++) { map[j][0] = 0; } }};#endif
RussiaBlock.cpp#include "RussiaBlock.h"#include <iostream>using namespace std;RussiaBlock::RussiaBlock(unsigned char width, unsigned char height){ gameFail = false; screenWidth = width; screenHeight= height; score = 0; for(int i=0;i != 100;i++) for(int j=0;j!=100;j++) { map[i][j] = 0; } srand(time(0)); nextBlock = CreatNewBlock(); Rotating = false;}Block RussiaBlock::CreatNewBlock(void){ short blockShape = 0; blockShape = (short)(rand()%8); Block newBlock; switch(blockShape) { case 0: newBlock = TianBlock();break; case 1: newBlock = LBlock();break; case 2: newBlock = TBlock();break; case 3: newBlock = FLBlock();break; case 4: newBlock = IBlock();break; case 5: newBlock = HIBlock();break; case 6: newBlock = ZBlock();break; case 7: newBlock = FZBlock();break; } newBlock.shape = blockShape; return newBlock;}void RussiaBlock::ShowScreen(){ system("clear"); for(int i=0;i<screenWidth+2;i++) cout << "_"; cout <<endl; for(int i(0);i<screenHeight;i++) { cout << "|"; for(int j(0);j<screenWidth;j++) { if(map[j][i] == 0) cout<<" "; else if(map[j][i] == 1 || map[j][i] == 2) cout<<"#"; else cout<<map[j][i]; } cout << "|"; cout<<endl; } for(int i=0;i<screenWidth+2;i++) cout << "-" ; cout << endl; ShowNextBlock(); cout << "score:" << score<<endl;}void RussiaBlock::ShowNextBlock(void){ bool have = false; for(int r=0;r<4;r++) { for(int c=0;c<4;c++) { have = false; for(int blk=0;blk<4;blk++) { if(nextBlock.pos[blk].x == c&& nextBlock.pos[blk].y == r) { have = true; cout << "#"; } } if(have==false) cout<<" "; } cout << endl; }}void RussiaBlock::GameStart(void){ pthread_t id_auto,id_key; try { int ret = pthread_create(&id_auto,NULL,&Thread_func,this); if(ret != 0) throw runtime_error("start game fail"); ret = pthread_create(&id_key,NULL,&Thread_Key,this); if(ret != 0) throw runtime_error("start game fail"); } catch(runtime_error err) { cout << err.what() <<endl; return; } gameFail = false; while(!gameFail) { dropToEnd = false; currentBlock = nextBlock; nextBlock = CreatNewBlock(); for(int i=0;i<4;i++) { currentBlock.pos[i].x += (screenWidth/2); map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1; } while(!dropToEnd) { if(AtTheEnd()) { dropToEnd = true; for(int i=0;i<4;i++) map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 2; DeleteLines(); } } for(int i=0;i<screenWidth;i++) { if(map[i][0] == 2) { gameFail = true; break; } } } pthread_join(id_auto,NULL); pthread_join(id_key,NULL); FailNotice();}bool RussiaBlock::AtTheEnd(void){ for(int i=0;i<4;i++) { if(map[currentBlock.pos[i].x][currentBlock.pos[i].y + 1] == 2|| currentBlock.pos[i].y ==screenHeight - 1) return true; } return false;}void RussiaBlock::FailNotice(void){ string failStr("Game Over!"); for(int i=0;i!=failStr.size();i++) { map[i][screenHeight/2] = failStr[i]; } ShowScreen();}void RussiaBlock::KeyOperate(void){ struct input_event ev_key; int btn_fd = open("/dev/input/event3",O_RDWR); if(btn_fd < 0) { cerr << btn_fd <<endl; cerr << "Game initial fail!" << endl; return; } while(!gameFail) { int count = read(btn_fd,&ev_key,sizeof(struct input_event)); //for(int i=0;i<(int)count/sizeof(struct input_event);i++) if(EV_KEY == ev_key.type && ev_key.value == 1) { switch(ev_key.code) { case KEY_A:MoveLeft();break; case KEY_S:DropEnd();break; case KEY_D:MoveRight();break; case KEY_W:RotateBlock();break; } } ShowScreen(); } close(btn_fd);}void RussiaBlock::DeleteLines(void){ for(int i=0;i<screenHeight;i++) { if(ThisLineIsFull(i)) { DeleteOneLine(i); score++; } }}void RussiaBlock::DropEnd(void){ bool getEnd = false; while(1) { for(int i=0;i<4;i++) { if(map[currentBlock.pos[i].x][currentBlock.pos[i].y + 1] == 2|| currentBlock.pos[i].y ==screenHeight - 1) { getEnd = true; break; } } if(!getEnd) { for(int i=0;i<4;i++) { map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 0; currentBlock.pos[i].y++; map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1; } } else break; }}void RussiaBlock::MoveRight(void){ for(int i=0;i<4;i++) { if(currentBlock.pos[i].x + 1 == screenWidth || map[currentBlock.pos[i].x+1][currentBlock.pos[i].y] == 2) { return ; } } for(int i=0;i<4;i++) { map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 0; currentBlock.pos[i].x++; } for(int i=0;i<4;i++) map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1;}void RussiaBlock::MoveLeft(void){ for(int i=0;i<4;i++) { if(currentBlock.pos[i].x - 1 < 0 || map[currentBlock.pos[i].x-1][currentBlock.pos[i].y] == 2) { return ; } } for(int i=0;i<4;i++) { map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 0; currentBlock.pos[i].x--; map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1; }}void RussiaBlock::RotateBlock(void){ short blockShape = currentBlock.shape; if(blockShape == TIAN_BLOCK) return; if(blockShape == I_BLOCK) { Pos pos[4] = {0}; for(int i=0;i<4;i++) { pos[i].y = currentBlock.pos[2].y; pos[i].x = currentBlock.pos[2].x + i-1; } for(int i=0;i<4;i++) { if(map[pos[i].x][pos[i].y] == 2 || pos[i].y >= screenHeight || pos[i].y < 0 || pos[i].x >= screenWidth || pos[i].x < 0) return ; } for(int i=0;i<4;i++) { map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 0; currentBlock.pos[i] = pos[i]; map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1; } currentBlock.shape = HI_BLOCK; return ; } if(blockShape == HI_BLOCK) { Pos pos[4] = {0}; for(int i=0;i<4;i++) { pos[i].x = currentBlock.pos[1].x; pos[i].y = currentBlock.pos[1].y + i-1; } for(int i=0;i<4;i++) { if(map[pos[i].x][pos[i].y] == 2 || pos[i].y >= screenHeight || pos[i].y < 0 || pos[i].x >= screenWidth || pos[i].x < 0) return ; } for(int i=0;i<4;i++) { map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 0; currentBlock.pos[i] = pos[i]; map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1; } currentBlock.shape = I_BLOCK; return ; } unsigned char maxX = currentBlock.pos[0].x,maxY = currentBlock.pos[0].y,minX = currentBlock.pos[0].x, minY = currentBlock.pos[0].y; for(int i=1;i<4;i++) { if(maxX < currentBlock.pos[i].x) maxX = currentBlock.pos[i].x; if(minX > currentBlock.pos[i].x) minX = currentBlock.pos[i].x; if(maxY < currentBlock.pos[i].y) maxY = currentBlock.pos[i].y; if(minY > currentBlock.pos[i].y) minY = currentBlock.pos[i].y; } unsigned char X = ((maxX-minX) == 2)?maxX-1:maxX; unsigned char Y = ((maxY-minY) == 2)?maxY-1:maxY; unsigned char arr[3][3] = {0}; short arrX=0,arrY=0; for(int i=Y-1;i<=Y+1;i++) { arrX = 0; for(int j=X-1;j<=X+1;j++) { arr[arrX++][arrY] = map[j][i]; if(map[j][i] == 2) return ; } arrY++; } //转置并换行 for(int i=0;i<3;i++) { for(int j = 0;j<=i;j++) { unsigned char temp = arr[j][i]; arr[j][i] = arr[i][j]; arr[i][j] = temp; } } for(int j=0;j<3;j++) { unsigned char temp = arr[j][0]; arr[j][0] = arr[j][2]; arr[j][2] = temp; } arrY = 0; int index = 0; for(int i=Y-1;i<=Y+1;i++) { arrX = 0; for(int j=X-1;j<=X+1;j++) { map[j][i] = arr[arrX++][arrY]; if(map[j][i] == 1) { currentBlock.pos[index].x = j; currentBlock.pos[index++].y = i; } } arrY++; }}Block RussiaBlock::TianBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 1; NewBlock.pos[1].y = 0; NewBlock.pos[2].x = 0; NewBlock.pos[2].y = 1; NewBlock.pos[3].x = 1; NewBlock.pos[3].y = 1; return NewBlock;}Block RussiaBlock::LBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 0; NewBlock.pos[1].y = 1; NewBlock.pos[2].x = 0; NewBlock.pos[2].y = 2; NewBlock.pos[3].x = 1; NewBlock.pos[3].y = 2; return NewBlock;}Block RussiaBlock::TBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 1; NewBlock.pos[1].y = 0; NewBlock.pos[2].x = 2; NewBlock.pos[2].y = 0; NewBlock.pos[3].x = 1; NewBlock.pos[3].y = 1; return NewBlock;}Block RussiaBlock::FLBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 1; NewBlock.pos[1].y = 0; NewBlock.pos[2].x = 2; NewBlock.pos[2].y = 0; NewBlock.pos[3].x = 2; NewBlock.pos[3].y = 1; return NewBlock;}Block RussiaBlock::IBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 0; NewBlock.pos[1].y = 1; NewBlock.pos[2].x = 0; NewBlock.pos[2].y = 2; NewBlock.pos[3].x = 0; NewBlock.pos[3].y = 3; return NewBlock;}Block RussiaBlock::HIBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 1; NewBlock.pos[1].y = 0; NewBlock.pos[2].x = 2; NewBlock.pos[2].y = 0; NewBlock.pos[3].x = 3; NewBlock.pos[3].y = 0; return NewBlock;}Block RussiaBlock::ZBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 0; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 1; NewBlock.pos[1].y = 0; NewBlock.pos[2].x = 1; NewBlock.pos[2].y = 1; NewBlock.pos[3].x = 2; NewBlock.pos[3].y = 1; return NewBlock;}Block RussiaBlock::FZBlock(void){ Block NewBlock = {0}; NewBlock.pos[0].x = 1; NewBlock.pos[0].y = 0; NewBlock.pos[1].x = 2; NewBlock.pos[1].y = 0; NewBlock.pos[2].x = 0; NewBlock.pos[2].y = 1; NewBlock.pos[3].x = 1; NewBlock.pos[3].y = 1; return NewBlock;}void *RussiaBlock::Thread_func(void *param){ RussiaBlock *p = (RussiaBlock *)param; p->AutoDrop(NULL);}void RussiaBlock::AutoDrop(void *ptr){ while(!gameFail) { int tim = time(0); while(tim == time(0)) ; DropOneLine(); ShowScreen(); }}bool RussiaBlock::DropOneLine(void){ for(int i=0;i<4;i++) { if(map[currentBlock.pos[i].x][currentBlock.pos[i].y + 1] ==2 ||currentBlock.pos[i].y == screenHeight -1) { return false; } } for(int i=0;i<4;i++) { map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 0; currentBlock.pos[i].y++; } for(int i=0;i<4;i++) map[currentBlock.pos[i].x][currentBlock.pos[i].y] = 1; return true;}void *RussiaBlock::Thread_Key(void *param){ RussiaBlock *p = (RussiaBlock *)param; p->KeyOperate();}
main.cpp#include <iostream>#include "RussiaBlock.h"using namespace std;int main(){ RussiaBlock blk(10,10); blk.GameStart(); return 0;}
makefileRussiaBlock: main.o RussiaBlock.o g++ -lpthread main.o RussiaBlock.o -o RussiaBlockmain.o: main.cpp RussiaBlock.h g++ -c main.cppRussiaBlock.o: RussiaBlock.cpp g++ -c RussiaBlock.cpp
0 0
- 俄罗斯方块----Ubuntu终端游戏
- 终端下的俄罗斯方块游戏tetris
- 坦克大战----Ubuntu终端游戏
- 俄罗斯方块游戏
- 俄罗斯方块游戏
- 俄罗斯方块游戏
- 俄罗斯方块游戏
- Ubuntu下用shell脚本实现俄罗斯方块游戏
- 一个俄罗斯方块游戏源程序
- [JAVA] 俄罗斯方块游戏
- [JAVA] 俄罗斯方块游戏
- 一个俄罗斯方块游戏
- [JAVA] 俄罗斯方块游戏
- javascript游戏-- 俄罗斯方块 源代码
- 【游戏】JavaScript 版俄罗斯方块
- javascript游戏-- 俄罗斯方块 源代码
- 俄罗斯方块游戏java代码
- 裸机游戏篇--俄罗斯方块
- Android 支付宝 微信 银联 支付
- 【Python学习笔记】递归函数
- NYOJ_349 Sorting It All Out 拓扑排序
- UVA 122 Trees on the level 二叉树
- JUnit4:多组数据的单元测试
- 俄罗斯方块----Ubuntu终端游戏
- POJ 3253 Fence Repair(贪心 + 优先队列)
- UVA - 11995 I Can Guess the Data Structure! 猜猜数据结构(STL模拟)
- 【Unity Shader编程】之十五 屏幕高斯模糊(Gaussian Blur)后期特效的实现
- 自定义ViewGroup容器,实现自动换行的流式布局的效果
- PyUnicodeUCS2*问题解决
- 剑指offer面试题7:用两个栈实现队列
- bash_history 和 mysql_history
- 调试中关于__FILE__, __LINE__ 及 __FUNCTION__ 用法