基于c++的拼图小游戏二次开发

拼图小游戏作为一款代码相对简单的程序,可以锻炼图片切割,以及定位。
游戏的基本玩法:通过鼠标点击将拼图碎片为原图位置,即为胜利。

采用 c++ 编写, 主要使用到了两个类, 分别是 GameFrame 和 Picture.
GameFrame 负责游戏界面的初始化和原始信息的绘制;Picture 负责图片的切割, 图片位置的初始化,
通关条件判断, 控制整个游戏正确运行.
点击即可查看部分源码(代码为网上查找,如有侵权请联系删除)

点击查看代码
#include "../Inc/picture.h"
int main()
{
	GameFrame gameframe;												// 建立游戏框架
	Picture picture;													// 建立图片框架
	gameframe.DrawBackground();											// 绘制背景
	gameframe.StartMenu();												// 绘制开始信息
	
	while (1)
	{
		picture.Run();													// 运行控制函数
		Sleep(10);														// 适当增加延时, 节约 CPU
	}
	getch();
	return 0;
}

#ifndef picture_h
#define picture_h

// 加载头文件
#include <easyx.h>
#include <conio.h>
   #include <string>
#include <ctime>

using namespace std;

// 定义游戏的背景颜色
#define BgColor   LIGHTGREEN

#pragma comment(lib,"winmm.lib")                                        //加载库文件

// 游戏的关数
const int PassCount = 8;

// 游戏边框的大小
const int xLength = 953;
const int yLength = 453;
const int Width = 600;
const int Height = 450;

// 图片, 结构体, 保存图像
struct Image
{
    IMAGE image;                                                        // 保存图像
    int x;                                                              // 保存图像的 x 坐标
    int y;                                                              // 保存图像的 y 坐标
};

// 游戏的框架类
class GameFrame
{
    public:
        GameFrame();                                                    // 默认构造函数
        void DrawBackground();                                          // 绘制背景图像
        void StartMenu();                                               // 开始界面, 选择游戏难度
};

// 图像类
class Picture
{
	private:
		IMAGE img;														// 保存完整图像
		Image **image;                                                  // 保存切割图像
        int Control;                                                    // 控制值
        int Diffcult;                                                   // 难度值
        int Pass;                                                       // 记录当前的关数
		int LocalX;														// 记录鼠标的位置信息
		int LocalY;
        string String;													// 保存图片路径
		MOUSEMSG MouseMessage;											// 鼠标消息
		int singleWidth;												// 单幅图像的宽度
		int singleHeight;												// 单幅图像的高度
		int **Query;													// 查询数组, 快速定位图片
    public:
		Picture()														// 默认构造函数
		{
            Control = 0;
            Diffcult = 0;
            Pass = 0;
            String = "Res\\00.jpg";
			LocalX = 0;
			LocalY = 0;
			singleWidth = 0;
			singleHeight = 0;
		}
		void Run();														// 控制函数
		void SetGameDifficult();										// 设置游戏的难度
        void SetPicture();                                              // 设置图片
		void SetLocal();												// 设置位置
		void DrawRect();												// 绘制线条
		void PrintPicture();											// 将图像输出到屏幕
        void ProcessMouse();                                            // 处理鼠标消息, 实现移动的关键算法
		void ProcessPicture();											// 处理图像
		void IsPass();                                                  // 判断是否通关
};

#endif
游戏将库存的图片拼图根据切割后的拼图块数分为3个难度, `void Picture::SetGameDifficult() { char num; // 读取键盘的键值
while (1)
{
    if (kbhit())
    {
		mciSendString("play  Res\\key.wav", NULL, 0, NULL);
        num = getch();                                              // 从键盘获取信息
        
        switch (num)
        {
			case 'a':Diffcult = 3;break;
            case 'b':Diffcult = 4;break;
            case 'c':Diffcult = 5;break;
            default:Diffcult = 0;
        }
    }

	// 如果游戏难度已获取则退出循环
    if (Diffcult != 0)
    {
        Control = 1;
        break;
    }
}

}`
在使用过程中,发现拼图游戏看似简单,在应用过程中却容易发生无解的情况,源代码对此使用了复杂的数学公式进行判断,因此将setlocal()函数进行了修改,修改后应用合适的图片定位算法,将图片位置的初始化不再是散乱随机,而是由原始位置倒推,确保了不会造成无解情况。

点击查看代码
void Picture::SetLocal()
{
	// 记录四个方向的值
	int sentryX[4] = {-1, 0, 1, 0};
	int sentryY[4] = {0, -1, 0, 1};

	int index = -1;
	int num = 0;
	int Diff = Diffcult -1;
	int Len = Diff;
	int x1, y1;
	int k = 0;
	loop:
	for (int l = 0; l < 8; ++l)
	{
		++index;
		index = index % 4;
		for (k = Len; k > 0; k--)
		{
			// 记录 LocalX 和 LocalY 的位置
			LocalX = image[Diff][Diff].x + sentryX[index];
			LocalY = image[Diff][Diff].y + sentryY[index];

			// 定位图片位置
			num = Query[LocalY][LocalX];

			// 记录 y1, x1 的位置
			y1 = num / Diffcult;
			x1 = num % Diffcult;

			// 修改查询数组的值
			Query[LocalY][LocalX] = Diffcult * Diffcult - 1;
			Query[image[Diff][Diff].y][image[Diff][Diff].x] = num;

			// 交换图片位置
			image[y1][x1].x = image[Diff][Diff].x;
			image[y1][x1].y = image[Diff][Diff].y;
			image[Diff][Diff].x = LocalX;
			image[Diff][Diff].y = LocalY;
		}
	}
	Len--;
	if (Len > 0)
	{
		goto loop;
	}
	srand(time(NULL));
	for (k = 0; k < 100; k++)
	{
		loop1:
		index = rand() % 4;
		// 记录 LocalX 和 LocalY 的位置
		LocalX = image[Diff][Diff].x + sentryX[index];
		LocalY = image[Diff][Diff].y + sentryY[index];
		if (LocalX >= 0 && LocalX <= Diff && LocalY >= 0 && LocalY <= Diff)
		{
			// 定位图片位置
			num = Query[LocalY][LocalX];
			
			// 记录 y1, x1 的位置
			y1 = num / Diffcult;
			x1 = num % Diffcult;
			
			// 修改查询数组的值
			Query[LocalY][LocalX] = Diffcult * Diffcult - 1;
			Query[image[Diff][Diff].y][image[Diff][Diff].x] = num;
			
			// 交换图片位置
			image[y1][x1].x = image[Diff][Diff].x;
			image[y1][x1].y = image[Diff][Diff].y;
			image[Diff][Diff].x = LocalX;
			image[Diff][Diff].y = LocalY;
		}
		else
		{
			goto loop1;
		}
	}

总结 通过这次对拼图游戏的二次开发,我对c++的代码使用有了进步,问题分析能力、和编程的实践能力有所提升。 一个游戏代码不止玩法的代码重要,画面的设置也很重要,我将会学习这方面进行改进,而这次实践中,对图片定位和鼠标信息的学习也让我受益匪浅
posted @ 2024-03-05 00:10  2024-310  阅读(221)  评论(0)    收藏  举报