用Qt写2048游戏。
程序功能:
0.游戏的开始按钮、重新开始按钮、规则提示
1.格子的左右移动 WASD
2.数字合并时的计算
3.得分计算
4.每次操作后随机出现2
5.判断游戏是否结束
6.游戏界面
设计思路:
0.对于2048这个4*4棋盘的游戏而言,我们可以设计一个int[4][4],于是直接对数组操作即可。
1.初始化函数,使得得分变为0,格子清空
2.随机函数生成2(检测有没有空的格子,若是有,那么直接生成2,如果没有,那么判断游戏是否结束)
3.格子的绘制paintEvent()
接下来,我们开始吧。
0.新建空项目
1.初始化部分
for(int i=0;i<4;i ){
for(int j=0;j<4;j ){
s[i][j]=0;
}
}
button=new QPushButton("开始游戏");
button->setGeometry(60,400,200,50);
//随机种子
qsrand(uint(QTime(0,0,0).secsTo(QTime::currentTime())));
//槽与信号
connect(button,SIGNAL(clicked()),this,SLOT(slotStart()));
2.绘制格子(此处只贴出设置2和0的格子,其余数字(4,8,16,32......)以此类推,改变数字和颜色即可)
void MainWindow::PaintEvent(QPaintEvent *)
{
QPainter p(this);
p.setBrush(Qt::blue);
p.setFont(QFont("微软雅黑",20,700,false)); //设置字体,颜色
QString strscore;
p.drawText(QPoint(20,60),"分数:" QString::number(score));//显示分数
//绘制格子
for(int i=0;i<4;i ){
for(int j=0;j<4;j ){
p.setPen(Qt::transparent);
if(s[i][j]==0){
p.setBrush(Qt::gray);
p.drawRect(i*60 40,j*60 120,55,55);
}
else if (s[i][j]==2){
p.setBrush(QColor(255,250,222,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
//在格子中部显示出当前数字,并居中对齐
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(2),QTextOption(Qt::AlignCenter));
}
}
}
}
3.控制读取键盘,完成数字的移动和相加(此处演示向上移动 相加,左下右以此类推,具体细节见最终源码)
void MainWindow::PressUp()
{
//看上方是否为空格,若是,则上移(注意:此处为整体上移)
for(int i=0;i<4;i ){
for(int j=1;j<3;j ){
if(s[i][j]==0) continue;
for(int p=0;p<j;p ){
if(s[i][j]==0){
s[i][p]=s[i][j];
s[i][j]=0;
break;
}
}
}
}
//相加并移动
for(int i=0;i<4;i ){
for(int j=0;j<3;j ){
if(s[i][j]==s[i][j 1]){
s[i][j 1]=2*s[i][j];
s[i][j]=0;
score =s[i][j];
for(int p=j 2;p<4;p ){
s[i][p-1]=s[i][p];
}
}
}
}
}
4.随机生成2,判断游戏是否结束
最终效果
源码:
headers:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QKeyEvent>
#include <QPushButton>
#include <QPainter>
#include <QTime>
#include <QDebug> //用来 Debug
#include <QMessageBox>//自定义消息提示框
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void paintEvent(QPaintEvent *);
void keyPressEvent(QKeyEvent *event);
void PressUp();
void PressDown();
void PressLeft();
void PressRight();
void myRand();
QPushButton *button;
int s[4][4];
int score=0;
bool state;
struct Ns{
int i;
int j;
};
public slots:
void slotStart(); //槽函数
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
//显示窗体
w.setFixedSize(320,480); //设置窗体固定的长宽
w.setWindowTitle("2048"); //设置窗体名
w.show();
return a.exec();
}
mainwindow.cpp:
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//初始化
for(int i=0;i<4;i ){
for(int j=0;j<4;j ){
s[i][j]=0;
}
}
button = new QPushButton("开始游戏",this);
button->setGeometry(60,400,200,50);//从(60,400)做一个200*50的按钮
//随机函数
qsrand(uint(QTime(0,0,0).secsTo(QTime::currentTime())));
connect(button,SIGNAL(clicked()),this,SLOT(slotStart()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.setBrush(Qt::blue);
p.setFont(QFont("微软雅黑",20,700,false));
QString strscore;
p.drawText(QPoint(20,60),"分数: " QString::number(score));
for (int i=0;i<4;i ) {
for (int j=0;j<4;j ) {
p.setPen(Qt::transparent);//?
if(s[i][j]==0){
p.setBrush(QColor(255,250,222,255));
p.drawRect(i*60 40,j*60 120,55,55);
}
else if (s[i][j]==2) {
p.setBrush(QColor(255,229,168,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
//在方块中 绘制Text, 并且文本位置位于中部
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(2),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==4) {
p.setBrush(QColor(255,197,136,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(4),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==8) {
p.setBrush(QColor(251,179,129,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(8),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==16) {
p.setBrush(QColor(250,160,99,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(16),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==32) {
p.setBrush(QColor(251,103,55,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(32),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==64) {
p.setBrush(QColor(213,92,14,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(64),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==128) {
p.setBrush(QColor(252,161,159,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(128),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==256) {
p.setBrush(QColor(248,126,124,147));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(256),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==512) {
p.setBrush(QColor(255,50,80,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(512),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==1024) {
p.setBrush(QColor(188,25,22,255));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(1024),QTextOption(Qt::AlignCenter));
}
else if (s[i][j]==2048) {
p.setBrush(QColor(245,69,67,15));
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(2048),QTextOption(Qt::AlignCenter));
}
else{
p.setBrush(Qt::darkBlue);
p.drawRect(i*60 40,j*60 120,55,55);
p.setPen(Qt::black);
p.setFont(QFont("微软雅黑",10,700,false));
p.drawText(QRectF(i*60 40,j*60 120,55,55),QString::number(s[i][j]),QTextOption(Qt::AlignCenter));
}
}
}
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(!state){
return ;
}
switch (event->key()) {
case Qt::Key_W:
PressUp();
break;
case Qt::Key_S:
PressDown();
break;
case Qt::Key_A:
PressLeft();
break;
case Qt::Key_D:
PressRight();
break;
default:
return;//忽略其他按钮
}
myRand();
update();
}
void MainWindow::slotStart(){
QMessageBox::about(this,"游戏规则","WSAD控制方块上下左右移动");
score=0;
for (int i=0;i<4;i ) {
for (int j=0;j<4;j ) {
s[i][j]=0;
}
}
button->setText("重新游戏");
int randi=qrand()%4;
int randj=qrand()%4;
s[randi][randj]=2;
state=true;
update();
}
void MainWindow::PressUp(){
//移动
for (int i=0;i<4;i ) {
for (int j=1;j<4;j ) {
if(s[i][j]==0)continue;
for (int p=0;p<j;p ) {
//查看前面是否有空格子可移动
if(s[i][p]==0){
s[i][p]=s[i][j];
s[i][j]=0;
break;
}
}
}
}
//相加
for (int i=0;i<4;i ) {
for (int j=0;j<3;j ) {
if(s[i][j]==s[i][j 1]){
s[i][j]=2*s[i][j];
s[i][j 1]=0;
score =s[i][j];
for (int p=j 2;p<4;p ) {
s[i][p-1]=s[i][p];
}
}
}
}
}
void MainWindow::PressDown(){
//移动
for (int i=0;i<4;i ) {
for (int j=2;j>=0;j--) {
if(s[i][j]==0)continue;
for (int p=3;p>j;p--) {
//查看前面是否有空格子可移动
if(s[i][p]==0){
s[i][p]=s[i][j];
s[i][j]=0;
break;
}
}
}
}
//相加
for (int i=0;i<4;i ) {
for (int j=3;j>0;j--) {
if(s[i][j]==s[i][j-1]){
s[i][j]=2*s[i][j];
s[i][j-1]=0;
score =s[i][j];
for (int p=j-2;p>=0;p--) {
s[i][p 1]=s[i][p];
}
}
}
}
}
void MainWindow::PressLeft(){
//移动
for (int j=0;j<4;j ) {
for (int i=1;i<4;i ) {
if(s[i][j]==0){
continue;
}
for (int p=0;p<i;p ) {
//查看前面是否有空格可移入
if(s[p][j] == 0){
s[p][j] = s[i][j];
s[i][j] = 0;
break;
}
}
}
}
//相加
for (int j=0;j<4;j ) {
for (int i=0;i<3;i ) {
if(s[i][j]==s[i 1][j]){
s[i][j]=s[i][j]*2;
score =s[i][j];
s[i 1][j]=0;
for(int p=i 2;p<4;p ){
s[p-1][j] = s[p][j];
}
}
}
}
}
void MainWindow::PressRight(){
//移动
for (int j=0;j<4;j ) {
for (int i=2;i>=0;i--) {
if(s[i][j]==0){
continue;
}
for (int p=3;p>i;p--) {
//查看前面是否有空格可移入
if(s[p][j] == 0){
s[p][j] = s[i][j];
s[i][j] = 0;
break;
}
}
}
}
//相加
for (int j=0;j<4;j ) {
for (int i=3;i>=0;i--) {
if(s[i][j]==s[i-1][j]){
s[i][j]=s[i][j]*2;
s[i-1][j]=0;
score =s[i][j];
for(int p=i-2;p>=0;p--){
s[p 1][j] = s[p][j];
}
}
}
}
}
void MainWindow::myRand(){
int i=0,j=0;
//找出格子
struct Ns n[15];
int ni=0;
for (i=0;i<4;i ) {
for (j=0;j<4;j ) {
if(s[i][j]==0){
n[ni].i=i;
n[ni].j=j;
ni ;
}
}
}
//判断游戏是否结束
if (ni==0) {
for (i=0;i<4;i ) {
for (j=0;j<3;j ) {
if(s[i][j]==s[i][j 1]){
return;
}
}
}
for (j=0;j<4;j ) {
for (i=0;i<3;i ) {
if(s[i][j]==s[i 1][j]){
return;
}
}
}
QMessageBox::about(this,"游戏失败","分数为:" QString::number(score) " ");
return;
}
int rand=qrand()%ni;
s[n[rand].i][n[rand].j]=2;
}
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved