Qt鬥地主界面的發牌,搶地主,出牌界面的實現。

      無聊的時候挺喜歡玩鬥地主,在學完Qt之後我想做一個鬥地主,在完成了界面和邏輯之後最終碰到了AI出牌算法這個問題。對於這種比較難得問題,小生束手難測,僅僅完成了界面。界面邏輯已經完成的差不多了。現將其中的核心代碼開源,望各位道友能指點一二。代碼寫的有點混亂,邏輯可能不清楚,還希望各位道友能多多海涵。

在以後用空的時候會將這個搶地主,自動發牌,出牌的邏輯模塊獨立剝離出來成爲一個完整獨立的類。

裏面的牌的界面是我用PS做的,我會在文章下方寫下文件的下載地址。望各位道友能有所收穫。

最後說一句,寫的不是代碼,是孤獨啊。

 

ifndef CARDWIDGET_H
#define CARDWIDGET_H

#include <QWidget>
#include <QLabel>
#include "verdesktop.h"

class cardWidget : public QWidget
{
    Q_OBJECT
public:
    QLabel *cardLabel;//牌面
    void setGeometryAndLabel();//設置座標與大小
    void setAnimation();//創建動畫
    void setNoAnimation();//創建無補間動畫
    void writeCardWidget_X(int x)//寫入座標X
    {
        this->cardWidget_X=x;
    }
    void writeCardNum(int Num);//寫入卡號
    int readCardNum();//讀取卡號
    void writeCardID(int id)
    {
        this->cardID=id;
    }//寫入卡的id
    int readCardID()
    {
        return this->cardID;
    }//讀取卡的id
    explicit cardWidget(QWidget *parent = 0);
    bool isup=false;
    bool isdown=true;
private:
    void mousePressEvent(QMouseEvent *event);//單擊事件
    void mouseDoubleClickEvent(QMouseEvent *event);
    int cardWidget_X;//x座標
    int cardID;//卡牌的id
    int cardNum=0;//定義從A-----大王分別爲1------------15
    float ver;
    VerDesktop *verDesktop;
signals:
    void mousePressSend(int ID);//發送信號單擊信號
    void animationFinished(int ID);//發送動畫結束信號
public slots:
    void getAnimationFinished();//接收動畫結束信號
};

#endif // CARDWIDGET_H

 

 
#include "cardwidget.h" #include <QDebug> #include <QMouseEvent> #include <QPropertyAnimation> cardWidget::cardWidget(QWidget *parent) : QWidget(parent) { verDesktop=new VerDesktop(this); ver=verDesktop->getVerDesktop(); } void cardWidget::setGeometryAndLabel() { this->hide(); int x=(cardNum/4)*100;//通過尋圖算法找到相應的撲克面 int y=(cardNum%4)*150; cardLabel=new QLabel(this); cardLabel->clear(); QPixmap MMM(":/res/image/cards.png");//提供大圖的撲克Pixmap QPixmap cardpix=MMM.copy(x,y,100*ver,150*ver); cardLabel->setGeometry(0,0,100*ver,150*ver); cardLabel->setPixmap(cardpix.scaled(100*ver,150*ver)); cardLabel->setScaledContents(true); } void cardWidget::getAnimationFinished() { emit animationFinished(cardID); } void cardWidget::writeCardNum(int Num) { this->cardNum=Num; } int cardWidget::readCardNum() { return cardNum; } void cardWidget::mousePressEvent(QMouseEvent *event) { Q_UNUSED(event); isup=!isup; emit mousePressSend(cardID); qDebug()<<cardID; qDebug()<<cardNum; } void cardWidget::mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event); } void cardWidget::setAnimation()//提供了一個動畫實現了發牌的動態展現 { this->show(); QPropertyAnimation *animation0=new QPropertyAnimation(this,"geometry"); QPropertyAnimation *animation1=new QPropertyAnimation(this->cardLabel,"geometry"); animation0->setDuration(300); animation1->setDuration(300); animation0->setStartValue(QRect(350*ver,0,50*ver,75*ver)); animation0->setEndValue(QRect(cardID*40*ver,120*ver,100*ver,150*ver)); animation1->setStartValue(QRect(0,0,50*ver,75*ver)); animation1->setEndValue(QRect(0,0,100*ver,150*ver)); animation1->start(QAbstractAnimation::DeleteWhenStopped); animation0->start(QAbstractAnimation::DeleteWhenStopped); connect(animation0,SIGNAL(finished()),this,SLOT(getAnimationFinished())); connect(animation1,SIGNAL(finished()),this,SLOT(getAnimationFinished())); } void cardWidget::setNoAnimation() { this->show(); this->setGeometry(cardID*40*ver,120*ver,100*ver,150*ver); }

 

 


 

 

 

 


 
#ifndef CARDSBASEWIDGET_H
#define CARDSBASEWIDGET_H

#include <QWidget>
#include "verdesktop.h"
#include "cardwidget.h"

class CardsBaseWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CardsBaseWidget(QWidget *parent = 0);
    void writeCardsSize(int Size){
        cardSize=Size;
    }
    int readCardsSize(){
        return cardSize;
    }
    cardWidget *cardwidget;
    QVector<cardWidget*>vector_card;
    void setGeometryAndLabels();//設定座標
private:
    float ver;
    VerDesktop *verDesktop;
    int cardSize=20;

signals:
    void hideCardssssLabel();//關閉信號
public slots:
    void getCardWidgetID(int id);//獲取單擊widgetID
    void getCardAnimationFinshedID(int id);//獲取動畫結束widgetID
    void openGame();//開始遊戲
#ifndef BASEWIDGET_H
#define BASEWIDGET_H

#include <QWidget>
#include <verdesktop.h>
#include <QPainter>
#include <QLabel>
#include <QTime>
#include<QPushButton>
#include"cardsbasewidget.h"
#include "mythreadrandomnum.h"

class BaseWidget : public QWidget
{
    Q_OBJECT
public:
    explicit BaseWidget(QWidget *parent = 0);
    void writeLeftCardSize(int size);//寫入
    void writeRightCardSize(int size);//寫入
    void showChuOrBuyaoButton();//顯示出牌或者不出

private:
    float ver;
    VerDesktop *verDesktop;
    CardsBaseWidget *cardBaseWidget;
    void setCardBaseWidgetOnBaseWidget();//將cardbasewidget定義在BaseWidget
    void setBaseWidgetSizeAndBackground();//設定BaseWidget的界面大小
    void changeBaseBackgroundPicture();//改變默認背景圖片
    void setNormalBaseBackgroundPicture();//設定默認的背景圖片
    void paintEvent(QPaintEvent *event);//繪製背景圖片
    QLabel *dizhuLabel;//地主
    QLabel *nongmin0Label;//農民1
    QLabel *nongmin1Label;//農民2
    QLabel *cardsAllLabel;//總牌數
    QLabel *rightCardAllLabel;//左方牌
    QLabel *leftCardAllLabel;//右方牌
    QWidget *rightCardSizeWidget;//左方牌數
    QWidget *leftCardSizeWidget;//右方牌數
    QLabel *rightCardSizeLabel;
    QLabel *leftCardSizeLabel;
    QPushButton *openGameButton;//開始遊戲
    QPushButton *getDizhuButton;//搶地主
    QPushButton *abandonDizhuButton;//不搶地主
    QPushButton *chupaiButton;//出牌
    QPushButton *buyaoButton;//不要
    void setPersonPixmapLabel();//設定角色圖片
    QList<int> numbersList;
    void getRandomCardNumList();//獲取隨機值
    QList<int> userNumCardList;//用戶的牌數與號
    QList<int> nongmin0NumCardList;//農民0的牌數與號
    QList<int> nongmin1NumCardList;//農民的牌數與號
    void setUserRandomCardNumList();//爲用戶分配隨機值
    void sortUserRandomCardNumList();//排序用戶的牌
signals:

public slots:
    void getHideCardsss();//關閉label--cardsss
    void openGameButtonSlot();//開始遊戲的slot
    void getDizhuButtonSlot();//搶地主的slot
    void abandonDizhuButtonSlot();//不搶的slot
    void chupaiButtonSlot();//出牌的slot
    void buyaoButtonSlot();//不要的slot
};

 

#include "basewidget.h"
#include <QPropertyAnimation>

BaseWidget::BaseWidget(QWidget *parent) : QWidget(parent)
{
    verDesktop=new VerDesktop(this);
    ver=verDesktop->getVerDesktop();
    setBaseWidgetSizeAndBackground();
    setCardBaseWidgetOnBaseWidget();
    setPersonPixmapLabel();
    connect(cardBaseWidget,SIGNAL(hideCardssssLabel()),this,SLOT(getHideCardsss()));
    connect(openGameButton,SIGNAL(clicked(bool)),this,SLOT(openGameButtonSlot()));
    connect(getDizhuButton,SIGNAL(clicked(bool)),this,SLOT(getDizhuButtonSlot()));
    connect(abandonDizhuButton,SIGNAL(clicked(bool)),SLOT(abandonDizhuButtonSlot()));
    connect(chupaiButton,SIGNAL(clicked(bool)),this,SLOT(chupaiButtonSlot()));
    connect(buyaoButton,SIGNAL(clicked(bool)),this,SLOT(buyaoButtonSlot()));
}
void BaseWidget::setBaseWidgetSizeAndBackground()
{
    this->setGeometry(5*ver,5*ver,1300*ver,900*ver);
    this->setMinimumSize(1300*ver,900*ver);
    this->setMaximumSize(1300*ver,900*ver);
}
void BaseWidget::changeBaseBackgroundPicture()
{
}
void BaseWidget::setNormalBaseBackgroundPicture()
{
}
void BaseWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPixmap background0;
    background0.load(":/res/image/basebackground0.png");
    background0.scaled(1300*ver,900*ver);
    QPainter painter(this);
    painter.save();
    painter.drawPixmap(0,0,1300*ver,900*ver,background0);
    painter.restore();
}
void BaseWidget::setPersonPixmapLabel()
{
    dizhuLabel=new QLabel(this);
    nongmin0Label=new QLabel(this);
    nongmin1Label=new QLabel(this);
    cardsAllLabel=new QLabel(this);
    openGameButton=new QPushButton(this);
    rightCardAllLabel=new QLabel(this);
    leftCardAllLabel=new QLabel(this);
    leftCardSizeWidget=new QWidget(this);
    leftCardSizeLabel=new QLabel(leftCardSizeWidget);
    rightCardSizeWidget=new QWidget(this);
    rightCardSizeLabel=new QLabel(rightCardSizeWidget);
    getDizhuButton=new QPushButton(this);
    abandonDizhuButton=new QPushButton(this);
    chupaiButton=new QPushButton(this);
    buyaoButton=new QPushButton(this);
    QPixmap nongmin0Pix(":/res/image/nongmin0.png");
    nongmin0Label->setGeometry(0,280*ver,155*ver,210*ver);
    nongmin0Label->setPixmap(nongmin0Pix.scaled(155*ver,210*ver));
    QPixmap nongmin1Pix(":/res/image/nongmin1.png");
    nongmin1Label->setGeometry(1148*ver,280*ver,155*ver,210*ver);
    nongmin1Label->setPixmap(nongmin1Pix.scaled(155*ver,210*ver));
    QPixmap dizhuPix(":/res/image/dizhu.png");
    dizhuLabel->setGeometry(10*ver,603*ver,170*ver,240*ver);
    dizhuLabel->setPixmap(dizhuPix);
    QPixmap cardsssPix(":/res/image/cardsss.png");
    cardsAllLabel->setGeometry(550*ver,370*ver,150*ver,150*ver);
    cardsAllLabel->setPixmap(cardsssPix.scaled(150*ver,150*ver));
    cardsAllLabel->setScaledContents(true);
    QPixmap rightCardsssPix(":/res/image/rightcardsss.png");
    rightCardAllLabel->setPixmap(rightCardsssPix.scaled(150*ver,110*ver));
    rightCardAllLabel->setGeometry(155*ver,370*ver,150*ver,110*ver);
    rightCardAllLabel->hide();
    QPixmap leftCardssPix(":/res/image/leftcardsss.png");
    leftCardAllLabel->setPixmap(leftCardssPix.scaled(150*ver,110*ver));
    leftCardAllLabel->setGeometry(1005*ver,370*ver,150*ver,110*ver);
    leftCardAllLabel->hide();
    cardsAllLabel->hide();
    openGameButton->setGeometry(550*ver,370*ver,100*ver,50*ver);
    openGameButton->setText(tr("開始遊戲"));
    rightCardSizeWidget->setGeometry(240*ver,275*ver,50*ver,50*ver);
    rightCardSizeLabel->setGeometry(0,0,50*ver,50*ver);
    rightCardSizeLabel->setText(tr("左部牌數"));
    leftCardSizeWidget->setGeometry(1012*ver,275*ver,50*ver,50*ver);
    leftCardSizeLabel->setGeometry(0,0,50*ver,50*ver);
    leftCardSizeLabel->setText(tr("右部牌數"));
    getDizhuButton->setGeometry(450*ver,475*ver,100*ver,50*ver);
    getDizhuButton->setText(tr("搶地主"));
    getDizhuButton->hide();
    abandonDizhuButton->setGeometry(650*ver,475*ver,100*ver,50*ver);
    abandonDizhuButton->setText("不搶");
    abandonDizhuButton->hide();
    chupaiButton->setGeometry(450*ver,475*ver,100*ver,50*ver);
    chupaiButton->setText("出牌");
    chupaiButton->hide();
    buyaoButton->setGeometry(650*ver,475*ver,100*ver,50*ver);
    buyaoButton->setText("不要");
    buyaoButton->hide();
}
void BaseWidget::showChuOrBuyaoButton()
{
    chupaiButton->show();
    buyaoButton->show();
}
void BaseWidget::setCardBaseWidgetOnBaseWidget()
{
    cardBaseWidget=new CardsBaseWidget(this);
    cardBaseWidget->show();
}
void BaseWidget::getHideCardsss()
{
    rightCardAllLabel->show();
    leftCardAllLabel->show();
    cardsAllLabel->hide();
    getDizhuButton->show();
    abandonDizhuButton->show();
}
void BaseWidget::openGameButtonSlot()
{
    getRandomCardNumList();
    setUserRandomCardNumList();
    sortUserRandomCardNumList();
    cardsAllLabel->show();
    QPropertyAnimation *animation0=new QPropertyAnimation(cardsAllLabel,"geometry");
    animation0->setDuration(6000);
    animation0->setStartValue(QRect(550*ver,370*ver,150*ver,150*ver));
    animation0->setEndValue(QRect(550*ver,420*ver,150*ver,100*ver));
    animation0->start(QAbstractAnimation::DeleteWhenStopped);
    cardBaseWidget->openGame();
    openGameButton->hide();
}
void BaseWidget::writeLeftCardSize(int size)
{
    leftCardAllLabel->setText(QString::number(size));
}
void BaseWidget::writeRightCardSize(int size)
{
    rightCardAllLabel->setText(QString::number(size));
}
void BaseWidget::getRandomCardNumList()
{
    int i,j;
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    for(i=0;i<54;i++)//生成54個隨機數
    {
        numbersList.append(qrand()%54);
        bool flag=true;
        while(flag)
        {
            for(j=0;j<i;j++)
            {
                if(numbersList[i]==numbersList[j])
                {
                    break;
                }
            }
            if(j<i)
            {
                numbersList[i]=rand()%54;
            }
            if(j==i)
            {
                flag=!flag;
            }
        }
    }
}
void BaseWidget::setUserRandomCardNumList()
{
    for(int i=0;i<17;i++)
    {
        userNumCardList.append(numbersList[i]);
    }
    for(int i=17;i<34;i++)
    {
        nongmin0NumCardList.append(numbersList[i]);
    }
    for(int i=34;i<51;i++)
    {
        nongmin1NumCardList.append(numbersList[i]);
    }
}
void BaseWidget::sortUserRandomCardNumList()
{
    qDebug()<<"11111111111111111111111";
    qDebug()<<userNumCardList.size();
    qDebug()<<"11111111111111111111111";
    cardBaseWidget->writeCardsSize(userNumCardList.size());
    qSort(userNumCardList.begin(),userNumCardList.end());
    for(int i=0;i<userNumCardList.size();i++)
    {
        qDebug()<<userNumCardList[i];
        cardBaseWidget->vector_card.at(i)->writeCardNum(userNumCardList[i]);
        cardBaseWidget->vector_card.at(i)->cardLabel->clear();
        cardBaseWidget->vector_card.at(i)->setGeometryAndLabel();
    }
}
void BaseWidget::getDizhuButtonSlot()//用戶搶完地主後重新刷新牌面顯示並且加入三張牌
{
    userNumCardList.append(numbersList[51]);
    userNumCardList.append(numbersList[52]);
    userNumCardList.append(numbersList[53]);
    qDeleteAll(cardBaseWidget->vector_card);
    cardBaseWidget->vector_card.clear();
    cardBaseWidget->writeCardsSize(userNumCardList.size());
    qSort(userNumCardList.begin(),userNumCardList.end());
    cardBaseWidget->setGeometryAndLabels();
    qDebug()<<"22222222222222222222222";
    qDebug()<<userNumCardList.size();
    qDebug()<<"22222222222222222222222";
    for(int i=0;i<userNumCardList.size();i++)
    {
        cardBaseWidget->vector_card.at(i)->writeCardNum(userNumCardList[i]);
        cardBaseWidget->vector_card.at(i)->cardLabel->clear();
        cardBaseWidget->vector_card.at(i)->setGeometryAndLabel();
        cardBaseWidget->vector_card.at(i)->setNoAnimation();
    }
    getDizhuButton->hide();
    abandonDizhuButton->hide();
    showChuOrBuyaoButton();
}
void BaseWidget::abandonDizhuButtonSlot()
{
    nongmin0NumCardList.append(numbersList[51]);
    nongmin0NumCardList.append(numbersList[52]);
    nongmin0NumCardList.append(numbersList[53]);
    getDizhuButton->hide();
    abandonDizhuButton->hide();
    showChuOrBuyaoButton();
}
void BaseWidget::chupaiButtonSlot()//出牌動作的實現,以及後臺數據分析進行。
{
    int size=cardBaseWidget->readCardsSize();
    for(int i=0;i<size;i++)
    {
        if(cardBaseWidget->vector_card.at(i)->isup==true)
        {
            int value=cardBaseWidget->vector_card.at(i)->readCardNum();
            userNumCardList.removeOne(value);
            continue;
        }
    }
    qDeleteAll(cardBaseWidget->vector_card);
    cardBaseWidget->vector_card.clear();
    cardBaseWidget->writeCardsSize(userNumCardList.size());
    qSort(userNumCardList.begin(),userNumCardList.end());
    cardBaseWidget->setGeometryAndLabels();
    qDebug()<<"33333333333333333333333";
    qDebug()<<userNumCardList.size();
    qDebug()<<"33333333333333333333333";
    for(int i=0;i<userNumCardList.size();i++)
    {
        cardBaseWidget->vector_card.at(i)->writeCardNum(userNumCardList[i]);
        cardBaseWidget->vector_card.at(i)->cardLabel->clear();
        cardBaseWidget->vector_card.at(i)->setGeometryAndLabel();
        cardBaseWidget->vector_card.at(i)->setNoAnimation();
    }
    chupaiButton->hide();
    buyaoButton->hide();
}
void BaseWidget::buyaoButtonSlot()
{
    chupaiButton->hide();
    buyaoButton->hide();
}

 

#include <QPropertyAnimation>

CardsBaseWidget::CardsBaseWidget(QWidget *parent) : QWidget(parent)
{
    verDesktop=new VerDesktop(this);
    ver=verDesktop->getVerDesktop();
    setGeometryAndLabels();
}
void CardsBaseWidget::setGeometryAndLabels()
{
    int x;
    if(cardSize<10)
    {
        x=250*ver+(10-cardSize)*40*ver;
    }else
    {
        x=250*ver+(20-cardSize)*20*ver;
    }
    int w=(cardSize-1)*40*ver+100*ver;
    this->setGeometry(x,520*ver,w,320*ver);
    for(int i=0;i<cardSize;i++)
    {
        cardwidget=new cardWidget(this);
        cardwidget->writeCardID(i);
        vector_card.append(cardwidget);
        vector_card.at(i)->setGeometryAndLabel();
    }
    for(int i=0;i<cardSize;i++)
    {
        connect(vector_card.at(i),SIGNAL(mousePressSend(int)),this,SLOT(getCardWidgetID(int)));
        connect(vector_card.at(i),SIGNAL(animationFinished(int)),this,SLOT(getCardAnimationFinshedID(int)));
    }
}
void CardsBaseWidget::getCardAnimationFinshedID(int id)
{
    if(id<cardSize-1)
    {
         int ID=id+1;
         vector_card.at(ID)->setAnimation();
         vector_card.at(ID)->show();
    }
    else
    {
        emit hideCardssssLabel();
    }
}
void CardsBaseWidget::getCardWidgetID(int id)
{
    if(vector_card.at(id)->isup==true)
    {
         vector_card.at(id)->setGeometry(id*40*ver,70*ver,100*ver,150*ver);
    }
    if(vector_card.at(id)->isup==false)
    {
          vector_card.at(id)->setGeometry(id*40*ver,120*ver,100*ver,150*ver);
    }
}
void CardsBaseWidget::openGame()
{
       vector_card.at(0)->setAnimation();
       vector_card.at(0)->setGeometryAndLabel();
       vector_card.at(0)->show();
}


核心代碼就是上述這些,完整的代碼就在下面的鏈接裏。

項目已經上傳到Github,如果大家喜歡歡迎給個Start,如有問題,歡迎issue。

https://github.com/zqljintu/Gameinterface-Doudizhu

或者去我的資源頁裏去尋找。
 

發佈了39 篇原創文章 · 獲贊 14 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章