Qt 制作2048小游戏

相信大家都玩过2048把,下面是我用qt写得2048小游戏。

2048.pro

HEADERS +=     Widget.h

SOURCES +=     Widget.cpp     main.cpp

QT += widgets gui

RESOURCES +=     ico.qrc

RC_ICONS = 2048.ico

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QKeyEvent>
#include <QPushButton>
#include <QPainter>
#include <QTime>

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    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;
    bool state;

    struct Ns{  //保存空格
        int i;
        int j;
    };

signals:

public slots:
    void slotStart();
};

#endif // WIDGET_H

widget.cpp

#include "Widget.h"
#include <QMessageBox>

#include <QDebug>

Widget::Widget(QWidget *parent) :
      QWidget(parent),score(0),state(false)
{
    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);
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));//随机函数
    connect(button,SIGNAL(clicked()),this,SLOT(slotStart()));

    //connect(timer,SIGNAL(timeout()),this,SLOT(update()));
}

void Widget::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(Qt::red);
                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));
            }
            else if(s[i][j] == 4){
                p.setBrush(Qt::darkRed);
                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(Qt::green);
                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(Qt::darkGreen);
                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(Qt::yellow);
                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(Qt::darkYellow);
                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(Qt::cyan);
                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(Qt::darkCyan);
                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(Qt::magenta);
                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(Qt::darkMagenta);
                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(Qt::blue);
                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 Widget::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 Widget::slotStart()
{
   QMessageBox::about(this,"游戏规则","亲!~用W,S,A,D分别控制方块上下左右移动,知道了吗?");
    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 Widget::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] = s[i][j]*2;
                 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 Widget::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] = s[i][j]*2;
                 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 Widget::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;
                 s[i+1][j] = 0;
                 score += s[i][j];
                 for(int p=i+2;p<4;p++)
                     s[p-1][j] = s[p][j];
             }

         }

}

void Widget::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 Widget::myRand()
{
    int i,j;
    //找出空的格子
   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;

}

main.cpp

#include "Widget.h"
#include <QApplication>

int main(int argc,char** argv)
{
    QApplication app(argc,argv);

    Widget w;
    w.setFixedSize(320,480);
    w.setWindowTitle("2048");
    w.setWindowIcon(QIcon(":/2048.ico"));
    w.show();

    return app.exec();
}

比起一大堆啰嗦的文字,我还是觉得代码更靠谱。

原文地址:https://www.cnblogs.com/StringSir/p/8445718.html

时间: 2024-10-10 04:26:10

Qt 制作2048小游戏的相关文章

[Qt 5.6.2] 利用Qt实现一个难度可变的2048小游戏

利用Qt实现一个难度随时可调的2048小游戏 一.游戏简介 1.规则创新 胜利条件:达成2048 难度变化:玩家可以通过调整难度条来控制随机池(2.4.8.16)中各个数出现的概率,同时也会改变分数的加成比例 移动触发:每次移动后会从随机池中按照概率随机选取一个数,将其随机放置在一个空余位置上 分数计算:总分=基础分+加成分,基础分+=合并的数值,加成分+=随机生成的数值*加成比例 2.游戏效果 二.设计思路 先将该项目分为游戏入口.主窗口设计与游戏逻辑三个主要模块,再在这三个模块的基础上继续细

【2048小游戏】——CSS/原生js爬坑之纯CSS模态对话框&amp;游戏结束

引言:2048小游戏的结束界面,使用纯CSS制作模态对话框,一般做模态对话框都会使用BootStrap自带的模态对话框组件方便使用,但在制作要运行在移动端的小项目时,就不能使用BootStrap,因为文件太大,下载耗时,耗费流量. 一.模态对话框的组成 2个Div,一个铺满整屛,一个显示内容 坑:如何让Div铺满整屛?解决:2个办法 宽  高 100%    →    position:absolute:  →   top=0;left=0; 四个方向  margin-top/left/righ

.NET手撸2048小游戏

.NET手撸2048小游戏 2048是一款益智小游戏,得益于其规则简单,又和2的倍数有关,因此广为人知,特别是广受程序员的喜爱. 本文将再次使用我自制的"准游戏引擎"FlysEngine,从空白窗口开始,演示如何"手撸"2048小游戏,并在编码过程中感受C#的魅力和.NET编程的快乐. 说明:FlysEngine是封装于Direct2D,重复本文示例,只需在.NET Core 3.0下安装NuGet包FlysEngine.Desktop即可. 并不一定非要做一层封装

使用AxureRP7.0制作经典小游戏"大家来找茬"

本案例是<网站蓝图AxureRP7.0从入门到精通视频教程>中的最后一节,适用于对Axure基础知识掌握比较熟练的同学:教程由axure原型库网站录制,转载请注明出处!相信很多刚接触Axure或者学习了一段时间但并没有深入的同学们,看到这个案例一定很惊讶,使用Axure竟然能做出如此逼真的交互效果!通过此案例也可以激发广大同学们学习Axure的热情和信心!试想一下,如果你有情侣的话,把你们珍藏的合影拿出来处理几张,做成大家来找茬的小游戏,不但锻炼了自己的技能,还能给对方一个惊喜,岂不是一举两得

C# 开发2048小游戏

这应该是几个月前,闲的手痒,敲了一上午代码搞出来的,随之就把它丢弃了,当时让别人玩过,提过几条更改建议,但是时至今日,我也没有进行过优化和更改(本人只会作案,不会收场,嘎嘎),下面的建议要给代码爱好的童鞋完成了. 更改建议: a.当数字超过四位数时,显示的时候有部分被它的容器TextBox遮挡了,能不能把显示的数值变小点?答案是可以的.代码里有一段通过矩阵数据填充TextBox值的操作,可以在填充时,判断下数值长度,然后修改TextBox的文字大小. b.玩游戏的时候,使用方向键移动时,焦点可能

2048小游戏(C语言版)

1 #include <climits> 2 #include <cstdio> 3 #include <cstring> 4 #include <stack> 5 #include <string> 6 #include <map> 7 #include <vector> 8 #include <cmath> 9 10 11 /* 12 玩法说明:编译运行后,输入一个整数n,表示自己想玩的游戏中是n*n的表格

canvas随笔之2048小游戏

HTML: <!DOCTYPE HTML> <html> <head> <title>2048小游戏</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, u

如何在CentOS上安装一个2048小游戏

如何在centos上安装一个2048小游戏 最近在学习CentOS系统,就琢磨着玩点什么,然后我看到有人在玩2048小游戏,所有我就在想,为啥不装一个2048小游戏搞一下嘞,于是乎,我就开始工作啦 由于我个人的编程能力不强,所以我就在网上找到了一个C语言版的2048游戏小程序,我把它放到我的百度网盘上,可以供大家下载(链接:http://pan.baidu.com/s/1jIutb3g 密码:mu9z),然后我们把这个程序给复制到CentOS系统下,在进行下一步的工作.我们可以在CentOS上安

Swift实战之2048小游戏

上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完善,就这么整理一下过程中一些值得记录的点吧. 用的Swift版本是2.0,原书中的Swift版本会低一些,所以实践起来有些地方语法并不一样. 一.开始页面   在程序的第一张页面(Main.storyboard)上,只放了一个“开始游戏”按钮,点击按钮,弹出一个提示对话框,确认后,进入游戏页面. 1