c语言编写的小游戏

你好,亲爱的朋友们,你好!

好久没用C语言写小游戏了。今天,我无事可做。我们开始吧。过程相当流畅,代码也相对简单。今天分享给大家~

c语言编写的小游戏

一、介绍

开发语言:C语言

开发工具:VS2022/2019,VScode,Dev-C++都有(如果没有VS,可以在文末获取)

不多说多余的话,先来看看效果图:

游戏中的人物、箱子、墙壁、球都是由人物组成的。通过wasd键移动,规则就是推箱子的规则,就不多说了。

二、代码实现

就代码而言,我尽量做到详细。希望大家能理解~

不想动的好兄弟也可以直接获取源代码(但不建议),你可以在文末获取!

(1)方法列表

//主函数

void main();

//初始化一些数据

initData();

//在控制台上打印地图

draw map();

//上移

move up();

//向左移动

向左移动()

//向下移动

下移()

//向右移动

moveRight();

这些方法都是顾名思义,用意非常明确。只是initData可能不知道具体用途,但是没有大问题。唯一的问题是上下左右的顺序可能会害死几个强迫症患者,哈哈。

(2)参数表

为了方便起见,我将include和宏定义放在了参数列表中。

//导入函数库

# include & ltstdio.h & gt

# include & ltstdlib.h & gt

# include & ltconio.h & gt

//宏定义

#定义宽度8

#定义高度8

//定义映射数组。二维数组有二维,地图也是二维矩形。

int map[HEIGHT][WIDTH] = {

{0, 0, 1, 1, 1, 0, 0, 0},

{0, 0, 1, 4, 1, 0, 0, 0},

{0, 0, 1, 0, 1, 1, 1, 1},

{1, 1, 1, 3, 0, 3, 4, 1},

{1, 4, 0, 3, 2, 1, 1, 1},

{1, 1, 1, 1, 3, 1, 0, 0},

{0, 0, 0, 1, 4, 1, 0, 0},

{0, 0, 0, 1, 1, 1, 0, 0}

};

//人的位置,在二维地图中,我们可以用坐标来表示一个人的位置,就像经纬度一样。

int x,y;

//箱子的数量,推箱子的时候一定要有箱子。

int boxs

这里参数不多,其中横坐标为X,纵坐标为y,另外,这里还有一些关于map的事情:

/**

* 0表示空

* 1表示墙壁。

* 2表示人

* 3表示一个盒子。

* 4表示目的地(球)

* 5表示完成的盒子。

*/

(3)功能的具体分析

接下来,让我们一次分析一个函数。

1.主要功能

int main(int argc,char *argv[]) {

充电方向;//存储键盘按下的方向。

initData();//初始化一些数据

//开始游戏的循环。这是一个无止境的循环,每按一次按钮就会循环一次。

while(1){

//在每个周期开始时清除屏幕

系统(& # 34;cls & # 34);

//画一张地图

draw map();

//判断,当盒数为0时!0为真,然后跳出循环(结束游戏)

如果(!方框){

打破;

}

//键盘输入方向,这里用getch,因为getch读取的字符不会显示在屏幕上。

direction = getch();

//使用开关判断用户输入的方向

开关(方向){

案例& # 39;w & # 39:

//按下W时,调用move up函数。

move up();

打破;

案例& # 39;一& # 39;:

//按A时,调用左移函数。

move left();

打破;

案例& # 39;s & # 39:

move down();

打破;

案例& # 39;d & # 39:

moveRight();

打破;

}

}

//跳出循环后,运行这条语句,游戏就结束了。

printf(& # 34;祝贺你完成游戏!※");

返回0;

}

我来说说过程。循环之外没什么特别的。InitData()只是一些简单数据的初始化,不用太在意。循环的一般过程如下:

清除屏幕

画一张地图

判断游戏是否结束。

反馈用户按下的按钮。

进入循环,先清屏,再画地图,然后判断游戏是否结束。可能大家都不是很理解这个顺序,所以这里先不考虑判定游戏结束的问题。我们把清屏和绘制地图结合在一起,简称为“重绘地图”,没有先考虑游戏结束的判断,所以把流程简化为“重绘地图+响应用户操作”。简单来说,用户按下按钮,我改变地图。

2、initData()

void initData(){

int i,j;

//加载数据时,让用户等待。一般来说,加载数据更快。

printf(& # 34;游戏正在加载,请稍候…");

//遍历地图中的数据

for(I = 0;我& lt身高;i++){

for(j = 0;j & lt宽度;j++){

//当遍历到2(人)时,记录人的坐标。x和y是前面定义的全局变量。

if(map[i][j] == 2){

x = j;

y = I;

}

//当遍历到3时,盒数增加。Boxs是前面定义的全局变量。

if(map[i][j] == 3){

box s++;

}

}

}

}

这个方法很简单,就是遍历地图,然后初始化人的位置和箱子的数量。这里需要注意的一点是,内环是宽度还是外环是宽度。

如图,遍历过程中。外部循环控制行数,即高度。那么内环应该是宽度。

3、绘制地图()

void drawMap(){

int i,j;

for(I = 0;我& lt宽度;i++){

for(j = 0;j & lt身高;j++){

开关(映射[i][j]){

案例0:

printf(& # 34;");

打破;

案例1:

printf(& # 34;■");

打破;

案例二:

printf(& # 34;♀");

打破;

案例三:

printf(& # 34;◆");

打破;

案例4:

printf(& # 34;●");

打破;

案例5:

printf(& # 34;★");

打破;

}

}

printf(& # 34;\ n & # 34);

}

}

这里也很简单,在map中可变元素,然后通过switch判断应该输出什么。然后内部循环在每次结束时循环。

4、moveUp()

这个函数的内容很多,所以我想说一下大概的思路:

晋升有两种方式。

1.正面是空白色

这种情况下有两个步骤。

(1)将一个人的当前位置设置为空 white (0),

(2)假设人前面的位置被设置为人(2)

2.前面是一个盒子

前面是盒子有三种情况。

1.盒子正面是空白色。

移动人和箱子有三个步骤。

(1)将人的当前位置设置为空(0)

(2)将框位置设置为person (2)

(3)将盒子的正面设置为盒子(3)

2.盒子的前面是一面墙

在这种情况下,不需要做任何事情。

3.盒子的前面是终点

这种情况下有四个步骤。

(1)将人的位置设置为空(0)

(2)将方框的位置设置为一个人(2)

(3)将结束位置设置为★ (5)

(4)盒箱数量减少一个。

3.前面是一堵墙

这种情况是最简单的,什么都不需要做。

4.前面是终点

在这里我不会想太多,所以这种情况我什么都不做。(如果更改地图,可能需要修改代码)

具体代码如下,我都写在评论里了:

void moveUp(){

//定义存储在变量中的字符上方的坐标。

int ux,uy;

//上面没有元素的时候直接返回(其实人不可能在边上)

if(y == 0){

返回;

}

//记录上面的坐标,其中X为水平,Y为垂直,所有ux = x,uy = Y-1;

UX = x;

uy = y-1;

//完成的盒子在上面。

if(map[uy][ux] == 5){

返回;

}

//如果上面有墙,直接返回。这个可以和上面的判断结合起来,这里为了清楚起见单独写出来。

if(map[uy][ux] == 1){

返回;

}

//假设上面有一个盒子。

if(map[uy][ux] == 3){

//判断盒子上方是否有墙。

if(map[uy – 1][ux] == 1){

返回;

}

//判断盒子顶部是否为终点。

if(map[uy – 1][ux] == 4){

//将框中的内容赋给5★

map[uy-1][UX]= 5;

map[uy][UX]= 0;

//盒子数减1。

方框-;

}否则{

//移动盒子

map[uy-1][UX]= 3;

}

}

//以上回报情况都没有遇到的时候,人肯定会动的。移动操作如下。

map[y][x]= 0;

map[uy][UX]= 2;

//更新人的坐标

y = uy

}

这是一个方向,其他方向要考虑的问题和之前一样,就不赘述了。

6、向左移动()

这里大致和上面一样,就是记录左坐标的时候,应该是lx = x-1。

void moveLeft(){

//定义变量来存储字符左侧的坐标。

int lx,ly;

//左边没有元素时,直接返回。

if(x == 0){

返回;

}

//记录左边的坐标

LX = x-1;

ly = y;

//左边是完成的方框。

if(map[ly][lx] == 5){

返回;

}

//假设左边是墙,直接返回。

if(map[ly][lx] == 1){

返回;

}

//假设左边有一个盒子。

if(map[ly][lx] == 3){

//判断盒子左侧是否是墙。

if(map[ly][lx – 1] == 1){

返回;

}

//判断盒子左边是否是球。

if(map[ly][lx – 1] == 4){

//将框的左边内容赋给5★

map[ly][LX-1]= 5;

map[ly][LX]= 0;

//盒子数减1。

方框-;

}否则{

//移动盒子

map[ly][LX-1]= 3;

}

}

map[y][x]= 0;

map[ly][LX]= 2;

x = lx

}

7、下移()

这里判断边界的时候,判断是y == HEIGHT-1。

void moveDown(){

//定义存储变量的字符下方的坐标。

int dx,dy;

//下面没有元素时,直接返回。

if(y == HEIGHT – 1){

返回;

}

//记录下面的坐标

dx = x;

dy = y+1;

//下面是完成的方框。

if(map[dy][dx] == 5){

返回;

}

//假设下面有墙,直接返回。

if(map[dy][dx] == 1){

返回;

}

//假设下面有一个盒子。

if(map[dy][dx] == 3){

//判断盒子下面是否有墙。

if(map[dy + 1][dx] == 1){

返回;

}

//判断盒子下面是否有球。

if(map[dy + 1][dx] == 4){

//将框下面的内容赋值为5★

map[dy+1][dx]= 5;

map[dy][dx]= 0;

//盒子数减1。

方框-;

}否则{

//移动盒子

map[dy+1][dx]= 3;

}

}

map[y][x]= 0;

map[dy][dx]= 2;

y = dy

}

8、moveRight()

这里没什么特别要说的:

void moveRight(){

//定义变量来存储字符右侧的坐标。

int rx,ry;

//当右边没有元素时,直接返回。

if(x == WIDTH – 1){

返回;

}

//记录右边的坐标

rx = x+1;

ry = y;

//完成的框在右边。

if(map[ry][rx] == 5){

返回;

}

//假设右边是墙,直接返回。

if(map[ry][rx] == 1){

返回;

}

//假设盒子在右边。

if(map[ry][rx] == 3){

//判断盒子右侧是否为墙壁。

if(map[ry][rx + 1] == 1){

返回;

}

//判断盒子左边是否是球。

if(map[ry][rx + 1] == 4){

//将框右侧的内容赋值为5★

map[ry][rx+1]= 5;

map[ry][rx]= 0;

//盒子数减1。

方框-;

}否则{

//移动盒子

map[ry][rx+1]= 3;

}

}

map[y][x]= 0;

map[ry][rx]= 2;

x = rx

}

三、总结

现在我们来回顾一下最初的操作步骤。

清除屏幕

画一张地图

判断游戏是否结束。

反馈用户按下的按钮。

这里把判断游戏是否结束放在重绘图像的后面,因为反馈给用户的只是地图中的数据发生了变化,实际上最后一个推到最后的盒子的图像还没有显示出来,所以重绘后需要判断是否结束游戏。

代码有很多冗余,一方面是想让大家更好的理解,另一方面也是我懒。哈哈,代码运行的时候没有问题。我会上传源代码和源程序。有兴趣可以下载,或者直接复制代码运行也没问题。

需要完整源代码对比的同学可以在文末获取!

推箱子教程到此结束。赶紧来试试吧!

源码素材获取通道:

可以关注边肖,后台私信我:【编程交流】哦!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论