宁夏大学
C#语言设计报告
题目:彩色贪吃蛇
学 院 数学计算机学院_______
专 业_____计算机科学与技术(师范)_
班别_____ ____ ___
学 号
学生姓名_____ ___________
指导教师_____ ___________
成 绩
20 年 月
目 录
1、课程设计目的…………………………………………………………1
2、课程设计要求…………………………………………………………1
3、设计题目
及内容…………………………………………………1
3.1程序功能………………………………………………………1
3.2设计思想………………………………………………………1
3.3设计的具体实现………………………………………………1
3.4 总体流程图……………………………………………………7
3.5程序代码编写及注释…………………………………………8
3.6调试问题及解决方法…………………………………………13
3.7调试结果………………………………………………………13
4、设计心得体会………………………………………………………14
5、建议…………………………………………………………………15
6、评阅
……………………………………………………………15
7、参考文献……………………………………………………………15
1、课程设计目的
编写C语言程序实现贪吃蛇游戏,贪吃蛇游戏是一个深受人们喜爱的游戏,一条蛇在密闭的围墙内,在围墙内随机出现一个食物,通过按键盘上的四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时计10分,接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉蛇头撞到自己的身体游戏结束。作为一个完整的程序,尤其是一个完整的游戏,必须考虑人机交流与用户体验。游戏的界面不能太丑,更不能连个简单的界面都没有。游戏应该有个比较漂亮的界面,在有必要硬件支持和软件的支持下,游戏开发者必须最大限度的使游戏美观。游戏的美观是一方面,游戏的内在素质是另一方面。一个游戏的优劣,最终由玩家决定。在游戏与玩家见面之前,游戏开发者要设计一种让玩家投入的游戏模式,并且在一定的游戏规则下进行。
关键词 贪吃蛇 流程图 c语言 源程序 WIN-TC
2、课程设计要求
(1)分析课程设计题目的要求
(2)写出详细设计说明
(3)编写程序代码,调试程序使其能正确运行
(4)设计完成的软件要便于操作和使用
(5)设计完成后提交课程设计报告
(6)贪吃蛇游戏的要求:
(1)用图形方式实现用键盘操作的贪吃蛇游戏,应有各种颜色、界面良好、操作方便等特点。
(2)收集资料,分析课题,分解问题,形成总体设计思路;深入分析各个小问题,列出大纲,编写各部分程序模块;对于设计中用到的关键函数,要学会通过查资料,弄懂其用法,要联系问题进行具体介绍;完成课程设计报告。
3、设计题目分析
3.1、程序功能
贪吃蛇游戏是一个经典小游戏,一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,同时记10分,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体叉蛇头撞倒自己身体游戏结束。
3.2 设计思想
程序关键在于表示蛇的图形及蛇的移动。用一个小矩形快表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用俩节表示。移动时必须从蛇头开始,所以蛇不能向相反的方向移动,如果不按任意键,蛇自行在当前方向上前移,但按下有效方向键后,蛇头朝着该方向移动,一步移动一节身体,所以按下有效方向键后,先确定蛇头的位置,而后蛇的身体随蛇头移动,图形的实现是从蛇头新位置开始画出蛇,这时,由于未清屏的原因,原来的蛇的位置和新蛇的位置差一个单位,所以看起来蛇多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现与消失也是画矩形块和覆盖矩形块。为了便于理解,定义两个结构体:食物与蛇。
3.3.设计的具体实现
(1)函数定义
函数定义是对各个基础函数的定义,并且设置需要运用的信息,便于调用
#define M 100
#define N 100
#define R 100
#define T 100
#include
#include
#include
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,j,key,q;
int score=0;/*得分*/
long gamespeed=50000;/*游戏速度自己调整*/
struct Food
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake
{
int x[M][N];
int y[R][T];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
void main(void)/*主函数*/
(2)主函数main( )
主函数是程序的主流程,首先定义使用到的常数、全局变量及函数原型说明,然后初始化图形系统,调用函数DrawK()画出开始画面,调用函数GamePlay(),即玩游戏的具体过程,游戏结束后调用Close()关闭图形系统,结束程序
/*主函数*/
void main(void)
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
/*图形驱动*/
void Init(void)
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();
}
(3) 画界面函数DrawK( )
主界面是一个封闭的围墙,用两个循环语句分别在水平和垂直方向输出连续的宽度和高度均的矩形方块,表示围墙,为了醒目,设置为白色。
void DrawK(void)/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
{
setbkcolor(0);/*设置当前背景颜色*/
setcolor(YELLOW);/*设置当前画线颜色*/
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=50;i<=600;i+=10)/*画围墙*/
{
rectangle(i,40,i+10,49); /*上边*/
rectangle(i,451,i+10,460);/*下边*/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10); /*左边*/
rectangle(601,i,610,i+10);/*右边*/
}
}
(4)游戏具体过程函数GamePlay( )
这是游戏的主要组成部分,他采用将前一节的坐标赋给后一节,用背景颜色将最后节去除,当蛇头的坐标与食物的坐标相等时,表示食物被吃掉了。
void GamePlay(void)
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0][0]=100;snake.y[0][0]=100;/*蛇头*/
snake.x[0][1]=110;snake.y[0][1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{
setcolor(15);
rectangle(food.x,food.y,food.x+10,food.y-10);
}
for(i=snake.node-1,j=snake.node-1;i>0,j>0;i--,j--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
{
snake.x[i][j]=snake.x[i-1][j-1];
snake.y[i][j]=snake.y[i-1][j-1];
}
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)
{
case 1:snake.x[0][0]+=10;break;
case 2: snake.x[0][0]-=10;break;
case 3: snake.y[0][0]-=10;break;
case 4: snake.y[0][0]+=10;break;
}
for(i=3,j=3;i595||snake.y[0][0]<55||
snake.y[0][0]>455)/*蛇是否撞到墙壁*/
{
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/
}
if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0][0]==food.x&&snake.y[0][0]==food.y)/*吃到食物以后*/
{
gamespeed= gamespeed+100;
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node][snake.node]=-20;snake.y[snake.node][snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/
}
q=rand()%15;
setcolor(q);/*画出蛇*/
for(i=0,j=0;i书也会变快。通过键盘操控来玩游戏主要由判反向移动模块完成,即当蛇不是反向移动时,按照键盘上方向键指示移动。游戏结束模块功能简单,仅完成输出得分与提示语功能。最后图形结束模块完成关闭图形功能。
3.5、程序代码编写及注释
#define M 100
#define N 100
#define R 100
#define T 100
#include
#include
#include
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,j,key,q;
int score=0;/*得分*/
long gamespeed=50000;/*游戏速度自己调整*/
struct Food
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake
{
int x[M][N];
int y[R][T];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void)
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
/*图形驱动*/
void Init(void)
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(6);
setlinestyle(SOLID_LINE,0,1);/*设置线型*/
for(i=50;i<=600;i+=10)/*画围墙*/
{
rectangle(i,40,i+10,49); /*上边*/
rectangle(i,451,i+10,460);/*下边*/
}
for(i=40;i<=450;i+=10)
{
rectangle(50,i,59,i+10); /*左边*/
rectangle(601,i,610,i+10);/*右边*/
}
}
/*玩游戏具体过程*/
void GamePlay(void)
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0][0]=100;snake.y[0][0]=100;/*蛇头*/
snake.x[0][1]=110;snake.y[0][1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{
setcolor(15);
rectangle(food.x,food.y,food.x+10,food.y-10);
}
for(i=snake.node-1,j=snake.node-1;i>0,j>0;i--,j--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
{
snake.x[i][j]=snake.x[i-1][j-1];
snake.y[i][j]=snake.y[i-1][j-1];
}
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)
{
case 1:snake.x[0][0]+=10;break;
case 2: snake.x[0][0]-=10;break;
case 3: snake.y[0][0]-=10;break;
case 4: snake.y[0][0]+=10;break;
}
for(i=3,j=3;i595||snake.y[0][0]<55||
snake.y[0][0]>455)/*蛇是否撞到墙壁*/
{
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/
}
if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0][0]==food.x&&snake.y[0][0]==food.y)/*吃到食物以后*/
{
gamespeed= gamespeed-100;
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node][snake.node]=-20;snake.y[snake.node][snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/
}
q=rand()%15;
setcolor(q);/*画出蛇*/
q=rand()%15;
for(i=0,j=0;i