#include "gamedlg.h"
#include "ui_gamedlg.h"
#include <QPainter>
#include <QTime>
#include <QKeyEvent>
#include <QDebug>
GameDlg::GameDlg(QWidget *parent)
: QDialog(parent)
, ui(new Ui::GameDlg)
{
ui->setupUi(this);
connect(ui->startButton, SIGNAL(clicked(bool)), this, SLOT(startOrPause()));
connect(ui->resetButton, SIGNAL(clicked(bool)), this, SLOT(reset()));
//加载填充小方格的位图
pixmaps[0].load(tr(":/img/grayBlock.png"));
pixmaps[1].load(tr(":/img/blueBlock.png"));
pixmaps[2].load(tr(":/img/cyanBlock.png"));
pixmaps[3].load(tr(":/img/greenBlock.png"));
pixmaps[4].load(tr(":/img/purpleBlock.png"));
pixmaps[5].load(tr(":/img/redBlock.png"));
pixmaps[6].load(tr(":/img/yellowBlock.png"));
//初始化各个小方格对应的Tetri数组元素
for(int i = 0; i < 20; i++)
{
for(int j = 0; j < 10; j++)
{
this->Grids[i][j] = 0;
}
}
setFocusPolicy(Qt::StrongFocus);
//加载方块样例位图
pixmapNext[0].load(tr(":/img/Type1.png"));
pixmapNext[1].load(tr(":/img/Type2.png"));
pixmapNext[2].load(tr(":/img/Type3.png"));
pixmapNext[3].load(tr(":/img/Type4.png"));
pixmapNext[4].load(tr(":/img/Type5.png"));
pixmapNext[5].load(tr(":/img/Type6.png"));
pixmapNext[6].load(tr(":/img/Type7.png"));
//设置随机种子,使得每次游戏开始时方块类型是随机的
qsrand(QTime::currentTime().msec());
nextBlockType =qrand() % 7 + 1; //产生一个方块类型
//nextBlockType = 6;
block =new OneBlock(nextBlockType, this);
ui->labelNext->setText(tr(""));
//设定Next区域显示下一个方块
ui->labelNext->setPixmap(pixmapNext[nextBlockType - 1]);
isBlkActive = false;
ifPaused = true;
score = 0;
ui->startButton->setCheckable(true);
ui->startButton->setChecked(false);//只能设置一个
ui->startButton->setAutoExclusive(true);
}
GameDlg::~GameDlg()
{
delete ui;
}
void GameDlg::paintEvent(QPaintEvent *)
{
//int xOrg = 98, yOrg = 1;
int xOrg = 327, yOrg = 22;
int cellw =pixmaps[0].width() + 1;
int cellh =pixmaps[0].height() + 2;
QPainter painter(this);
mutex.lock();
//绘制主场景中的已经固定的方块
for(int i = 0; i < 20; i++)
{
for(int j = 0; j < 10; j++)
{
if(this->Grids[i][j] > 0)
{
painter.drawPixmap(xOrg + j * cellw, yOrg + i * cellh,
cellw, cellh, pixmaps[Grids[i][j] - 1]);
}
}
}
if(isBlkActive)
{
//绘制当前活动方块
int x = blkLocX, y = blkLocY;
for(int i = 0; i <= block->cont_D; i++)
{
for(int j = block->cont_L; j <= block->cont_R; j++)
{
if(block->d[i][j] != 0)
{
painter.drawPixmap(xOrg + (y + j) * cellw, yOrg + (x + i) * cellh,
cellw, cellh, pixmaps[block->d[i][j] - 1]);
}
}
}
//在NEXT区显示下一个方块
ui->labelNext->setPixmap(pixmapNext[nextBlockType - 1]);
}
mutex.unlock();
}
void GameDlg::startOrPause()
{
//ui->startButton->setCheckable(true);
bool chkState = ui->startButton->isChecked();
if(chkState == true)
{
ui->resetButton->setEnabled(true);
nTimerId = startTimer(500);
ifPaused = false;
}
else
{
ifPaused = true;
killTimer(nTimerId);
}
}
void GameDlg::reset()
{
//主场景中方块清空
for(int i = 0; i < 20; i++)
{
for(int j = 0; j < 10; j++)
{
this->Grids[i][j] = 0;
}
}
//分数清零
score = 0;
QString str = QString::number(score);
ui->labelScore->setText(str);
ifPaused = true;
isBlkActive = false;
//start按钮恢复初始状态
ui->startButton->setChecked(false);
ui->startButton->setEnabled(true);
//reset按钮失效
ui->resetButton->setEnabled(false);
killTimer(nTimerId);
update();
}
void GameDlg::timerEvent(QTimerEvent *)
{
if(ifPaused)
{
return;
}
mutex.lock();
if(!isBlkActive)
{
//放入一个方块
blkLocX = 0;
blkLocY = 3;
block->InitialBlk(nextBlockType);
//产生下一个方块的类型
nextBlockType =qrand()%7 + 1;
//nextBlockType = 6;
//方块进入活动状态
isBlkActive = true;
}
else
{
if(block->ifCanDown())
{
this->blkLocX++;
}
else
{
int x = blkLocX, y = blkLocY;
//将方块内容合并到主场景中
for(int i = 0; i <= block->cont_D; i++)
for(int j = block->cont_L; j <= block->cont_R; j++)
{
if(block->d[i][j] != 0)
Grids[x + i][y + j] =block->d[i][j];
block->d[i][j] = 0;
}
isBlkActive = false; //方块处于非活动状态
//若新进的模块一步也不能向下移动,则游戏结束
if(blkLocX == 0)
{
ifPaused = true;
ui->startButton->setChecked(false);
ui->startButton->setEnabled(false);
}
}
DestroyLines();
}
mutex.unlock();
this->update();
}
void GameDlg::keyPressEvent(QKeyEvent *e)
{
if(ifPaused) return;
mutex.lock();
switch (e->key())
{
case Qt::Key_Left:
if(block->ifCanLeft()) blkLocY--;
qDebug() << "keyPressEvent, Key_Left";
break;
case Qt::Key_Right:
if(block->ifCanRight()) blkLocY++;
qDebug() << "keyPressEvent, Key_Right";
break;
case Qt::Key_Down:
if(block->ifCanDown()) blkLocX++;
qDebug() << "keyPressEvent, Key_Down";
break;
case Qt::Key_Up:
block->tryRotate();
qDebug() << "keyPressEvent, Key_Up";
break;
}
DestroyLines();
mutex.unlock();
this->update();
//Dialog::keyPressEvent(e);
}
void GameDlg::DestroyLines()
{
for(int i = 0; i < 20; i ++) //从上向下扫描
{
bool full = true;
for(int j = 0; j < 10; j++) //判断第i行是否满
{
if(Grids[i][j] == 0) full = false; //未满
}
//若第i行满,则删除
if(full)
{
int k = i;
while(k > 0)
{
for(int j = 0; j < 10; j++)
{
Grids[k][j] = Grids[k - 1][j];
}
k--;
}
for(int j = 0; j < 10; j++)
{
Grids[0][j] =0;
}
//分数更新
score = score + 10;
QString str = QString::number(score);
ui->labelScore->setText(str);
}
}
}
collin18
- 粉丝: 0
- 资源: 1
最新资源
- nyakumi-lewd-snack-3-4k_720p.7z.002
- 现在微信小程序能用的mqtt.min.js
- 基于MPC的非线性摆锤系统轨迹跟踪控制matlab仿真,包括程序中文注释,仿真操作步骤
- 基于MATLAB的ITS信道模型数值模拟仿真,包括程序中文注释,仿真操作步骤
- 基于Java、JavaScript、CSS的电子产品商城设计与实现源码
- 基于Vue 2的zjc项目设计源码,适用于赶项目需求
- 基于跨语言统一的C++头文件设计源码开发方案
- 基于MindSpore 1.3的T-GCNTemporal Graph Convolutional Network设计源码
- 基于Java的贝塞尔曲线绘制酷炫轮廓背景设计源码
- 基于Vue框架的Oracle数据库实训大作业设计与实现源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈