C - 简易贪吃蛇的编写
不多废话,直接进入正题——用C编写简易贪吃蛇。附上拙劣的源码 * c-snake *
首先说明使画面动起来的原理:通过 system("cls"); 清除当前控制台的显示,再printf下一步画面进行显示,以此循环形成动画效果(类似手翻书)。因为这是在控制台,难免会有晃眼的感觉,并且不存在美工一说,所以就将就下吧。
有了使画面动起来的方法,接下来就是贪吃蛇游戏本体的制作思路了,可将游戏本体分解为以下3个部分:
1、边界,即墙:圈定一个范围,蛇只能在墙内移动,食物只能生成在墙内
2、蛇:游戏主角,可视为2部分组成——蛇头和蛇身。蛇头引导了蛇身前行的方向,也用于判定蛇是否吃到食物
3、食物:蛇的猎物,被蛇吃掉后会触发2个事件——蛇身加长、重新生成一个食物
将本体分解完后,就是解析游戏方式:蛇会自动向蛇头朝向进行移动,玩家需要控制蛇头的方向进行移动,抛却理论不说(理论上可以将蛇身占满整个边界内部),游戏结束的情况有2种:撞墙和撞身
用人话将贪吃蛇游戏理了一遍,接下来就是将人话变成真正的设计思路:
1、边界的描述:可看作一个二维数组,四周为墙,用“*”表示;内部为空,用“ ”表示
2、蛇的描述:由蛇头和蛇身组成,而蛇头可看作蛇身的特殊部分,因此实际并无蛇头一说,仅仅是表示方式不同罢了(蛇头用“@”表示,蛇身用“#”表示),从而将蛇头和蛇身的描述问题转为了蛇身的描述。而蛇身应当如何描述?蛇身由一个又一个的、连续的点组成,因此,该问题实质便是如何去描述一个点。在二维坐标中,点便是用x和y描述,所以蛇的每个蛇身(点)都需要储存x和y这2个”标识符”,同时又需要储存多个xy对,显而易见,依旧是用一个二维数组去描述蛇
3、食物的描述:食物本质上依旧是一个点,但和蛇身不同,食物有且仅有1个,所以用一个一维数组即可描述食物
4、蛇的移动:什么是移动?移动即为位置的改变,所以在确定了方向后,我们要做的仅仅是将蛇头向该方向移动后,后面的蛇身依次覆盖前一个蛇身/头,即拷贝前一个蛇身所储存的xy坐标。当吃到食物时,应当将长度+1
5、蛇的移动方向控制:那么如何控制蛇头所指向的方向呢?虽然方向是蛇头的属性之一,但可将其从蛇中分离出去,定义一个单独的变量去描述方向。当有键盘敲击输入事件发生时,获取输入值并判断输入值与方向的关系,更新方向即可
6、食物的消失与生成:当蛇头与食物的坐标相同时,食物应当消失(被吃),消失后应当生成一个新的食物,而生成食物的x和y应为随机数,且需在墙内,不能生成在蛇上
7、游戏的结束:判断蛇头的位置即可(撞墙:当蛇头的位置处于墙上时;撞身:当蛇头的位置处于蛇身上时)
有了思路,代码其实就自然而然的写出来了:
定义部分:
/*
若内部场地大小为x*y:
墙定义为char wall[y+2][x+2],+2是因为2边的边界
蛇定义为int snake[x*y][3],snake[i][0]表示x坐标,snake[i][1]表示y坐标,snake[i][2]表示该蛇身是否存在。当然亦可定义为snake[x*y][2],初始化为0,判断x和y值是否为0去确定该蛇身是否存在
食物定义为int food[3],food[0]表示x坐标,food[1]表示y坐标,food[2]表示食物是否已经存在
移动的方向定义为int direction,1/2/3/4分别对应4个方向
*/ char wall[][];
int snake[][];
int food[];
int direction = ; //方向:1-上 2-右 3-下 4-左
define
功能模块部分:
//初始化围墙属性
void init_wall()
{
extern char wall[][];
int i,j;
for(i = ; i < ; i++)
{
for(j = ; j < ; j++)
{
if(i == || i == )
wall[i][j] = '*';
else if(j == || j == )
wall[i][j] = '*';
else
wall[i][j] = ' ';
}
}
}
init_wall
//初始化蛇属性
void init_snake()
{
/*
snake[i][0]为x坐标
snake[i][1]为y坐标
snake[i][2]值为1或0 1表示存在 0表示不存在
*/
extern int snake[][];
snake[][] = ;
snake[][] = ;
snake[][] = ;
snake[][] = ;
snake[][] = ;
snake[][] = ;
snake[][] = ;
snake[][] = ;
snake[][] = ;
}
init_snake
//初始化食物属性
void init_food()
{
/*
food[0]为x坐标
food[1]为y坐标
food[2]值为1或0 1表示不存在 0表示存在
*/
extern int food[];
extern int snake[][]; int x,y;
int flag = ; //是否在蛇身的标志 1表示在 0表示不在
food[] = ; //生成食物 置0 while(flag)
{
srand(time());
x = rand()%+;
y = rand()%+;
int i;
for(i = ; i < ; i++)
{
if(snake[i][])
{
if(snake[i][] == x && snake[i][] == y)
break;
}
else
flag = ;
}
}
food[] = x;
food[] = y;
}
init_food
//在墙中生成蛇和食物
void change()
{
extern char wall[][];
extern int snake[][];
extern int food[];
int i; if(food[])
{
init_food();
} wall[food[]][food[]] = 'O'; //食物 for(i = ; i < ; i++)
{
if(snake[i][])
{
int x = snake[i][];
int y = snake[i][];
if(i == )
wall[y][x] = '@'; //蛇头
else
wall[y][x] = '#'; //蛇身
}
}
}
change
//判断是否吃到食物
int ifEat()
{
extern int snake[][];
extern int food[];
extern int score; if(snake[][] == food[] && snake[][] == food[])
{
food[] = ;
return ; //吃到返回1
}
return ; //没吃到返回0
}
ifEat
//判断是否撞墙或自身
int ifBreak()
{
extern int snake[][];
int i; if(snake[][] == || snake[][] == || snake[][] == || snake[][] == )
return ;
for(i = ; i < ; i++)
{
if(snake[][] == snake[i][] && snake[][] == snake[i][])
return ;
}
return ;
}
ifBreak
//获取输入的方向
void getKey()
{
char ch;
if(_kbhit())
{
ch = _getch();
}
switch(ch)
{
case 'w':
case 'W':
if(direction != )
direction = ;
break;
case 'd':
case 'D':
if(direction != )
direction = ;
break;
case 's':
case 'S':
if(direction != )
direction = ;
break;
case 'a':
case 'A':
if(direction != )
direction = ;
break;
default:
break;
}
}
getKey
//移动
void move()
{
extern int direction;
extern int snake[][];
extern int score;
int i = score - ;
int x,y; switch(direction)
{
case :
x = ;
y = -;
break;
case :
x = ;
y = ;
break;
case :
x = ;
y = ;
break;
case :
x = -;
y = ;
break;
default:
break;
} if(ifEat())
{
snake[score][] = snake[score-][];
snake[score][] = snake[score-][];
snake[score][] = ;
score++;
} while(i > )
{
if(snake[i][] != )
{
snake[i][] = snake[i-][];
snake[i][] = snake[i-][];
}
i--;
} snake[][] += x;
snake[][] += y;
}
move
//打印
void print_all()
{
extern char wall[][];
int i,j;
for(i = ; i < ; i++)
{
for(j = ; j < ; j++)
{
printf("%c", wall[i][j]);
}
printf("\n");
}
}
print_all
最后只需在main中按照顺序将各个模块进行调用即可
void main()
{
extern char wall[][];
extern int snake[][];
extern int score;
int speed = ;
int spot = ; init_snake();
init_food(); while()
{
getKey();
system("cls");
init_wall();
move();
change();
print_all(wall[][]);
if(ifBreak())
break;
Sleep(speed);
if(score == spot)
{
speed = 0.9*speed;
spot += ;
}
}
printf("Game Over\n");
printf("score:%d\n",score);
system("pause");
}
main
C - 简易贪吃蛇的编写的更多相关文章
- Luat Inside | 致敬经典,使用Air724UG制作简易贪吃蛇
作者简介: 打盹的消防车--活跃于Luat社群的新生代全能开发者,东北小伙儿爽朗幽默.好学敏思,更是实力行动派.幼年曾手握火红炽铁而后全然无恙,堪称魔幻经历:如今热衷于各类嵌入式软硬件研究,快意物联江 ...
- <Android 应用 之路> 简易贪吃蛇
最简单的贪吃蛇 最近想着忙里偷闲写点简单的Android应用,增加一些生活乐趣,由于平时工作主要精力并不是集中在书写apk上,更多的是解决代码问题和维护模块稳定,但是写代码本身是一件比较有趣的事情,因 ...
- Python实例:贪吃蛇(简单贪吃蛇编写)🐍
d=====( ̄▽ ̄*)b 叮~ Python -- 简易贪吃蛇实现 目录: 1.基本原理 2.需要学习的库 3.代码实现 1.基本原理 基本贪吃蛇所需要的东西其实很少,只需要有一块让蛇动的屏幕, 在 ...
- javascript 编写的贪吃蛇
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- pygame编写贪吃蛇
一直想用pygame做一个小游戏的,可是因为拖延症的缘故一直没有动,结果那天看到了一个12岁的国际友人小盆友用pygame做的一款塔防游戏,突然感觉已经落后超级远了,所以心血来潮做小游戏了.高中陪伴我 ...
- 贪吃蛇(简易版)Leslie5205912著
# include <stdio.h># include <string.h># include <windows.h># include <stdlib.h ...
- JavaScript 实现简易版贪吃蛇(Day_13)
时光永远在变迁,你始终要丢下过去. 使用语言 JavaScript 概述 运用JavaScript 实现简易版<贪吃蛇>. Html 页面 1 <!DOCTYPE htm ...
- 用OpenGL简单编写的一个最简单贪吃蛇游戏
刚学OpenGL的时候,写的一个最简单的贪吃蛇游戏代码 如下: //贪吃蛇游戏 #include<stdio.h> #include<stdlib.h> #include< ...
- Javascript基础示例:用JS写简易版贪吃蛇(面向对象)
废话不多说,代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...
随机推荐
- 【java设计模式】-06原型模式
原型模式简述 定义: 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象 ,也就是通过复制现有对象实例产生新的对象,也就是所谓的"克隆" 实现方式: 1.实现Cl ...
- UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
先看第一题,有n*m个点,求在这些点中,有多少条直线,经过了至少两点,且不是水平的也不是竖直的. 分析:由于对称性,我们只要求一个方向的线即可.该题分成两个过程,第一个过程是求出n*m的矩形中,dp[ ...
- 【Redis 设置Redis使用LRU算法】
转自:http://ifeve.com/redis-lru/ 本文将介绍Redis在生产环境中使用的Redis的LRU策略,以及自己动手实现的LRU算法(php) 1.设置Redis使用LRU算法 L ...
- Spring学习随笔(2):Eclipse下Spring环境配置+入门项目
1 准备工作 (按需下载) Eclipse 下载:http://www.eclipse.org/downloads/eclipse-packages/ : Spring 下载:http://repo. ...
- LeetCode 221. 最大正方形(Maximal Square)
题目描述 在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积. 示例: 输入: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 输出: ...
- Failed to execute aapt
Failed to execute aapt 没错,看到这个表示你的资源出错了.不用想别的. 比如: Failed to execute aapt com.android.ide.common.pro ...
- error: atomic: 没有那个文件或目录
Linux下编译的时候遇到一个问题,就是提示 error: atomic: 没有那个文件或目录 执行的命令是gcc -o myCXXLog myCXXLog.c 经过网上搜索,解决方法有二 (1 ...
- 阿里云安装 fastdfs 总结
还要开放 23000 22122,添加进安全组
- 一百一十:CMS系统之剩余菜单栏的页面和视图
增加所有剩余菜单的页面,并用视图渲染,方便后面调试权限控制 {% extends 'cms/cms_base.html' %} {% block title %}板块管理{% endblock %} ...
- 用Red5搭建支持WEB播放的实时监控视频
用Red5搭建支持WEB播放的实时监控视频 1. 下载Red5:https://github.com/Red5/red5-server/releases 下载了Red5 1.0.6 release的Z ...