课程设计封面;
目 录
1 前言 1
2 需求分析 1
2.1 课程设计目的 1
2.2 课程设计任务 1
2.3 设计环境 1
2.4 开发语言 1
3 分析和设计 1
3.1 模块设计 1
3.2 系统流程图 1
3.3 主要模块的流程图 2
4 具体代码实现 2
5 课程设计总结 2
5.1 程序运行结果 / 预期运行结果 2
5.2 课程设计体会 2
参考文献 2
致 谢 2
1 前言
编写一个程序来实现贪吃蛇小游戏的运行。通过结构体以及结构体数组和各种函数的调用来实现该游戏的功能。
2 需求分析
2.1 课程设计目的
该课程设计主要是利用学习到的c语言来编写贪吃蛇小游戏。
2.2 课程设计任务
(1). 通过编写“贪吃蛇游戏”程序,掌握结构化,模块块化程序设计的思想,培养解决实际问题的能力。
(2). 设计好数组元素与蛇,食物的对应关系,实现按键控制方向。
(3) . 随机产生食物。
(4). 有分数统计,等功能。
2.3 设计环境
(1)WINDOWS 2000/2003/XP/7/Vista系统
(2)Visual C++或TC集成开发环境
2.4 开发语言
C语言
3 分析和设计
一;先了解关于该代码的课外知识。如下
1;#include
#include
#include
void gotoxy(int x ,int y)
{
COORD c;//大写的COORD;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
这样子在最开始定义了之后,那么就可以在后面使用这个函数了。
3;a = getch();函数;这个可以不是;getchar哦。应该是兄弟吧;
getch();
头文件是#include
功能是;从键盘上读取一个字符,但不将读入的一个字符显示在屏幕上。
难点;getch的用法,使用getch时要打两个输入,
a=getch();
b=getch();
先判断a,即getch的返回值;按f1到f12就返回0反之返回224;
b才是真正的getch所接收的符号。
还有就是要注意的一点是;getch();并非标准C中的函数,不存在C语言中。所以在使用的时候要注意程序的可移植性;
4;system();函数;
头文件;#include
system是一种windows操作系统下的函数语言;
现在我们只了解颜色和清屏,暂停;
暂停;system(“pause”);
清屏就是;system(“cls”);
颜色就举例子吧。
例如 system(“color 0A”); 其中color后面的0是背景色代号,A是前景色代号。各颜色代码如下:
0=黑色 1=蓝色 2=绿色 3=湖蓝色 4=红色 5=紫色 6=黄色 7=白色 8=灰色 9=淡蓝色 A=淡绿色 B=淡浅绿色 C=淡红色 D=淡紫色 E=淡黄色 F=亮白色
5;SetConsoleTextAttribute()函数;
SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数;这个函数的使用主要是查找资料吧,参数太长了。
举个例子;
FOREGROUND_RED表示设置前景色为红色,即字体的颜色为红色;
FOREGROUND_INTENSITY 表示设置前景色为高亮显示,FOREGROUND_GREEN表示绿色,两个参数中间加“|”表示前景色为高亮绿色;
BACKGROUND_INTENSITY表示设置背景色为高亮显示,BACKGROUND_BLUE表示背景色为蓝色,BACKGROUND_INTENSITY |BACKGROUND_BLUE两个参数就使背景色为高亮蓝色。
要表示红色字体,白色背景可以使用SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY |FOREGROUND_INTENSITY | FOREGROUND_RED|BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
颜色得来是三个里面混合得来的,比如白色就是红蓝绿三色混合;
这只是了解一下,程序中具体的使用就要直接百度来控制颜色;
6;loop;
goto loop;
的使用。
Goto是跳转到程序指定的地方。
Loop;就是指goto要跳转的地方;
7;srand与rand;就是随机函数;专业的就是随机数发生器的初始化函数。
再看使用。两者是一起使用的,产生伪随机序列;
Srand()和其中的参数。来产生生成伪随机数序列的种子。如果参数没有变化那么,rand产生的随机数将不会变化,因此需要一个变化的参数;一般选择系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。注意time(NULL)函数在time.h头文件里面。
rand()函数的使用;要与%搭配。rand()%(a)+b;b表示随机数会在b开始的(str),a就是end-str+1;则它的表达式就是给出了一个str到end的随机数;为什么一定a是end-str+1。代值,当想表示从2到100,就是rand()%(99)+2;产生99时就是出现2的随机数,产生98时就是出现100的随机数。
8;我们要从键盘上输入控制方向的键;那么我们就应该判断他是否读入成功,因此就要kbhit()函数;
作用就是;检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
头文件;#include
9;一旦出现问题;就要exit()函数来反应过来;
功能是;关闭所有文件,终止正在执行的进程
exit(1)表示异常退出.这个1是返回给操作系统的;
exit(0)表示正常退出;
10;f1到f12的数字表示;
因为f1到f12没有asc||码,则只能用扫描码;
F1======59;
F2======60;
F3======61;
F4======62;
其余依次类推;
11;控制方向的按键,方向键上下左右与WXAD是一样的asc||码,则不需要分开处理或者限制;
流程图
、
实现代码
#include
#include
#include
#include
#include
#define height 28
#define width 60
#define n 400
void GameStart();//游戏开始
void First_snack();//初始化的蛇
int move();//蛇头的移动和数据的更新
void move_snack();//蛇的其他部位移动
void static_info();//静态数据
void food_move();//食物的出现
int judge_head();//判断是否死亡
int GameOver();//游戏结束
void dynamic_info();//动态数据
int node;
int music;
int speed;
int direction;
int score;
int p;
struct SNACK
{
int x;
int y;
int life;
}snack[n];
struct FOOD
{
int x;
int y;
}food;
void gotoxy(int x,int y)
{
COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
void Game_frame()//框架;
{
int i;
for(i = 1; i <= height; i++){//为什么竖是加1而横是加2;
gotoxy(0,i);
printf("■");//因为这是中文状态下的;
gotoxy(width,i);
printf("■");
}
for(i = 0; i <= width+1; i=i+2){
gotoxy(i,0);
printf("■");
gotoxy(i,height+1);
printf("■");
}
}
void First_snack()//蛇的初始位置;
{
int i, j = 0;
Game_frame();
for(i = 0; i < node; i++){
snack[i].x = 28-j;
snack[i].y = 17;
j = j-2;
gotoxy(snack[i].x,snack[i].y); printf("■");
}
}
//蛇头移动和数据更新
int move()
{
int a,b ;
static_info();
int key_direction=3;
while(!kbhit())//没按键进入
{
loop://下次
gotoxy(food.x,food.y);printf("※");
switch(key_direction)//头的移动;
{
case 1 : move_snack(); snack[0].y=snack[0].y-1;gotoxy(snack[0].x,snack[0].y);printf("■"); break;//向上移
case 2 : move_snack(); snack[0].y=snack[0].y+1;gotoxy(snack[0].x,snack[0].y);printf("■"); break;//向下移
case 3 : move_snack(); snack[0].x=snack[0].x-2;gotoxy(snack[0].x,snack[0].y);printf("■"); break;//向左移
case 4 : move_snack(); snack[0].x=snack[0].x+2;gotoxy(snack[0].x,snack[0].y);printf("■"); break;//向右移
}
dynamic_info();
judge_head();
if(p == 0){
return 0;
}
Sleep(speed);//暂停的时间来控制速度
}
a=getch();//getch的返回值
b=getch();//getch的接收的符号。
switch(a)
{
case 224:switch(b)//更改方向
{//1---下;2代表上;3代表左;4代表右;
case 72:key_direction=1;if(direction==2) key_direction=0; break;
case 75:key_direction=3;if(direction==4) key_direction=0; break;
case 80:key_direction=2;if(direction==1) key_direction=0; break;
case 77:key_direction=4;if(direction==3) key_direction=0; break;
}break;
case 0: switch(b)//功能选项
{
case 59:speed-=20;break;
case 60:speed+=20;break;
case 61:music=music==1?0:1;break;
case 62:system("color 0C");static_info();break;//红色
case 63:system("color 0E");static_info();break;//黄色
case 64:system("color 0A");static_info();break;//绿色
case 65:system("color 0D");static_info();break;//紫色
case 66:system("color 0F");static_info();break;//亮白色
case 67:system("color 08");static_info();break;//灰色
}break;
default: goto loop;
}
if(key_direction)
direction=key_direction;// 实现按反向键时暂停;
else
goto loop;
goto loop;//表示返回到loop位置,
}
//蛇的其他部位移动
void move_snack()
{
int i ;
gotoxy(snack[node-1].x,snack[node-1].y); //清除蛇尾
printf(" ");
for(i=node-1;i>=1;i--)
{
snack[i]=snack[i-1];
gotoxy(snack[i].x,snack[i].y); printf("◆");
}
}
int judge_head()
{
int i=0;
if(snack[0].x==0 || snack[0].x==width || snack[0].y==0 || snack[0].y==height+1){
GameOver();//首先判断是不是撞墙了
return p = 0;
}
for(i=node-1;i>=1;i--)//判断是不是咬着自己了
{
if(snack[0].x==snack[i].x&&snack[0].y==snack[i].y){
GameOver();
return p = 0;
}
}
if(snack[0].x==food.x && snack[0].y==food.y)//如果吃到食物,给尾巴加上一节
{
if(music)
putchar(7);//响铃
score+=100;
node++;
snack[node-1]=snack[node-2];
gotoxy(snack[node-1].x,snack[node-1].y);printf("◆");
food_move();
}
}
void food_move()//食物出现;
{
srand(time(NULL));
do
{
food.x = rand()%(width-3)+2;
}while(food.x%2!=0);
food.y = rand()%(height-1)+1;
gotoxy(food.x,food.y);printf("◆");//身体 //看调用的地方和作用;
}
void static_info()//静态信息
{
gotoxy(width+4,2);printf("%c %c %c %c控制",24,25,26,27);
gotoxy(width+4,3);printf("按任意键暂停");
gotoxy(width+4,4);printf("F1加速,F2减速");
gotoxy(width+4,5);printf("F3开关声音");
gotoxy(width+4,7);printf("蛇速度:");
gotoxy(width+4,8);printf("蛇长度:");
gotoxy(width+4,9);printf("得分:");
gotoxy(width+4,11);printf("蛇头位置:");
gotoxy(width+4,13);printf("食物位置:");
gotoxy(width+4,15);printf("声音:");
gotoxy(width+4,16);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F4:■");//红色
gotoxy(width+4,18);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F5:■");//黄色
gotoxy(width+4,20);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY);printf("F6:■");//绿色
gotoxy(width+4,22);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F7:■");//紫色
gotoxy(width+4,24);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY);printf("F8:■");//亮白色
gotoxy(width+4,26);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);printf("F9:■");//灰色
}
void dynamic_info()//动态信息
{
gotoxy(width+13,7);printf("%4d",500-speed);
gotoxy(width+13,8);printf("%4d",node);
gotoxy(width+13,9);printf("%4d",score);
gotoxy(width+13,13);printf("%2d,%2d",food.x,food.y);
gotoxy(width+13,11);printf("%2d,%2d",snack[0].x,snack[0].y);
gotoxy(width+9,15);music==1?printf("开"):printf("关");
}
void GameStart() //首界面
{
Game_frame();
gotoxy(25,10);printf("贪吃蛇游戏");
gotoxy(22,17);system("pause");
}
int GameOver()
{
system("cls");
Game_frame();//因为前面清屏了。
gotoxy(25,10);printf("Game Over");
gotoxy(25,12);printf("得分:%d",score);
gotoxy(20,14);printf("重复游戏请按p键\n");
return 0;
}
int main()
{
char a;
loop:
p = 1;
system("cls");
system("mode con: cols=80 line=31");
GameStart();
system("cls");
node = 4;
music = 1;
speed=280;
direction = 3;
score = 0;
First_snack();
food_move();
move();
a = getch();
if(a == 'p'){
goto loop;
}
return 0;
}