今天做了个拼图小游戏,用来以消遣闲暇时光;
因为比较喜欢海贼王,所以就用了一张路飞的图片,各位可以根据自己的喜好,自定义图片。
而且因为C语言没有对应的图形库,所以我在此处用的是EasyX_2018春分版
下面是代码,大家可以借鉴一下;
#include <graphics.h> // 引用图形库头文件
#include <conio.h>
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#define N 5 //声明为N*N的拼图
#define WinW 480 //宏定义图形的长宽
#define WinH 480
void DrawPic(int layout[N][N], IMAGE*img)//对图片的操作,程序灵魂
{
setfillcolor(RGB(0, 0, 0)); //设置当前的填充颜色
int x, y, w, h, x1, y1;
w = WinW / N;
h = WinH / N; //计算每一个小块所占的长和宽
for (int i = 0; i < N; i++)//循环遍历整个数组
{
for (int j = 0; j < N; j++)
{
x = j*w;
y = i*h;
if (layout[i][j] >= 0)
{
x1 = layout[i][j] % N*w;//计算数组中每个数对应的矩形块的位置
y1 = layout[i][j] / N*h;
putimage(x, y, w, h, img, x1, y1);//把图片中左顶点坐标为(x,y)长宽分别为
//w,h的矩形移到左顶点坐标为(x1,y1)的位置
}
else
{
fillrectangle(x, y, x + w, y + h);//用于画填充矩形,把layout[i][j]<0的矩形块改为背景色
}
}
}
int x2, y2;
for (int i = 0; i < N - 1; i++)//划线,把一整幅图分割开
{
x1 = 0;
x2 = WinW;
y1 = y2 = WinH / N*(i + 1);
setlinecolor(RGB(0, 0, 0));//线的颜色
line(x1, y1, x2, y2);//直线的两个端点
}
for (int i = 0; i < N - 1; i++)//划线,把一整幅图分割开
{
x1 = x2 = WinW / N*(i + 1);
y1 = 0;
y2 = WinH;
setlinecolor(RGB(0, 0, 0));
line(x1, y1, x2, y2);
}
}
int FindBlank(int layout[N][N])//寻找要移动的图形块
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (layout[i][j]< 0)
{
return i*N + j;//返回此时要移动块的位置
}
}
}
}
void Moveleft(int layout[N][N])//对图形快进行上移操作
{
int index = FindBlank(layout);
int i = index / N;
int j = index % N;
int t;
if (j - 1 >= 0)//找到要移动的块和他的上一个块进行移动,若此块为最上面的一个,则不移动
{
t = layout[i][j];
layout[i][j] = layout[i][j - 1];
layout[i][j - 1] = t;
}
}
void MoveRight(int layout[N][N])//对图形快进行下移操作
{
int index = FindBlank(layout);
int i = index / N;
int j = index % N;
int t;
if (j + 1 <N)
{
t = layout[i][j];
layout[i][j] = layout[i][j + 1];
layout[i][j + 1] = t;
}
}
void MoveUp(int layout[N][N])//对图形快进行左移操作
{
int index = FindBlank(layout);
int i = index / N;
int j = index % N;
int t;
if (i - 1 >= 0)
{
t = layout[i][j];
layout[i][j] = layout[i - 1][j];
layout[i - 1][j] = t;
}
}
void MoveDown(int layout[N][N])//对图形快进行右移操作
{
int index = FindBlank(layout);
int i = index / N;
int j = index % N;
int t;
if (i + 1 < N)
{
t = layout[i][j];
layout[i][j] = layout[i + 1][j];
layout[i + 1][j] = t;
}
}
int GameOver(int layout[N][N])//判断游戏是否结束
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (layout[i][j] != i*N + j)
{
goto lp;
}
}
}
lp:if ((i == N - 1) && (j == N - 1))
{
return 0;
}
return 1;
}
int main()
{
initgraph(WinW, WinH); // 创建绘图窗口
IMAGE img;
loadimage(&img, _T("./pic.jpg"));//插入图片
//putimage(0, 0, &img);
//Delineate();
int layout[N][N];//定义数组
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
layout[i][j] = i * 5 + j;//为数组赋值
}
}
srand((unsigned)time(NULL));//根据电脑当前时间随机生成一个数
/*layout[N - 1][N - 1] = -1;*/
for (int i = 0; i < 25; i++)//将图片随机打乱
{
int j, t;
i = rand() % 25;//根据随机生成的数,生成一个[0-24]的数
j = rand() % 25;
t = layout[i / N][i % N];
layout[i / N][i % N] = layout[j / N][j % N];
layout[j / N][j % N] = t;
}
for (int i = 0; i < N; i++)//遍历随机乱序后的数组
{
for (int j = 0; j < N; j++)
{
int t;
if (layout[i][j] == 24)//找到值为24的数组元素,和数组最后一个元素交换,并
//把最后一个元素的值变为可移动块的值-1
{
layout[i][j] = layout[N - 1][N - 1];
layout[N - 1][N - 1] = -1;
}
}
}
DrawPic(layout, &img);//调用函数绘出此时的图片
while (GameOver(layout))//对图片进行移动操作
{
char key;
key = _getch();
switch (key)
{
case 'a':
case 'A':
Moveleft(layout);
break;
case 'd':
case 'D':
MoveRight(layout);
break;
case 'w':
case 'W':
MoveUp(layout);
break;
case 's':
case 'S':
MoveDown(layout);
break;
}
DrawPic(layout, &img);//没此移动完一次要对图片从新绘制,显示新的图片
}
//DrawPic(layout, &img);
//closegraph(); // 关闭绘图窗口
//printf("你真是个小天才!\n");
TCHAR s[] = _T("Very good!");
outtextxy(WinW / 2, WinH / 2, s);//在图形框中显示Very good!字样表明图片已拼好
}
代码有一点问题,就是随机函数随机后的图形不一定可以拼出来图片,因为拼出图片也需要一定的条件,不是所有的情况都可以拼出图片;
如果有知道什么情况下拼不出图片的可以留言告诉我,谢谢~!
如果有想要EasyX_2018春分版的可以留言,我可以给你私发,应为CSDN上好像不能上传文件夹;