大一学了C语言有什么用,写个拼图小游戏表白女神,快学起来吧

mac2022-06-30  17

国庆长假,男朋友女朋友们都出去旅游了,而我只能和我的idol隔着手机单相思,不过我可以用表白神器代码来一波骚操作,自慰一下我苦涩又空虚的灵魂。亲测可行,运行时在文件夹下插入两张图片即可女神\空白,空白图片可自行截取网页等空白区域,整体游戏效果图如下,附以源码链接:https://paste.ubuntu.com/p/z39f7HKGSn/

文章目录

一、.h与main二、绘制菜单三、加载资源四、绘制拼图五、游戏过程

一、.h与main

首先,若想使用#include<graphics.h>需要安装EasyX。EasyX是一个轻量级的简单的C++图形库,可以用来做些简单的演示2d类游戏。现提供官网下载地址:EasyX 注意当安装过程检测到支持的编程软件,Visual C++2017、Visual C++2019即是本机上的VS2017、VS2019,小编在此亲测过,直接安装打开VS即可编译调用该图形库 当程序调用getchar()时,程序就等着用户按键。用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止,用在此处是为了防止闪屏 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<graphics.h> IMAGE img, blank; int array1D[9] = { 0 }; int array2D[3][3] = { 0 }; int main() { drawmenu(); initgraph(300, 300); loadresource(); playgame(); closegraph(); return 0; }

二、绘制菜单

字体样式设置通过查找路径 C:\Windows\Fonts,打开字体库对应字体名称,最终菜单界面如下图所示

void drawmenu() { initgraph(500, 600); setbkcolor(WHITE);//窗口设置为白色 cleardevice(); setfillcolor(BLUE); settextstyle(20, 0, "华文行楷");//宽、高、字体,0:自适应 setbkmode(TRANSPARENT);//透明方式去掉文字背景 fillrectangle(200, 100, 300, 150);//(int x,int y,int xx,int yy) fillrectangle(200, 100 + 70, 300, 150 + 70); outtextxy(200 + 15, 100 + 15, "开始游戏"); outtextxy(200 + 15, 100 + 70 + 15, "退出游戏"); settextcolor(RED); outtextxy(200, 400, "made by xiexie"); MOUSEMSG m; while (1) { m = GetMouseMsg(); if (m.x >= 200 && m.x <= 300 && m.y >= 100 && m.y <= 150) { setlinecolor(RED); rectangle(200 - 5, 100 - 5, 300 + 5, 150 + 5); if (m.uMsg == WM_LBUTTONDOWN) break; } else if (m.x >= 200 && m.x <= 300 && m.y >= 100 + 70 && m.y <= 150 + 70) { setlinecolor(RED); rectangle(200 - 5, 170 - 5, 300 + 5, 220 + 5); if (m.uMsg == WM_LBUTTONDOWN) break; } else { setlinecolor(WHITE); rectangle(200 - 5, 100 - 5, 300 + 5, 150 + 5); rectangle(200 - 5, 170 - 5, 300 + 5, 220 + 5); } } closegraph(); }

三、加载资源

srand函数是随机数发生器的初始化函数。原形:void srand(unsigned seed) srand根据seed返回一个随机数但是一个伪随机数,多次编译产生的随机数是一样的,除非给一个变化的种子 因此使用系统时间来初始化time函数可获得当前系统时间srand ((unsigned)time(NULL)) 从单目运算符的优先级别从右到左考虑,返回秒数后,最后强制转化为unsigned int 型整数rand函数经常和srand函数一起使用,rand函数每一次被调用的时候,都会先查看srand函数是否被调用。如果被调用,则会调用srand(seed)初始化它的随机值,如果没被调用,则会默认调用srand(1)初始化此部分代码段为拼图游戏的核心,将随机初始化一维数组的值赋给二维数组,使得每次拼图的原始界面都不同图片的加载需要将两张图片 女神\空白 存储在工程文件夹的直接层下面,空白图用于制作右下角可供周围拼图块移动调整的区域 /*此代码块使用的头文件 #include<stdlib.h> #include<time.h> #include<graphics.h> */ void loadresource() { srand((unsigned int)time(NULL)); int length = 8; int pos = 0; int i, j; //1.给一维数组初始化0-15 for (i = 0; i < 8; i++) { array1D[i] = i; } //2.随机出来一个下表 for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { //单独处理最后一个位置 if (i == 2 && j == 2) { array2D[2][2] = 8; break; } pos = rand() % length; array2D[i][j] = array1D[pos]; for (int k = pos; k < length; k++) { array1D[k] = array1D[k + 1]; } length--; } if (i == 2 && j == 2) { array2D[2][2] = 8; break; } } //缩放加载 loadimage(&img, "圣经经.jpg", 300, 300); loadimage(&blank, "blank.jpg", 100, 100); }

四、绘制拼图

// 绘制图像的各个参数(指定宽高和起始位置) void putimage( int dstX, // 绘制位置的 x 坐标 int dstY, // 绘制位置的 y 坐标 int dstWidth, // 绘制的宽度 int dstHeight, // 绘制的高度 IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针 int srcX, // 绘制内容在 IMAGE 对象中的左上角 x 坐标 int srcY, // 绘制内容在 IMAGE 对象中的左上角 y 坐标 );

根据打乱顺序的二维数组中的值去拿照片中相应的位置,效果图如下:

void drawmap() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { int x = i * 100; int y = j * 100; switch (array2D[i][j]) { case 0: case 1: case 2: putimage(x, y, 100, 100, &img, (array2D[i][j] % 3) * 100, 0); break; case 3: case 4: case 5: putimage(x, y, 100, 100, &img, (array2D[i][j] % 3) * 100, 100); break; case 6: case 7: putimage(x, y, 100, 100, &img, (array2D[i][j] % 3) * 100, 200); break; case 8: putimage(x, y, &blank); break; } } } }

五、游戏过程

这里是我被坑最久的代码区,主要原因是鼠标操作导致二维数组下标溢出。VS2019会显示报错(好评++),同时我还用了VC++6.0,编译通过也能加载拼图资源(没有显示具体报错内容),但在playgame,某些边界的拼图块无法和空白块交换位置导致界面卡住

解决之路还挺曲折的,先是自己盯着警告,最后也明白错误的可能根源,但没有想出合适的解决办法,最后万分感谢莫老师,远程控制帮我写了两个子函数,bug消失了,游戏过程如下

//温馨提示,不要采用这种定位方式 for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { if (array2D[i][j] == 8) { break; } } if (array2D[i][j] == 8) { break; } } //此处为正解 int searchPos_i() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (array2D[i][j] == 8) { return i; } } } return -1; } int searchPos_j() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (array2D[i][j] == 8) { return j; } } } return -1; } void playgame() { MOUSEMSG m; int i, j; int j_Mouse, i_Mouse; while (1) { drawmap();//每次循环开始都要重新定位白块的坐标位置 i = searchPos_i(); j = searchPos_j(); m = GetMouseMsg(); switch (m.uMsg) { case WM_LBUTTONDOWN: i_Mouse = m.x / 100; j_Mouse = m.y / 100; if (j_Mouse == j + 1 && i_Mouse == i) { array2D[i][j] = array2D[i_Mouse][j_Mouse]; array2D[i_Mouse][j_Mouse] = 8; } if (j_Mouse == j - 1 && i_Mouse == i) { array2D[i][j] = array2D[i_Mouse][j_Mouse]; array2D[i_Mouse][j_Mouse] = 8; } if (i_Mouse == i - 1 && j_Mouse == j) { array2D[i][j] = array2D[i_Mouse][j_Mouse]; array2D[i_Mouse][j_Mouse] = 8; } if (i_Mouse == i + 1 && j_Mouse == j) { array2D[i][j] = array2D[i_Mouse][j_Mouse]; array2D[i_Mouse][j_Mouse] = 8; } break; } } }

最后,感谢大家抽出时间阅读小编的文章,我会继续努力,用代码写出好玩的东西的!

祝大家国庆快乐呀

最新回复(0)