当前位置:网站首页>C3-qt realize Gobang games (I) November 7, 2021

C3-qt realize Gobang games (I) November 7, 2021

2022-06-22 02:47:00 Morning and evening rain

Qt Gobang games

qt Realize Gobang ( Two )

The goal is :

Open the game , Click the start button to start the game , Play chess in the order chosen in advance , The color and number of steps of the current player will be displayed , And allow the current chess color to fall , At the same time, it is accompanied by the falling sound effect , It is also testing whether the players win , Once we win , Prompt the winner immediately . The size of the chessboard can be changed according to the size of the window .

step :

** The first big step is to build a chessboard .** The logic of the chessboard ( The chessboard ) And the logic of playing chess ( main interface ) Separate , The chessboard can send the current coordinate signal in response to the mouse event , The main interface receives coordinate signals , And use the method provided by the chessboard to refresh the chessboard , Refresh the chessboard . Every move of chess , Refresh the chessboard , Judge whether to win or not , Switch roles, etc .
In this small project, there is the application of the things mentioned in the previous basic chapter , There are also simple applications of classes that do not appear , At the same time, we should pay more attention to , The design ability of decoupling program modules , This ability can make large projects instant ” crumble “, Let your programming 、 debugging 、 The test is well organized , adept .
Because my computer is encrypted , Unable to upload project , So please understand and create your own project in combination with the following step descriptions and code comments .

1. Create without ui The checkerboard class of the interface

establish chessplate class , Inherited from QWidget, Although not ui Interface , But in main Instantiate the object in and call show Method , The interface will be displayed , This is because it inherits from widget.

2. Get ready

.pro Add a multimedia module to make it easy to read QSound Use , as follows :

QT  +=  multimedia

stay chessplate.h Add the header file of the class to the file , as follows :

#include <QWidget>
#include <QPainter>
#include <QResizeEvent>
#include <QDebug>
#include <QMouseEvent>

3.QPainter Drawing board

① Draw a background picture ( Paste the code at the end )
② Draw a checkerboard line . Put the chessboard in the grid 、 start 、 The end point is defined as a member variable , When the window changes , Trigger resize event , stay resize Change the size of the above three variables in the event , meanwhile resize Will trigger QPainter event , Redraw the interface , Then the chessboard will change with the size of the window .
③ Draw anchor points , have access to brush Draw a circle around the four dots , You can also draw pictures in fixed positions .
④ Painting pieces , Use a two-dimensional array to store the status of the current chessboard , for example 1 For black . Click the event with the mouse , Click generate coordinates , The coordinate information is combined with the current role to refresh the storage array , call update() Redraw the picture , The checkerboard status will be refreshed according to the latest storage array . In order to interact with other modules , Carry out the following design , When you click the mouse , Coordinate information ( Not real coordinates , But the coordinates of the transformed lattice ) As a signal , Other categories ( It mainly refers to the main interface ) Receive this message , Refresh the storage array in the main interface p, take p Passed as a parameter to the method of refreshing the chessboard provided by the chessboard class , Complete the interaction between modules , Complete the interface refresh . besides , Attention should also be paid to , The chess pieces should be drawn to the intersection of the horizontal and vertical lines of the chessboard .

4. Mouse events

Click the mouse , Record the current coordinate information , Divide it into grids , That is, to get the information about where the user wants to be located , Take the coordinates of this grid as a signal . If you want to be meticulous , You should consider constraining the response orientation of mouse click events , For example, the response should be limited to the radius of the intersection , Avoid careless mistakes by users .

5.resizeEvent

Every time resize Will automatically trigger QPainter Repaint , So in resize In the event of only , Go back to the current interface size information , Then calculate the size of the interface , How big should the checkerboard grid be , After these calculations QPainter Will be redrawn based on this data , Make sure the size of the chessboard changes dynamically with the size of the interface . But considering the beauty of the chessboard , There should be restrictions on the extent to which the interface can be enlarged or narrowed , Of course, this restriction is made in the main interface that calls it .

6. External supply method

Provides a way to modify the background image , Provide to modify the checkerboard line thickness 、 Line style 、 Method of line color , Provides a method to refresh the checkerboard state . When a class wants to provide external methods to modify something , You should add class member variables , Then use the parameters of the external method function to change the value of the class member variable , These member variables are simultaneously ” What to modify “ Use as a parameter . This makes , An external class changes something of this class by providing new parameters .

    // Provides a way to modify the background image 
    void setBackGroundPic(const QString filename);
    // Change the checkerboard line style 
    void setPlateLine(const QColor color,const Qt::PenStyle style,const int width);
    // Refresh the chessboard 
    void setChessStatus(void *p);

effect

stay main Instantiate and call the show Method , You can see the following effect .
Insert picture description here
 Insert picture description here

Code

The posted code is as follows :
chessPlate.h Code

#ifndef CHESSPLATE_H
#define CHESSPLATE_H

#include <QWidget>
#include <QPainter>
#include <QResizeEvent>
#include <QDebug>
#include <QMouseEvent>
#define GRIDCOUNT 16

class chessPlate : public QWidget
{
    
    Q_OBJECT

public:
    chessPlate(QWidget *parent = nullptr);
    ~chessPlate();

    enum ChessType{
    Empty=0,White,Black};
    // Provides a way to modify the background image 
    void setBackGroundPic(const QString filename);
    // Change the checkerboard line style 
    void setPlateLine(const QColor color,const Qt::PenStyle style,const int width);
    // Refresh the chessboard 
    void setChessStatus(void *p);
protected:
    void paintEvent(QPaintEvent *);
    void resizeEvent(QResizeEvent *);
    void mousePressEvent(QMouseEvent *);
private:
    QString bgFileName;
    QColor lineColor;
    Qt::PenStyle lineStyle;
    int lineWidth;
    // Grid width and height , Draw the starting point of the line 
    int gridWidth, gridHeight,startX,startY;
    int chessData[15][15];
    void Init();

signals:
    void mousePosSend(int i,int j);
};
#endif // CHESSPLATE_H

chessPlate.cpp

#include "chessplate.h"

chessPlate::chessPlate(QWidget *parent)
    : QWidget(parent)
{
    
    Init();
}

chessPlate::~chessPlate()
{
    
}

void chessPlate::paintEvent(QPaintEvent *)
{
    
    QPainter painter(this);
    // Painting background 
    QRect rect(QPoint(0,0),QSize(this->width(),this->height()));
    QPixmap pix(bgFileName);
    painter.drawPixmap(rect,pix);
// QPixmap pix2(":/res/black.png");
// painter.drawPixmap(QPoint(100,30),pix2);

    // Draw line 
    QPen pen;
    pen.setColor(lineColor);
    pen.setStyle(lineStyle);
    pen.setWidth(lineWidth);
    painter.setPen(pen);

    for (int i = 0;i<15 ;i++ ) {
    
        // Draw line 
        painter.drawLine(startX,startY+i*gridHeight,startX+14*gridWidth,startY+i*gridHeight);//x
        painter.drawLine(startX+i*gridWidth,startY,startX+i*gridWidth,startY+14*gridHeight);//y

    }
    // Draw four dots 
    QBrush brs;
    brs.setColor(Qt::black);
    brs.setStyle(Qt::SolidPattern);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    painter.setBrush(brs);
    painter.drawEllipse(QPoint(4*gridWidth,4*gridHeight),6,6);
    painter.drawEllipse(QPoint(12*gridWidth,4*gridHeight),6,6);
    painter.drawEllipse(QPoint(8*gridWidth,8*gridHeight),6,6);
    painter.drawEllipse(QPoint(12*gridWidth,12*gridHeight),6,6);
    painter.drawEllipse(QPoint(4*gridWidth,12*gridHeight),6,6);
    painter.setPen(pen);

    // Fallout display 
    QString chessFilename;
    for (int i= 0;i<15 ;i++ ) {
    
        for (int j = 0;j<15 ;j++ ) {
    
            if(chessData[i][j]==White){
    
                chessFilename = ":/res/white.png";
            }
            else if(chessData[i][j]==Black){
    
                chessFilename = ":/res/black.png";
            }
            else
            {
    
                chessFilename.clear();
                continue;
            }
            painter.drawPixmap(startX/2+i*gridWidth,startY/2+j*gridHeight,gridWidth,gridHeight,QPixmap(chessFilename));
        }
    }
}
void chessPlate::resizeEvent(QResizeEvent *event)
{
    
    this->gridWidth = event->size().width()/GRIDCOUNT;
    this->gridHeight = event->size().height()/GRIDCOUNT;
    startX = gridWidth;
    startY = gridHeight;
}
void chessPlate::mousePressEvent(QMouseEvent *event)
{
    
    int x=event->x();
    int y=event->y();
    //x
    if(x>=startX/2 &&(x<=startX/2+15*gridWidth)){
    
        //y
        if(y>=startY/2&&(y<=startY/2+15*gridHeight))
        {
    
            // Find out which grid the current coordinate belongs to   The lattice does not correspond to the actual lattice , Because , Put him on the diagonal 
            int i = 0,j =0;
            i = (x-startX/2)/gridWidth;
            j = (y-startY/2)/gridHeight;
// chessData[i][j]=Black;
// this->update();
            mousePosSend(i,j);
        }
    }
}
void chessPlate::Init()
{
    
    // Initialization function : Set the initial value of the member variable ( The default value is ); Set the initial status of the interface, such as the title and icon 


    bgFileName.clear();
    bgFileName = ":/res/chess_back.jpg";
    lineColor = Qt::black;
    lineStyle = Qt::SolidLine;
    lineWidth = 3;

    for (int i=0;i<15 ;i++ ) {
    
        for (int j = 0;j<15 ;j++ ) {
    
            chessData[i][j]=Empty;
        }
    }
// chessData[3][3] = White;
// chessData[4][4] = Black;

}

void chessPlate::setBackGroundPic(const QString filename)
{
    
    this->bgFileName = filename;
    this->update();
}
void chessPlate::setPlateLine(const QColor color, const Qt::PenStyle style, const int width)
{
    
    this->lineColor = color;
    this->lineStyle = style;
    this->lineWidth = width;
    this->update();
}
void chessPlate::setChessStatus(void *p)
{
    
    memcpy(chessData,p,sizeof(int)*15*15);
    this->update();
}

To be continued ……

原网站

版权声明
本文为[Morning and evening rain]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206211658129673.html