资源描述
北京化工大学北方学院
课程设计汇报
课程名称 C语言课程设计
设计题目 贪吃蛇游戏
专业、班级 信工0902
学 号 09057
姓 名 苏 灿
指导老师 邵兰洁
设计时间9月29日—10月11日
年 10月 11 日
1.设计目标
本课程设计目标就是要经过一次集中强化训练,使学生能立即巩固已学知识,补充未学但又必需内容。进行课程设计目标在于加深对程序设计基础中基础理论和基础知识了解,促进理论和实践结合,深入提升程序设计能力。具体目标以下:
1.使学生更深入地了解和掌握该课程中相关基础概念,程序设计思想和方法。
2.培养学生综合利用所学知识独立完成课题能力。
3.培养学生勇于探索、严谨推理、实事求是、有错必改,用实践来检验理论,全方位考虑问题等科学技术人员应含有素质。
4.提升学生对工作认真负责、一丝不苟,对同学团结友爱,协作攻关基础素质。
5.培养学生从资料文件、科学试验中取得悉识能力,提升学生从她人经验中找四处理问题新路径悟性,初步培养工程意识和创新能力。
6.对学生掌握知识深度、利用理论去处理问题能力、试验能力、课程设计能力、书面及口头表示能力进行考评。
2.设计题目及要求
【1】设计题目 贪吃蛇游戏
【2】要求
实现以下功效:
贪吃蛇按一个方向运行
判短是否撞到自己
是否撞墙
游戏结束
退出
【3】本程序最大优点是简单易行
综合应用数组、指针、结构体、文件等,对该设计题目进行设计和实现。
一、 正文
1. 计算法分析设
1.1 模块调用层次图
主函数
↓
图形驱动Init 画界面DrawK 游戏具体过程GamePlay 图形结束Close
↓
游戏结束GameOver 输出成绩PrScore
【2】系统模块调用层次图
Main
load
Save
insert
change
renew
statistics
load
insert
change
renew
statistics
1.总体模块步骤图:
2. 算法分析
①主函数main():
定义使用常数,全局变量及函数原型说明,并调用Init()函数初始化图形系统;然后调用DrawK()函数画界面,调用GamePlay()函数实现游戏具体过程,游戏结束后调用Close()函数关闭图形系统结束程序。
②画界面函数DrawK():
主界面是一个密封围墙,用两个循环语句分别在水平方向和垂直方向输出连续宽度和高度均为10个单位矩形小方块,设置成淡青色,背景颜色为黑色。
③游戏具体过程函数GamePlay():
3. 算法过程:
a. 设置初始值。为预防食物出现在一个位置上,要设置随机数发生器,真正产生随机数。初始时,蛇只有蛇头,设定一个开始方向;
b. 循环实施,直到按Esc键退出;
c. 没有按键情况下,循环实施。
假如没有食物,随机出现食物;食物随机出现要确保它位置在10倍数位置上,因为蛇坐标全部是以10为模;假如有食物,则显示食物,蛇移动身体,依据蛇方向改变坐标值,并判定蛇是否撞到了墙或自己吃到了自己,假如出现这两种情况之一,则蛇死;调用游戏结束函数GamePlay(),结束此次游戏;
判定蛇吃到食物方法是蛇头坐标和食物坐标全部相等;假如蛇吃到了食物,蛇身体长一节,数组元素增加一个,身体节数、分数全部进行对应改变。
在新位置画出蛇。采取方法是每次移动时候从最终一节开始到倒数第二节,将前一节坐标赋值给后一节坐标,移动后只要把最终一节用背景色去除即可。
D.假如有按键,则识别按键值。假如按键为Esc键则结束游戏,程序运行结束;假如所按键为方向键,则依据该键改变蛇方向变量direction值,相反方向键无效。
④游戏结束函数GameOver():
游戏结束,清除屏幕,调用输出分数函数PrScore(),并显示游戏结束。
⑤输出分数函数PrScore():
在指定位置利用sprintf()将整数转换为字符串,用outtextxy()输出,、bar()函数应用是为了覆盖原来值。
⑥图形结束函数Close():
在显示游戏结束信息画面时,按任意键关闭图形系统,程序结束。
二、 运行结果
程序载入turbo C
编译实施
处理编译过程中句法错误
程序运行过程调试
依据修改部分指令来修改程序运行过程
如:
结果图
三、 源程序清单
#include <iostream.h>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h> //使用目前时间做种子;
enum dir{up,down,left,right}; //枚举类型enum dir;
//围墙;
class Fence{
public:
void InitFence();
void OutputF();
public:
char game[20][20];
}f; //定义对象;
//画框框;
void Fence::InitFence(){
for(int i=0; i<20; i++)
for(int j=0; j<20; j++){
if(i==0||i==19||j==0||j==19)
game[i][j]= '*';
else game[i][j]= ' ';
}
}
//显示框框;
void Fence::OutputF(){
for(int i=0; i<20; i++){
for(int j=0; j<20; j++)
cout<<game[i][j]<<' ';
cout<<endl;
}
}
//蛇结点;
class SnakeNode{
private:
int x,y;
SnakeNode *prior,*next;
public:
void add_head(int x,int y);
int get_x();
int get_y();
void delete_tail();
}*head=NULL, *tail =NULL;
//插入头结点;
void SnakeNode::add_head(int x,int y){
SnakeNode *q=new SnakeNode;
q->x =x; q->y =y;
q->next =head;
q->prior =NULL;
if(head) head->prior =q;
head =q;
if(!tail) tail =head;
f.game[x][y]= '*'; //f对象能够在定义Fence类时定义; 且Fence类在SnakeNode类前定义;
}
int SnakeNode::get_x(){
return x;
}
int SnakeNode::get_y(){
return y;
}
//删除尾结点;
void SnakeNode::delete_tail(){
SnakeNode *p =tail;
f.game[tail->get_x()][tail->get_y()]= ' ';//把尾结点坐标表示'*'置为空格;
if(tail==head)
tail= head= NULL;
else{
tail= tail->prior;
tail->next= NULL;
}
delete p;
}
//move移动;
class move{
public:
dir point; //枚举变量point: 控制方向;
int food_x;
int food_y;
public:
void moving();
void change_point(char); //改变方向;
void get_food();
};
void move::moving(){
int a,b;
a= head->get_x(); //取得头结点横坐标
b= head->get_y(); //头结点纵坐标
switch(point){
case up: --a; break;
case down: ++a; break;
case left: --b; break;
case right: ++b; break;
}
if(a==19||b==19||a==0||b==0){ //判定是否撞墙;
cout<<"game over!!!"<<endl;
exit(0);
}
if(a==food_x && b==food_y){ //吃food;
head->add_head(a,b);
get_food();
}
else{
head->add_head(a,b); //插入头结点;
head->delete_tail(); //删除尾结点;
}
}
void move::change_point(char keydown){
switch(keydown){
case 'w': point= up; break;
case 's': point= down; break;
case 'a': point= left; break;
case 'd': point= right; break;
}
}
void move::get_food(){
srand((unsigned int) time(NULL)); //做种子(程序运行时间);
food_x= rand()%18+1;
food_y= rand()%18+1;
f.game[food_x][food_y]= '*';
}
//main();
int main(){
cout<<"Using 'w,s,a,d'to control direction!!!\n\n\n";
//画框框和小蛇;
move m;
f.InitFence();
head->add_head(4,3);
head->add_head(4,4);
head->add_head(4,5);
m.get_food();
f.OutputF();
while (true){
char keydown= getch(); //getch()返回键盘上读取字符;包含头文件<conio.h>
m.change_point(keydown);
while(!kbhit()){ //判定有没有按键落下;
system("cls"); //清屏函数;
m.moving();
f.OutputF();
Sleep(200);
}
}
return 0;
四、 个人碰到困难和处理方法
1.程序结构了解
因为长时间对C语言和数据结构没有接触,使我们对这些有部分相对陌生,关键是二维数组引用和循环控制方面,如:
(1) for(i=snake.node-1;i>0;i--)/*蛇每个步骤往前移 动,也就是贪吃蛇关键算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
(2)for(i=3;i<snake.node;i++)/*从蛇第四节开始判定是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver();/*显示失败*/
snake.life=1;
break;
}
}
2.graphics.h图形库函数陌生
第一次接触graphics.h库函数,对其一无所知经过查阅资料找到graphics.h库函数中多个关键函数功效及使用方法。
如:setcolor(int color);定义线型等颜色
rectangle(int left, int top, int right, int bottom);画矩形
等。
3.图形函数中坐标
在屏幕中位置图形库函数是以坐标来实现,它和通用坐标不一样,以屏幕左上角为原点以像素为单位长度,图。
(x+I,y)
(x,y)
(x,y+i)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
五、 结论
经过此程序,我做成了一个完整小产品。使我们熟悉了面向程序设计方法步骤。
这次程序设计,我们碰到了一个全新库函数,我们经过自己查看库函数源文件,了解了程序使用方法并进行了应用。以此我们能够经过发散思维对以后其它程序所设计到新库文件也找到了入手点进而能够编写新程序。
六、 参考文件
《写给大家看C语言书》作者:(美)佩里著,谢小刚,刘艳娟译
《C++程序设计语言》作者:Stephen译本
《C语言程序设计》作者:谭浩强
《Microsoft Visual C++ 6.0程序员指南》作者:[美] Beck Zaratian
展开阅读全文