吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 775|回复: 3
收起左侧

[学习记录] c语言拼图游戏-PicturePuzzle

[复制链接]
vtor 发表于 2023-6-22 23:34
本帖最后由 vtor 于 2023-6-22 23:45 编辑

c语言拼图游戏-PicturePuzzle2023年6月22日 ​
开发环境:使用vs2019,配合easyx图形库
image.png
基本设计:

注意,需要自行(寻找并)添加图片,
在例子中,使用原神角色 甘雨进行游戏。
struct Block结构体:每个方块,都有坐标,以及对应的图片, 所以起码需要col,row,imgIdx。init函数:然后使用easyx,初始化图片对象,,加载图片等。
paint函数:使用col得到y坐标,使用row得到x坐标,使用imgIdx得到确定图片,直接进行绘制图片,在程序中,增加了线,用于区分每个block。
userInput函数:使用easyx图形库,确定点击的坐标(x,y),        
                                      左击时,,,根据y得到col,根据x得到row,判断四个方向是否有空缺(注意防止越界),如果有空缺,交换两者的imgIdx,从而完成图片交换。        
                                       当完成游戏时,右击可重新开始游戏。checkWin函数:检查block的imgidx是否有序即可。

拓展功能:
为了保证能完成拼图,打乱时,需要保证逆序数是偶数,两个循环比较一下即可。


以下是完整代码:
[C++] 纯文本查看 复制代码
#include <stdio.h>
#include <time.h>
#include <easyx.h>


#define GAME_LEVEL    3

#define WINDOW_WIDTH    800
#define WINDOW_HEIGHT    800


#define    X_OFFSET    0
#define Y_OFFSET    0
#define BLOCK_SIZE    (WINDOW_HEIGHT / GAME_LEVEL)

#define GetXByCol(col)    (col * BLOCK_SIZE + X_OFFSET)
#define GetYByRow(row)    (row * BLOCK_SIZE + Y_OFFSET)

#define GetColByX(x)    ((x - X_OFFSET) / BLOCK_SIZE)
#define GetRowByY(y)    ((y - Y_OFFSET) / BLOCK_SIZE)

struct Block
{
    int col, row;
    int imgIdx;
};

int colNum = GAME_LEVEL;
int rowNum = GAME_LEVEL;

int moveFlag = 0;


struct Block blocks[GAME_LEVEL][GAME_LEVEL] = {0};

const char* imgFileString = { "res//ganyu-1280.png" };
//const char* imgFileString = { "res//unable.png" };
IMAGE wholeImg;
// https://wiki.biligame.com/ys/%E7%94%98%E9%9B%A8#/media/%E6%96%87%E4%BB%B6:%E7%94%98%E9%9B%A8%E7%AB%8B%E7%BB%98.png
IMAGE img[GAME_LEVEL * GAME_LEVEL] = { 0 };


int getReverseOrder()
{
    int reverseOrderCnt = 0;
    for (int preOrder = 0; preOrder < colNum * rowNum - 1; preOrder++) {
        for (int nextOrder = preOrder + 1; nextOrder < colNum * rowNum; nextOrder++) {
            if (blocks[preOrder % colNum][preOrder / colNum].imgIdx != colNum * rowNum - 1
                && blocks[nextOrder % colNum][nextOrder / colNum].imgIdx != colNum * rowNum - 1) {
                if (blocks[preOrder % colNum][preOrder / colNum].imgIdx
                    > blocks[nextOrder % colNum][nextOrder / colNum].imgIdx)
                {
                    reverseOrderCnt++;
                }
            }
        }
    }
    return reverseOrderCnt;
}

bool checkWin()
{
    bool winFlag = true;
    for (int imgIdx = 0; imgIdx < colNum * rowNum - 1; imgIdx++) {
        if (blocks[imgIdx % colNum][imgIdx / colNum].imgIdx != imgIdx) {
            winFlag = false;
            break;
        }
    }
    return winFlag;
}


void start()
{
    int swapCnt = 3;
    while (1)
    {
        if ((swapCnt < 0) && (getReverseOrder() % 2 == 0))
        {
            break;
        }
        int swapIdx1 = rand() % (colNum * rowNum - 1);
        int swapIdx2 = rand() % (colNum * rowNum - 1);
        int tempImgIdx = blocks[swapIdx1 / colNum][swapIdx1 % colNum].imgIdx;
        blocks[swapIdx1 / colNum][swapIdx1 % colNum].imgIdx = blocks[swapIdx2 / colNum][swapIdx2 % colNum].imgIdx;
        blocks[swapIdx2 / colNum][swapIdx2 % colNum].imgIdx = tempImgIdx;
        swapCnt--;
    }

}


void init()
{
    srand(time(NULL));
    initgraph(WINDOW_WIDTH, WINDOW_HEIGHT, EW_SHOWCONSOLE);
    // 加载到画面中,为下一步做准备
    loadimage(&wholeImg, imgFileString, WINDOW_WIDTH, WINDOW_WIDTH);
    putimage(0, 0, &wholeImg);


    for (int row = 0; row < rowNum; row++) {
        for (int col = 0; col < colNum; col++) {
            blocks[col][row].col = col;
            blocks[col][row].row = row;
            // 先有序,然后进行打乱
            blocks[col][row].imgIdx = row * rowNum + col;

            if (row * colNum + col < colNum * rowNum - 1)
            {
                getimage(&img[blocks[col][row].imgIdx],
                    GetXByCol(col),
                    GetYByRow(row),
                    BLOCK_SIZE,
                    BLOCK_SIZE);
            }
        }
    }
    // 针对最后一张图片额外处理
    //loadimage(&img[colNum * rowNum - 1], imgFileString, BLOCK_SIZE, BLOCK_SIZE);
    cleardevice();
}


void userInput()
{
    MOUSEMSG msg;
    if (PeekMouseMsg(&msg)) {
        if (WM_LBUTTONDOWN == msg.uMsg) {
            int clickCol, clickRow;
            clickCol = GetColByX(msg.x);
            clickRow = GetRowByY(msg.y);
            printf("lbutton  %d %d\r\n", clickCol, clickRow);
            for (int around = -3; around <= 3; around +=2)
            {
                int aroundCol = clickCol + (around % 3);
                int aroundRow = clickRow + (around / 3);

                printf("around %d %d\r\n", aroundCol, aroundRow);
                // 需要判断有效,防止越界访问
                if (0 <= aroundRow && aroundRow < rowNum
                    && 0 <= aroundCol && aroundCol < colNum) {
                    // 如果有一个方向是空块,那么将进行坐标置换
                    if (blocks[aroundCol][aroundRow].imgIdx == rowNum * colNum - 1) {
                        int tempImgIdx = blocks[clickCol][clickRow].imgIdx;
                        blocks[clickCol][clickRow].imgIdx = blocks[aroundCol][aroundRow].imgIdx;
                        blocks[aroundCol][aroundRow].imgIdx = tempImgIdx;
                        break;
                    }
                }
            }
        }
        else if (WM_RBUTTONDOWN == msg.uMsg) {
            // 游戏结束,右击,重新开始
            if (checkWin())
            {
                start();
            }
            for (int row = 0; row < rowNum; row++) {
                printf("     ");
                for (int col = 0; col < colNum; col++) {

                    printf("%d %d %d\t\t",
                        blocks[col][row].col,
                        blocks[col][row].row,
                        blocks[col][row].imgIdx);
                }
                printf("\r\n");
            }
            printf("getReverseOrder = %d\r\n\r\n", getReverseOrder());
        }

    }
}

void paint()
{
    BeginBatchDraw();
    cleardevice();
    for (int row = 0; row < rowNum; row++) {
        for (int col = 0; col < colNum; col++) {
            putimage(
                GetXByCol(blocks[col][row].col),
                GetYByRow(blocks[col][row].row),
                &img[blocks[col][row].imgIdx]);
        }
    }

    setlinestyle(0, 3);
    setlinecolor(RGB(0, 0, 255));
    for (int row = 1; row < rowNum; row++) {
        line(0, row * BLOCK_SIZE, (colNum + 1) * BLOCK_SIZE, row * BLOCK_SIZE);
    }
    for (int col = 1; col < colNum; col++) {
        line(col * BLOCK_SIZE, 0, col * BLOCK_SIZE, (rowNum + 1) * BLOCK_SIZE);
    }
    EndBatchDraw();
}


int main(void)
{
    init();
    start();
    while (1) {
        // 当逆序为0时,说明游戏成功
        if (checkWin()) {
            BeginBatchDraw();
            putimage(0, 0, &wholeImg);
            EndBatchDraw();
        } else {
            paint();
        }
        userInput();
    }
    system("pause");
    return 0;
}

免费评分

参与人数 3吾爱币 +8 热心值 +2 收起 理由
Kdocke + 1 我很赞同!
RippleSky + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| vtor 发表于 2023-6-23 11:59
哇哦,居然是版主 苏紫方璇 参与了评分,多谢,嘿嘿~
seawaycao 发表于 2023-6-23 12:13
qingyun36 发表于 2023-6-24 07:28
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 22:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表