自顶向下设计C语言贪吃蛇
来源:互联网 发布:电子琴入门软件 编辑:程序博客网 时间:2024/05/21 10:46
本篇博客适于c语言界的小白,大神请移步~~~
关于自顶向下,之前写的一篇博客TOP-DOWN里面有记录一丢丢。
言归正传,自顶向下设计的思路就是break down
设计思路
相信大家都有玩过贪吃蛇的游戏,贪吃蛇可分解为以下部分:
1、框架、蛇的表示
2、将图形输出
3、移动蛇的位置
4、食物的出现与消失(被吃)
5、撞墙over
下面开始逐个击破。
start
1、框架、蛇的表示
因为蛇、食物都在框架里面,那么单纯c语言输出,必须是将其全部囊括在一个字符数组里面,即char screen[15][15], 表示15*15的框架。
然后需要明白的一点就是:移动的过程其实只是蛇尾与蛇头的移动
用面向对象的方法,蛇头(head)、蛇尾(tail)的属性为x,y坐标,移动方向。将它们的信息储存在结构体turn中
typedef struct T{ int x; int y; char dir;}turn;turn tail, head;
将框架与蛇初始化:
void initial(char(*Screen)[15])//初始化输出数组{ for (i = 0; i < 15; i++) { for (j = 0; j < 15; j++) { if (i == 0 || j == 0 || j == 14 || i == 14) Screen[i][j] = '#'; else Screen[i][j] = ' '; } } Screen[1][1] = '*';//*表示尾巴 Screen[1][2] = Screen[1][3] = 'O';//O表示身体 Screen[1][4] = '@';//@表示头 tail.x = 1; tail.y = 1; tail.dir = 'd'; head.x = 1; head.y = 4; head.dir = 'd';}
2、输出看看
out (screen);void out(char(*SCREEN)[15]){ for (i = 0; i < 15; i++) { for (j = 0; j < 15; j++) { printf("%c", SCREEN[i][j]); } printf("\n"); }}
如图
3、移动蛇的位置
蛇分为两种行进,前进与转弯,这里的转弯包括蛇尾与蛇头的转弯。
(1)前进
void move(turn *Tail, turn *Head){ screen[Tail->x][Tail->y] = ' '; switch (Tail->dir)//尾巴向着蛇尾的方向前进 { case 'd'://s/S、d/D、w/W、a/A分别表示下、右、上、左 case 'D': Tail->y++; break; case 'a': case 'A': Tail->y--; break; case 'w': case 'W': Tail->x--; break; case 's': case 'S': Tail->x++; break; default: break; } screen[Tail->x][Tail->y] = '*'; screen[Head->x][Head->y] = 'O'; switch (Head->dir)//头向着头的方向前进 { case 'd': case 'D': Head->y++; break; case 'a': case 'A': Head->y--; break; case 'w': case 'W': Head->x--; break; case 's': case 'S': Head->x++; default: break; } screen[Head->x][Head->y] = '@';}
(2)转弯
蛇头的转弯比较容易,输入方向,改变head.dir就可以了。
如下
if (_kbhit())//判断是否有输入方向 { change = getchar();//记录方向 head.dir = change;//头部方向变为所记录的方向 Ticks();//Tick是函数,作用下面解释 } Free();//Free是函数,作用下面解释
那么蛇尾就尴尬了,当前输入的方向并不能改变tail.dir。
那怎么办呢??
首先我们知道,蛇尾运行到某些位置会转弯,那么把那些位置记下来,看看蛇尾是否在那个位置即可。
记下位置属性:
turn ticks[14];int times=0;//记录位置数量void Ticks()//增加位置{ ticks[times] = head;//增加的位置恰好就蛇头的位置 times++;}void Free()//减少位置{ int n; if (screen[ticks[0].x][ticks[0].y] == '*') { tail.dir = ticks[0].dir; for (n = 0; n < times; n++) { ticks[n] = ticks[n + 1];//第一个位置要删除,将后面的位置信息给前一个 } times--; }}
4、食物的出现与消失
首先明白:屏幕上始终只有一个食物,一个食物的消失伴随另一个食物的出现。
那么,就让它消失吧!
int food[2]={1,4};//初始化食物的位置刚好在蛇头void eat(){ srand(time(NULL)); if (head.x == food[0] && head.y == food[1]) //蛇头坐标与食物坐标相同,就被吃掉 { screen[head.x][head.y] = 'O';//食物位置变成身体的一节 switch (head.dir)//蛇头位置向前 { case 'd': case 'D': head.y++; break; case 'a': case 'A': head.y--; break; case 'w': case 'W': head.x--; break; case 's': case 'S': head.x++; default: break; } screen[head.x][head.y] = '@';重新制造蛇头 while (screen[food[0]][food[1]] != ' ') {//制造食物,随机食物坐标不在蛇身 food[0] = rand() % 13 + 1;//坐标范围1~13 food[1] = rand() % 13 + 1; } screen[food[0]][food[1]] = '$';//$是食物 }}
5、撞墙over
肯定是头撞墙。
if (head.x == 0 || head.y == 14 || head.x == 14 || head.y == 0) { printf("game over"); break;//这里是跳出主循环 }
主函数完整代码,其中有些部分已在前面出现
int main(){ char change; initial(screen); out(screen); eat(); while (1) { if (_kbhit()) { change = getchar(); head.dir = change; Ticks(); } Free(); move(&tail, &head); eat(); system("cls");//清屏 out(screen); if (head.x == 0 || head.y == 14 || head.x == 14 || head.y == 0) { break; } Sleep(500);//延时500毫秒 } system("cls"); printf("\n game over!\n"); system("pause"); return 0;}
将主函数与辅助函数整合在一起,如下
#include <stdio.h>#include <stdlib.h>#include<string.h>#include<time.h>#include<conio.h>#include<Windows.h>char screen[15][15];int i, j, times=0, food[2] = { 1,4 };typedef struct T{ int x; int y; char dir;}turn;turn ticks[14], tail, head;void initial(char(*Screen)[15])//初始化输出数组{ for (i = 0; i < 15; i++) { for (j = 0; j < 15; j++) { if (i == 0 || j == 0 || j == 14 || i == 14) Screen[i][j] = '#'; else Screen[i][j] = ' '; } } Screen[1][1] = '*'; Screen[1][2] = Screen[1][3] = 'O'; Screen[1][4] = '@'; for (i = 0; i < 14; i++) { ticks[i].x = 0; ticks[i].y = 0; } tail.x = 1; tail.y = 1; tail.dir = 'd'; head.x = 1; head.y = 4; head.dir = 'd';}void out(char(*SCREEN)[15]){ for (i = 0; i < 15; i++) { for (j = 0; j < 15; j++) { printf("%c", SCREEN[i][j]); } printf("\n"); }}void move(turn *Tail, turn *Head){ screen[Tail->x][Tail->y] = ' '; switch (Tail->dir) { case 'd': case 'D': Tail->y++; break; case 'a': case 'A': Tail->y--; break; case 'w': case 'W': Tail->x--; break; case 's': case 'S': Tail->x++; break; default: break; } screen[Tail->x][Tail->y] = '*'; screen[Head->x][Head->y] = 'O'; switch (Head->dir) { case 'd': case 'D': Head->y++; break; case 'a': case 'A': Head->y--; break; case 'w': case 'W': Head->x--; break; case 's': case 'S': Head->x++; default: break; } screen[Head->x][Head->y] = '@';}void eat(){ srand(time(NULL)); if (head.x == food[0] && head.y == food[1]) { screen[head.x][head.y] = 'O'; switch (head.dir) { case 'd': case 'D': head.y++; break; case 'a': case 'A': head.y--; break; case 'w': case 'W': head.x--; break; case 's': case 'S': head.x++; default: break; } screen[head.x][head.y] = '@'; while (screen[food[0]][food[1]] != ' ') { food[0] = rand() % 13 + 1; food[1] = rand() % 13 + 1; } screen[food[0]][food[1]] = '$'; }}void Ticks(){ ticks[times] = head; times++;}void Free(){ int n; if (screen[ticks[0].x][ticks[0].y] == '*') { tail.dir = ticks[0].dir; for (n = 0; n < times; n++) { ticks[n] = ticks[n + 1]; } times--; }}int main(){ char change; initial(screen); out(screen); eat(); while (1) { if (_kbhit()) { change = getchar(); head.dir = change; Ticks(); } Free(); move(&tail, &head); eat(); system("cls"); out(screen); if (head.x == 0 || head.y == 14 || head.x == 14 || head.y == 0) { break; } Sleep(500); } system("cls"); printf("\n game over!\n"); system("pause"); return 0;}
阅读全文
0 0
- 自顶向下设计C语言贪吃蛇
- 自顶向下设计
- 自顶向下伸展树头文件C语言
- 自顶向下伸展树实现文件C语言
- 简要叙述“自顶向下设计”
- 自顶向下的设计方法
- 自顶向下,精益求精
- 自顶向下
- 自顶向下语法分析器的设计与实现
- 自顶向下、逐步求精的算法设计
- python自顶向下的设计方法进行体育竞技分析
- 基于python的爬虫---自顶向下的设计思想
- 伸展树---(自顶向下的设计)
- 自顶向下语法分析原理与设计思想
- “自顶向下 逐步求精”的设计方法
- "自顶向下,逐步求精“设计方法
- 自顶向下,逐步求精设计方法
- 用C语言设计贪吃蛇
- 周总结之视频去重用到的一些c++知识点
- python简介
- 手工制作学数学——三维空间八个象限
- self4j log4j配置与调用
- 栈的顺序存储及实现
- 自顶向下设计C语言贪吃蛇
- java 开发模式之四 : 单例模式
- 笔记:深度学习驱动的自动驾驶新主流框架盘点
- angularjs控制器间传值的五种方案
- 16.dubbo路由规则、配置规则
- Python异常处理中的Finally else的功能
- OpenShift Origin 排错
- 尹成 双循环链表
- acronis true image 2018 破解版 | Acronis True Image 2018(最强备份还原工具)官方中文版V2018.10640下载