Qt-俄罗斯方块
来源:互联网 发布:springmvc ajax json 编辑:程序博客网 时间:2024/05/01 16:40
头文件:
//Tetris.h#ifndef ELUOSIWIDGET_H#define ELUOSIWIDGET_H#include <QtGui/QWidget>#include <QPainter>#include <QPaintEvent>#include <QKeyEvent>#include <cstring>#include <ctime>#define REC_SIZE 25 //方块大小#define SCENE_W 16 //场景列数#define SCENE_H 10 //场景行数enum direction{UP,DOWN,LEFT,RIGHT,SPACE};typedef struct { int pos_x; //方块x坐标 int pos_y; //方块y坐标}REC_Point;class eluosiWidget : public QWidget{ Q_OBJECTsignals: void GameOver(); //游戏结束信号 void CurrentScore(int); //游戏当前分数public slots: void StartGame(); //游戏开始 void PlayGame(); //恢复游戏 void PauseGame(); //暂停游戏 void SetSpeed(int level);//设置速度等级 void SetHard(int level);//设置是否增加难度public: eluosiWidget(QWidget *parent = 0); //构造函数 ~eluosiWidget(); //析构函数 void weizhi(int x,int y,int tx,direction direct); //位置变换 void paintEvent(QPaintEvent *event); //场景绘制 void change(int x,int y,int num,int state); //方块变换 void clear(int x,int y,int num); //清除当前位置信息 void move(int hang,direction direct);//部分移动 void SetLevel();//设置难度等级protected: void timerEvent(QTimerEvent *event); //定时设置 void keyPressEvent(QKeyEvent *event); //键盘事件private: int scene_num[SCENE_W][SCENE_H];//场景数据 REC_Point rpoint[4]; //定义四个方块的位置 int REC_tx[2];//定义方块的图形 int timerid1,timerid2;//记录两个定时器id int speed_ms,fresh_ms;//speed_ms记录下落速度,fresh_ms设置窗体刷新速度 int score;//分数 bool Pauseflag;//暂停标志 bool Levelflag;//难度标志 int HardLevel;//难度等级};#endif // ELUOSIWIDGET_H
实现:
//Tetris.cpp#include "Tetris.h"int tx_code[][4]={{456,258,456,258},{142,142,142,142},{246,268,123,248},{128,467,289,346}, {238,146,278,469},{247,126,247,126},{269,234,269,234}};//图形代码eluosiWidget::eluosiWidget(QWidget *parent) : QWidget(parent){ this->resize(SCENE_H*REC_SIZE,SCENE_W*REC_SIZE); //设置窗口大小 StartGame(); //开始游戏}eluosiWidget::~eluosiWidget(){ ;}void eluosiWidget::StartGame() //初始化{ for(int i=0;i<SCENE_W;i++) //清空舞台信息 memset(scene_num[i],0,sizeof(int) * SCENE_H); score = 0; //分数初始化 speed_ms = 800;fresh_ms = 50;//设置下落速度和刷新速度 rpoint[0].pos_x = 1;rpoint[0].pos_y = SCENE_H/2;//设置主方块位置信息 srand(time(0));REC_tx[0] = rand()%7;REC_tx[1] = rand()%7;//随机出现第一个图形 change(rpoint[0].pos_x,rpoint[0].pos_y,tx_code[REC_tx[0]][0],2); Pauseflag = false;Levelflag=false; PlayGame(); //开始下落}void eluosiWidget::change(int x, int y, int num,int state) //设置本次位置信息{ int temp = num; for(int i=1;i<4;i++){ rpoint[i].pos_x=x-1+(num%10-1)/3;rpoint[i].pos_y=y-1+(num%10-1)%3; scene_num[rpoint[i].pos_x][rpoint[i].pos_y]=state; num = num/10; } scene_num[x][y]=state; rpoint[0].pos_x = x;rpoint[0].pos_y = y; if(258 == temp){ scene_num[x+2][y]=state;rpoint[2].pos_x=x+2;rpoint[2].pos_y=y; } else if(456 == temp){ scene_num[x][y+2]=state;rpoint[2].pos_x=x;rpoint[2].pos_y=y+2; }}void eluosiWidget::clear(int x, int y, int num) //清除上次位置信息{ if(258 == num) scene_num[x+2][y]=0; else if(456 == num) scene_num[x][y+2]=0; for(int i=0;i<3;i++){ scene_num[x-1+(num%10-1)/3][y-1+(num%10-1)%3]=0; num = num/10; } scene_num[x][y] =0;}void eluosiWidget::weizhi(int x,int y,int tx,direction direct){ //x,y是坐标,tx是7种形状,direct是方向 static int temp_tx;bool temp_flag; temp_flag = true; switch(direct){ case UP: //变换方块动作 for(int i=0;i<4;i++) //判断方块是否允许变换 temp_flag = temp_flag && rpoint[i].pos_y-1 >= 0 && rpoint[i].pos_x+1 < SCENE_W-1 && rpoint[i].pos_x+1 != 1 && rpoint[i].pos_y+1 < SCENE_H ; if(temp_flag){ //执行变换动作 clear(x,y,tx_code[tx][temp_tx++]);if(temp_tx >= 4) temp_tx = 0;change(x,y,tx_code[tx][temp_tx],2); }break; case DOWN://下移 for(int i=0;i<4;i++) //判断是否允许下移 temp_flag = temp_flag && scene_num[rpoint[i].pos_x+1][rpoint[i].pos_y] !=1 && scene_num[rpoint[i].pos_x][rpoint[i].pos_y] !=1 && rpoint[i].pos_x+1 < SCENE_W; if(temp_flag){ //执行下移动作 clear(x,y,tx_code[tx][temp_tx]);change(x+1,y,tx_code[tx][temp_tx],2); }else{ //落下后更改状态为静止 change(x,y,tx_code[tx][temp_tx],1); //判断是否满行 for(int i=0;i<SCENE_W;i++){ for(int j=0;j<SCENE_H;j++){ //将满行的信息消除 if(scene_num[i][j]==0) break; else if(j==SCENE_H-1){ move(i,DOWN);//从第i行开始整体下移 emit CurrentScore(score*10);break; } } } //判断是否结束游戏 if(scene_num[0][y] == 1){ killTimer(timerid1);killTimer(timerid2); emit GameOver();break; } //判断是否加难度 if(Levelflag){ SetLevel(); Levelflag=false; } //重新构造一个方块 rpoint[0].pos_x = 1;rpoint[0].pos_y = SCENE_H/2;//设置主方块位置信息 REC_tx[0]=REC_tx[1];//随机出现第一个图形 REC_tx[1] = rand()%7; change(rpoint[0].pos_x,rpoint[0].pos_y,tx_code[REC_tx[0]][0],2); temp_tx = 0; } break; case LEFT://左移 for(int i=0;i<4;i++) //判断是否允许左移 temp_flag = temp_flag && scene_num[rpoint[i].pos_x][rpoint[i].pos_y-1] !=1 && rpoint[i].pos_y-1 >=0; if(temp_flag){ //执行左移动作 clear(x,y,tx_code[tx][temp_tx]);change(x,y-1,tx_code[tx][temp_tx],2); }break; case RIGHT://右移 for(int i=0;i<4;i++) //判断是否允许右移 temp_flag = temp_flag && scene_num[rpoint[i].pos_x][rpoint[i].pos_y+1] !=1 && rpoint[i].pos_y+1 < SCENE_H; if(temp_flag){ //执行右移动作 clear(x,y,tx_code[tx][temp_tx]);change(x,y+1,tx_code[tx][temp_tx],2); }break; case SPACE://快速下移 for(int j=0;j<SCENE_W;j++){ for(int i=0;i<4;i++) //判断是否允许下移 temp_flag = temp_flag && scene_num[rpoint[i].pos_x+1][rpoint[i].pos_y] !=1 && scene_num[rpoint[i].pos_x][rpoint[i].pos_y] !=1 && rpoint[i].pos_x+1 < SCENE_W; if(temp_flag){ //执行下移动作 clear(x+j,y,tx_code[tx][temp_tx]);change(x+j+1,y,tx_code[tx][temp_tx],2); }else break; }break; }}void eluosiWidget::paintEvent(QPaintEvent *event){ //设置画笔 QPainter painter(this); //刷新舞台 for(int i=0;i<SCENE_W;i++){ for(int j=0;j<SCENE_H;j++){ if(scene_num[i][j] == 1){ painter.setBrush(QBrush(Qt::blue,Qt::SolidPattern)); painter.drawRect(j*REC_SIZE,i*REC_SIZE,REC_SIZE,REC_SIZE); } else if(scene_num[i][j] > 1){ painter.setBrush(QBrush(Qt::red,Qt::SolidPattern)); painter.drawRect(j*REC_SIZE,i*REC_SIZE,REC_SIZE,REC_SIZE); } } }}void eluosiWidget::timerEvent(QTimerEvent *event){ if(!Pauseflag && timerid1==event->timerId()){ weizhi(rpoint[0].pos_x,rpoint[0].pos_y,REC_tx[0],DOWN);//下移 } if(!Pauseflag && timerid2==event->timerId()) this->update(); //刷新绘图}void eluosiWidget::keyPressEvent(QKeyEvent *event) //键盘事件{ if(!Pauseflag) switch(event->key()){ case Qt::Key_Up: //按下方向键上时 weizhi(rpoint[0].pos_x,rpoint[0].pos_y,REC_tx[0],UP);break; case Qt::Key_Down: //按下方向键下时 weizhi(rpoint[0].pos_x,rpoint[0].pos_y,REC_tx[0],DOWN);break; case Qt::Key_Left: //按下方向键左时 weizhi(rpoint[0].pos_x,rpoint[0].pos_y,REC_tx[0],LEFT);break; case Qt::Key_Right: //按下方向键右时 weizhi(rpoint[0].pos_x,rpoint[0].pos_y,REC_tx[0],RIGHT);break; case Qt::Key_Space: //快速下移 weizhi(rpoint[0].pos_x,rpoint[0].pos_y,REC_tx[0],SPACE);break; }}void eluosiWidget::move(int hang, direction direct){ if(direct == UP){ for(int i=0;i<hang;i++) for(int j=0;j<SCENE_H;j++) scene_num[i][j] = scene_num[i+1][j]; }else if(direct == DOWN){ for(int i=hang;i>0;i--) for(int j=0;j<SCENE_H;j++) scene_num[i][j] = scene_num[i-1][j]; }}void eluosiWidget::SetHard(int level){ HardLevel = level; Levelflag = true;}void eluosiWidget::SetSpeed(int level) //设置速度等级{ speed_ms = 800 - level * 60; PauseGame(); PlayGame();}void eluosiWidget::SetLevel(){ for(int i=0;i<HardLevel;i++){ move(SCENE_W-1,UP); for(int j=0;j<SCENE_H;j++) scene_num[SCENE_W-1][j] = rand()%2; }}void eluosiWidget::PlayGame(){ timerid1 = startTimer(speed_ms);//设置下落速度 timerid2 = startTimer(fresh_ms);//设置刷新速度 Pauseflag = false;}void eluosiWidget::PauseGame(){ killTimer(timerid1);killTimer(timerid2); Pauseflag = true;}
主函数:
#include <eluosiwidget.h> int main(int argc, char *argv[]) { QApplication a(argc, argv); eluosiWidget w; w.show(); return a.exec();}
其他版本:
http://blog.csdn.net/imxiangzi/article/details/50667532
https://www.jerryzone.cn/qt-teris/
阅读全文
0 0
- Qt-俄罗斯方块
- Qt-俄罗斯方块
- Qt-俄罗斯方块
- Qt小游戏开发:俄罗斯方块
- QT -WS俄罗斯方块游戏
- QT/c++ 简易俄罗斯方块
- Qt做的俄罗斯方块游戏
- Qt版双人俄罗斯方块游戏
- Qt做的俄罗斯方块游戏
- 使用Qt开发俄罗斯方块游戏
- QT项目一:俄罗斯方块游戏
- 多库俄罗斯方块之十(Qt)
- Qt学习之路_13(简易俄罗斯方块)
- Qt学习之路 简易俄罗斯方块
- Qt学习之路_13(简易俄罗斯方块)
- qt俄罗斯方块 可以使用 (一)
- 使用Qt开发俄罗斯方块游戏(1)
- 【连载】Qt俄罗斯方块——公告
- identifier of an instance of bean was altered from 1 to 2(持久化对象ID变更)
- MySQL索引类型总结和使用技巧以及注意事项
- 安装RYU,以及安装RYU的GUI
- 问号 的判断
- 什么是硬分叉,什么是软分叉,什么是共识?
- Qt-俄罗斯方块
- cocoapods创建共有库过程中遇到的坑以及版本删除
- Nginx之代理配置以及负载均衡
- UIbutton设置圆角边框(Xcode8.3.3+swift3)
- Long-Short Term Memory(长短时记忆模型)
- 剑指offer 数值的整数次方
- ue4 c++ 接口写法
- 机器学习笔记之线性回归的正则化
- Java集合---Stack的源码分析