0%

拼图游戏

项目地址:https://github.com/0ziyuan/Jigsaw-puzzle.git

拼图游戏,大一C语言结课作业,依赖于acllib库实现,仅支持Windows环境下运行。

项目描述

滑块拼图是一款策略类游戏,把一幅图案分为相等的若干正方型小方块,取走其中一块留出空位,利用多余的空格滑动其他小方块,打乱图案形成拼图。复位时都不能取下任何小方块,利用缺少的空位滑动图案中的小方块使其复原。

程序运行后先随机打乱,然后利用鼠标点击将拼图复原。鼠标只能分别控制与空格相邻的上下左右的滑块往空格位移动,判断图片复原则显示拼图完成

算法分析与概要设计

核心算法的详细设计与实现

加载

音效加载与图片加载类似,原图片和拼图完成后播放的音乐均直接加载,而9个拼图块与9个钢琴音效均借助对文件名的修改,从而实现每次循环将不同的jpg或mp3文件加载进ACL_Image或ACL_Sound类型数组的相应空间中。

初始化map坐标数组

map数组为二维数组,定义为map[ROW][COL],用于存储图片编号,行标和列标对应具体位置。初始化过程十分简单,行标和列标二重循环,将行标+列标总行数(i + j\ROW)的值赋给map[i][j]即可。但对于之后拼图块的交换十分方便。

随机打乱函数

绘制图片

原图片单独绘制,9个拼图块(含空白块)按i,j的二重循环,由“putImageScale(&img[map[i][j]], i * SIZE, j * SIZE, SIZE, SIZE);”语句绘制,便可呈现打乱后的图片

鼠标控制移动

鼠标点击控制与空格相邻的上下左右的滑块往空格位移动

判断拼图是否复原

在i,j二重循环下,判断map[i][j] 是否等于i + j * ROW(即map的初始值)。若二者相等,count(初值为0)做自增操作。循环结束,判断count是否等于9,若等,则判定为复原,显示拼图完成,并播放音乐。

边界测试Debug

鼠标点击原图片
Bug

当原图片右侧为空白块时,点击原图片,二者发生奇怪的交换,bug如下图

Debug

对交换图片的条件作进一步限制

1
2
3
4
5
6
7
8
9
10
/*游戏过程*/
void MouseEvent(int x, int y, int button, int event)
{
int r, c;
//修改为if (x < (WNDWIDTH - SIZE) && (button == LEFT_BUTTON && event == BUTTON_DOWN))
if (button == LEFT_BUTTON && event == BUTTON_DOWN)
{
c = y / SIZE;
r = x / SIZE;
if ((r==r0&&c==c0-1)||(r==r0&&c==c0+1)|| //通过鼠标点击时的坐标与空白块坐标比对,判断是否可交换
拼图完成后鼠标移动
Bug

拼图完成后将播放音乐,但鼠标移动会再次触发监听,反复重播音乐,影响体验。

Debug

声明一个全局变量boolean suc = true;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//判断拼图是否复原
int count = 0;
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COL; j++)
if (map[i][j] == i + j * ROW)//将map数组中的值与初始值比较,从而判断
count++;
if (count == ROW * COL)
{
if (suc)
{
char str[50];
playSound(winsound, 1);
sprintf_s(str, 50, "拼图完成");
beginPaint();
setTextSize(40);
paintText(WNDWIDTH - 180, 20, str);//绘制文字
endPaint();
suc = false;//使得成功效果只触发一次
}
}

最终效果

1.程序成功运行,拼图已打乱,并已加载绘制,原图片绘制在窗口右侧。

2.鼠标左键点击控制与空格相邻的上下左右的滑块往空格位移动,移动时伴有钢琴音效,不同图片音效不同;点击其他区域无响应

3.拼图复原,窗口右上角显示拼图完成,并播放一段音乐

-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道