基于C++与QT仿照羊了个羊规则的鸿了个鸿贴图游戏

目录

1.游戏效果展示

2.游戏介绍

3.游戏核心思路

3.1游戏理念

3.2游戏思路

4.游戏核心模块实现

4.1设置背景和卡片图片

4.2画卡片

4.2.1画第一层图片

4.2.2画第二层图片

4.3鼠标事件

4.3.1鼠标事件重写

4.3.2判断点击是哪个图片

4.4卡槽区功能

4.4.1卡槽区贴图模块

4.4.2页面跳转

4.4.3判断三消和结束判断

5 全部代码

第一关

.h

第二关 与第一关同理

.cpp

.h


1.游戏效果展示

基本和游戏差不多如果用的图对的话


2.游戏介绍

该游戏是基于c++和QT实现的一款仿照网络爆火的羊了个羊的游戏,但是目前本人也是初学者所有只写出来基础款羊了羊,关卡是固定的而且卡片分配是有一定规律的,后期我也会努力学习改进算法让游戏可以更加逼真。所有如果你喜欢这款羊了个羊,我会一步一步教你如何实现这款羊了个羊游戏的,也请大佬多多指教。

3.游戏核心思路


3.1游戏理念


因为QT设计可以直接进行贴图,所有设计羊了个羊算法和思维并不难但是却是比较繁,但是却可以锻炼自己的鼠标事件和贴图的能力,可以让初学者更加深刻的理解QT开发贴图游戏的思路。

3.2游戏思路


羊了个羊,本质就是一个贴图游戏,只要搞清楚每张图每次在哪里,那么这个问题就解决啦,对于第一关只需要3*6张图,那么我们完全可以用一个二维数组来维护这些图片,开一个a[3][3]={1}让这个二维数组里所有的数值设成为1,让1代表这些图片在卡片区,而当我们点击一次鼠标让该区域最上面那张图片对应的二维数组的值改变为0,让0代表这张卡片在卡槽区,然后遍历卡槽区里的卡片是否有满足三消条件,如果达到三消就将这三张照片所对应的二维数组对应的值改变为2,让2代表这张卡片在垃圾桶。最后判断获胜遍历使用图片对应的二维数组是否都为2图片全在垃圾桶。第二关和第一关思路一模一样,只不过加大了难度。

4.游戏核心模块实现


以下代码只有部分作为讲解 完整代码在最下面

4.1设置背景和卡片图片


做羊了个羊最重要的是你需要在纸上画出你的游戏大小和规划好每个图片所在的位置,然后在ui界面里固定好界面的大小和确定好每个图片所在的位置。

通过画家来画我们界面和游戏,该游戏所有的画图都在画图函数中执行。首先导入所有需要的图片资源,然后用一个画家指针来帮我们画画,后期也是在这个函数里进行的。

void yanglgyang::paintEvent(QPaintEvent *)
{
    QString picture =  {":/new/prefix1/photo/01.jpg"};//界面绿草背景
    QString picture2 = {":/new/prefix1/photo/02.jpg"};//界面那个卡片槽的槽图片
    QString picture3 = {":/new/prefix1/photo/03.jpg"};//卡片1
    QString picture4 = {":/new/prefix1/photo/04.jpg"};//卡片2
    QString picture5 = {":/new/prefix1/photo/05.jpg"};//卡片3
    QPainter*painter = new QPainter(this);
    QPixmap pixmap;
    pixmap.load(picture);
    pixmap.scaled(this->width(),this->height());
    painter->drawPixmap(0,0,this->width(),this->height(),pixmap);//画背景
    pixmap.load(picture2);
    pixmap.scaled(600,100);
    painter->drawPixmap(40,680,600,100,pixmap);//画卡片槽
    painter->end();
}

4.2画卡片


4.2.1画第一层图片


用一个判断语句如果这个二维数组为0说明这个地方有这张图片 部分判断代码 ,而且二维数组的第一维表示第几种卡片,第二维表示第几张图片,用这样的方法把每张图片分开。然后通过自己想让图片在那块,就在在那个坐标位置进行绘制。

if(jishu[0][0]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(160,160,80,80,pixmap);
            painter->end();
    }
 if(jishu[0][1]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(290,310,80,80,pixmap);
            painter->end();
    }

4.2.2画第二层图片


在第一次图片的基础上纵坐标加10,然后绘制,让第二次绘制的图片将第一层图片覆盖达到游戏里的覆盖的效果。

if(jishu[0][3]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(430,170,80,80,pixmap);
            painter->end();
    }
 if(jishu[0][4]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(160,470,80,80,pixmap);
            painter->end();
    }

4.3鼠标事件


4.3.1鼠标事件重写

void yanglgyang::mousePressEvent(QMouseEvent *ev)
{
    int x = ev->x();
    int y = ev->y();
}


4.3.2判断点击是哪个图片


需要判断点击是那个图片需要解决两个问题,第一个鼠标点击是那个地方且这个地方有卡片,第二个点击这个地方的图片上面有没有压它的卡片,需要解决这个问题就需要,用到坐标处理每个卡片所在的区域做一个范围,如果鼠标事件传来这个范围的坐标就说明玩家点击了这个卡片,但是我们还需要确认这个卡片上面没有压它的图片,如果有压它的图片那么就吧压它的卡片先从卡片区移除,然后再次点击这个范围,才能移除它。但是我们还需要确定这个范围有卡片,不然当这个范围的卡片全部被消除,在按还是会进行判断导致BUG。

void yanglgyang::mousePressEvent(QMouseEvent *ev)
{
    int x = ev->x();
    int y = ev->y();
    if(x>150&&x<150+80&&y>160&&y<160+80&&jishu[0][0]==1)
    {
        if(jishu[1][3]==1)
            jishu[1][3]=0;
         else jishu[0][0]=0;
    }
   else if(x>290&&x<290+80&&y>160&&y<160+80&&jishu[1][0]==1)
    {
        if(jishu[2][3]==1)//判断是否最压它的卡片
              jishu[2][3]=0;
        else jishu[1][0]=0;
    }
 
}

4.4卡槽区功能


4.4.1卡槽区贴图模块


羊了个羊卡槽区的卡片每次都会更新将相同的放在一起,所有我们也需要将相同的图片放在一起,所有我们没有卡槽区贴图,可以依次遍历二维数组,而二维数组第一维表示图片种类,所有遍历一遍,遍历过程依次贴图完全可以让相同的图片相邻。

4.4.2页面跳转


加需要跳转到页面的头文件

#include"dierguan.h"
在.h文件里声明指针

 dierguan *dir;
在cpp文件里给指针一个空间 然后指向show()

dir = new dierguan;

 dir->show();

4.4.3判断三消和结束判断


首先还是遍历二维数组然后判断没一类卡片是否有三张卡片为0,如果是将三张卡片变为2

 
   

     int i=0;
        a=0;
        for(int j=0;j<6;j++)
        {
            if(jishu[i][j]==0)
             {
                a++;
             }
 
        }
        if(a==3)
        {
 
            for(int k=0;k<6;k++)
            {
                if(jishu[i][k]==0)
                {
                    jishu[i][k]=2;//2为垃圾桶
                }
                //加一个音效
            }
        }
        i=1;
        a=0;
        for(int j=0;j<6;j++)
        {
            if(jishu[i][j]==0)
             {
                a++;
             }
 
        }
        if(a==3)
        {
 
            for(int k=0;k<6;k++)
            {
                if(jishu[i][k]==0)
                {
                    jishu[i][k]=2;//2为垃圾桶
                }
                //加一个音效
            }
        }
        i=2;
        a=0;
        for(int j=0;j<6;j++)
        {
            if(jishu[i][j]==0)
             {
                a++;
             }
 
        }
        if(a==3)
        {
 
            for(int k=0;k<6;k++)
            {
                if(jishu[i][k]==0)
                {
                    jishu[i][k]=2;//2为垃圾桶
                }
                //加一个音效
            }
        }
 
 
    int x11=80;
    int y11=690;
     b=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<6;j++)
        {
            if(jishu[i][j]==0)
            {
                if(i==0)
                {
                   QPainter*painter = new QPainter(this);
                   QPixmap pixmap;
                   pixmap.load(picture3);
                   pixmap.scaled(80,80);
                   painter->drawPixmap(x11,y11,80,80,pixmap);
                   painter->end();
                   x11=x11+80;
                   b++;
                }
               else if(i==1)
                {
                   QPainter*painter = new QPainter(this);
                   QPixmap pixmap;
                   pixmap.load(picture4);
                   pixmap.scaled(80,80);
                   painter->drawPixmap(x11,y11,80,80,pixmap);
                   painter->end();
                   x11=x11+80;
                   b++;
                }
               else if(i==2)
                {
                   QPainter*painter = new QPainter(this);
                   QPixmap pixmap;
                   pixmap.load(picture5);
                   pixmap.scaled(80,80);
                   painter->drawPixmap(x11,y11,80,80,pixmap);
                   painter->end();
                   x11=x11+80;
                   b++;
                }
 
            }
        }
 
    if(b==7)
    {
        QMessageBox::information(this,"玩家","胜败乃兵家常事\n大侠请重新来过");
       this->close();
    }
    int sss=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<6;j++)
        {
            if(jishu[i][j]==2)
            {
                sss++;
            }
        }
    if(sss==18)
    {
        //QMessageBox::information(this,"玩家","胜");
        this->close();
       // sco = new scound;
     //   sco->show();
        dir = new dierguan;
        dir->show();
    }
 
}

5 全部代码


第一关


.cpp

#include "yanglgyang.h"
#include "ui_yanglgyang.h"
 
yanglgyang::yanglgyang(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::yanglgyang)
{
    ui->setupUi(this);
    this->setWindowTitle("羊了个羊");
}
 
yanglgyang::~yanglgyang()
{
    delete ui;
}
 
void yanglgyang::paintEvent(QPaintEvent *)
{
    QString picture =  {":/new/prefix1/photo/01.jpg"};
    QString picture2 = {":/new/prefix1/photo/02.jpg"};
    QString picture3 = {":/new/prefix1/photo/03.jpg"};
    QString picture4 = {":/new/prefix1/photo/04.jpg"};
    QString picture5 = {":/new/prefix1/photo/05.jpg"};
    QPainter*painter = new QPainter(this);
    QPixmap pixmap;
    pixmap.load(picture);
    pixmap.scaled(this->width(),this->height());
    painter->drawPixmap(0,0,this->width(),this->height(),pixmap);
    pixmap.load(picture2);
    pixmap.scaled(600,100);
    painter->drawPixmap(40,680,600,100,pixmap);
    painter->end();
    if(jishu[0][0]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(160,160,80,80,pixmap);
            painter->end();
    }
    if(jishu[0][1]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(290,310,80,80,pixmap);
            painter->end();
    }
    if(jishu[0][2]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture3);
            pixmap.scaled(80,80);
            painter->drawPixmap(430,460,80,80,pixmap);
            painter->end();
    }
    if(jishu[1][0]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture4);
            pixmap.scaled(80,80);
            painter->drawPixmap(290,160,80,80,pixmap);
            painter->end();
    }
    if(jishu[1][1]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(picture4);
            pixmap.scaled(80,80);
            painter->drawPixmap(160,310,80,80,pixmap);
            painter->end();
    }
    if(jishu[1][2]==1)
    {
 
            QPainter*painter = new QPainter(this);
            QPixmap pixmap;
            pixmap.load(pict
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值