《C#程序设计及应用教程》课程设计报告
设计题目 贪吃蛇游戏
专 业 2011级软件工程
班 级 2011级软件工程
姓 名
学 号 111164015
完成日期 20##-06-24
目 录
1. 问题描述………………………………………………
2. 系统设计………………………………………………
3. 数据结构与算法描述…………………………………
4. 测试结果与分析………………………………………
5. 总 结…………………………………………………
6. 参考文献………………………………………………
附录 程序源代码…………………………………………
(报告正文部分):
课程设计题目
1. 问题描述
我设计的的游戏首先在主界面选择游戏难度,接着进行游戏,在游戏过程中贪吃蛇不停地吃掉随机产生的食物,蛇身增长,直到蛇触碰到自己的身躯或边框,游戏结束
特色:1.游戏可以自选难度,且蛇身长每增加
2游戏可以储存游戏分数,你可以查看最高分
3游戏过程中蛇的颜色,食物的颜色,分数的颜色,可以不停变换,增加视觉效果
2. 系统设计
2.1 设计目标
C#课程设计是教学实践环节中一项重要内容,进行此课程设计旨在掌握基础知识的基础上,进一步加深对C#的理解和掌握; 提高和加强学生的计算机应用及软件开发能力,使学生具备初级程序员的基本素质; 培养学生独立分析问题、解决问题、查阅资料以及自学能力,以适应信息管理行业日新 2 月异的发展形势; 本次课程设计是以学生独立思考解决问题为主,教师指导为辅,结合上机操作,完成指定的任务,做出设计报告。
2.2 设计思想
程序关键在于表示蛇的图形及蛇的移动。用一个小矩形快表示蛇的一节身体,身体每长一节,增加一个矩形块。移动时必须从蛇头开始,所以蛇不可以向相反的方向移动,如果不按任意键,蛇自行在当前方向右前移,但按下有效方向键后,蛇头朝该方向移动,一步移动一节身体,所以按下有效方向键后,先确定蛇头的位置,而后蛇的身体随蛇头移动,图形的实现是从蛇头新位置开始画出蛇,这时,由于未清屏的原因,原来的蛇的位置和新的位置差一个单位,所以看起来蛇多一节身体,所以将蛇的最后节用背景色覆盖。食物的出现与消失也是画矩形块和覆盖矩形块。为了便于理解,定义两个结构体:食物与蛇,同时还定义了一个随意的墙。然后利用图形驱动,,制作美观的游戏界面,通过随机函数产生随机的食物,控制游戏过程食物的出现。定义键盘操作控制游戏过程蛇的移动方向,画出边界,并判断游戏是否结束,统计游戏过程中蛇吃的食物数量,计算并输出游戏成绩。
2.3 系统模块划分
3. 数据结构与算法描述
4. 测试结果与分析(可将测试过程抓图说明)
(1)主菜单
(2)游戏设置界面
(3)关于贪吃蛇(帮助)
5. 总 结
这是我自己去设计一个比较系统的程序,对我们来说也是一个很好的锻炼。
首先,为了能写出程序,我将以前所学都好好的巩固了一遍,并且努力的去灵活的运用。很多都清楚起来。其次,平时都是编写一些单个的操作,这次需要自己写出一个可以实现
几个功能的系统性的程序,刚开始时是一头雾水,但经过大家的讨论,自己的摸索,也慢慢找到了方法。这让我体会到,在编写程序时,不仅需要扎实的知识,还要有细心周到的考虑,同学之间的合作也是很重要的。
在这两个星期里,我觉得发现了自己还有很多很多的不足,也深刻的体会到了自己还
有很多东西要学,而且要真的掌握,还得多用心,多用脑。计算机的确不好学,但只要努力
就会有收获。这次程序是写了不少,但还是没能运行出一个正确的结果,不过我相信,经过以后的学习和努力,是肯定能做出一个好的程序来的!
6. 参考文献 (包括书籍、论文、网络资料等)
[1] 马骏等《C#程序设计及应用教程》. 人民邮电出版社
附录 程序源代码(主要部分)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace MySnake
{
public partial class frmGame : Form
{
private Controller objController;
private Snake objSnake;
private string strUp = "";
private string strDown = "";
private string strLeft = "";
private string strRight = "";
private bool blIsGameStart;
public frmGame()
{
InitializeComponent();
}
private void frmGame_Load(object sender, EventArgs e)
{
blIsGameStart = false;
Config objConfig = new Config();
strUp = objConfig.GetConfigValue("Up");
strDown = objConfig.GetConfigValue("Down");
strLeft = objConfig.GetConfigValue("Left");
strRight = objConfig.GetConfigValue("Right");
lblUp.Text = strUp;
lblDown.Text = strDown;
lblLeft.Text = strLeft;
lblRight.Text = strRight;
}
private void timer1_Tick(object sender, EventArgs e)
{
objController.Move();
if (objController.IsGameOver)
{
timer1.Enabled = false;
开a始º?ToolStripMenuItem.Enabled = true;
暂Y停ª¡êToolStripMenuItem.Enabled = false;
MessageBox.Show("Game Over");
}
else
{
if (objController.IsGetTarget)
{
lblTargetCount.Text = objController.TargetCount.ToString();
lblSnakeLength.Text = objSnake.Length.ToString();
lblScore.Text = objController.Score.ToString();
lblSpeedLevel.Text = objSnake.Speed.ToString();
timer1.Interval = 245 - objSnake.Speed * 20;
}
}
}
private void 暂Y停ª¡êToolStripMenuItem_Click(object sender, EventArgs e)
{
timer1.Enabled = !timer1.Enabled;
}
private void 退ª?出?ToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void 开a始º?ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (objController != null)
{
objController.ClearSnake();
}
initializeSnake();
timer1.Enabled = true;
开a始º?ToolStripMenuItem.Enabled = false;
暂Y停ª¡êToolStripMenuItem.Enabled = true;
结¨¢束º?游®?戏¡¤ToolStripMenuItem.Enabled = true;
}
private void initializeSnake()
{
objSnake = new Snake();
objController = new Controller(plGame, objSnake);
lblDirection.Text = "向¨°右®¨°";
lblSnakeLength.Text = "6";
lblTargetCount.Text = "0";
timer1.Interval = 245 - objSnake.Speed * 20;
Config objConfig = new Config();
strUp = objConfig.GetConfigValue("Up");
strDown = objConfig.GetConfigValue("Down");
strLeft = objConfig.GetConfigValue("Left");
strRight = objConfig.GetConfigValue("Right");
lblUp.Text = strUp;
lblDown.Text = strDown;
lblLeft.Text = strLeft;
lblRight.Text = strRight;
objController.InitializeSnake();
blIsGameStart = true;
}
private void 结¨¢束º?游®?戏¡¤ToolStripMenuItem_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
开a始º?ToolStripMenuItem.Enabled = true;
暂Y停ª¡êToolStripMenuItem.Enabled = false;
结¨¢束º?游®?戏¡¤ToolStripMenuItem.Enabled = false;
}
private void frmGame_KeyDown(object sender, KeyEventArgs e)
{
string strKey = e.KeyData.ToString();
if (strKey == strUp)
{
if (objSnake.Direction != "D")
{
objSnake.Direction = "U";
lblDirection.Text = "向¨°上¦?";
}
}
else if (strKey == strLeft)
{
if (objSnake.Direction != "R")
{
objSnake.Direction = "L";
lblDirection.Text = "向¨°左Á¨®";
}
}
else if (strKey == strDown)
{
if (objSnake.Direction != "U")
{
objSnake.Direction = "D";
lblDirection.Text = "向¨°下?";
}
}
else if (strKey == strRight)
{
if (objSnake.Direction != "L")
{
objSnake.Direction = "R";
lblDirection.Text = "向¨°右®¨°";
}
}
}
private void frmGame_Paint(object sender, PaintEventArgs e)
{
if (blIsGameStart)
{
objController.DrawSnakeAndTarget();
}
}
private void 游®?戏¡¤设¦¨¨置?ToolStripMenuItem_Click(object sender, EventArgs e)
{
frmSettings objFrm = new frmSettings();
objFrm.ShowDialog();
}
private void 关?于®¨²AToolStripMenuItem_Click(object sender, EventArgs e)
{
frmAbout newFrm = new frmAbout();
newFrm.ShowDialog();
}
private void label4_Click(object sender, EventArgs e)
{
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
}
private void 游®?戏¡¤GToolStripMenuItem_Click(object sender, EventArgs e)
{
}
}
}
一、读程序题部分(贪吃蛇)
1、程序的功能
设计游戏界面,包括画墙、画蛇、画食物,并且设置蛇和食物的属性,编写蛇的运动方式和游戏方式。
2、主函数分析
主函数中前两行与编写图形程序有关,第三行中调用Speed函数,把Speed函数的返回值付给变量speed;第五行dwall函数的作用是画墙,函数中又调用wall函数来画墙上的砖块
3、函数的调用关系
4、数据变量定义作用
定义食物的横坐标food.x和食物的纵坐标food.y可以有效的随机设置食物出现在界面的任何地方;
定义snake.life表示蛇的生死以否,好判断是否结束游戏
snake.dir=1;/*方向向右*/
定义snake.x[0]和 snake.y[0]表示蛇头的坐标,在后面蛇撞墙死的问题上用的到蛇头的坐标;
定义蛇的节数snake.node,方便蛇每吃到食物节数增加;
定义snake.level,显示蛇的闯关数
5、主要函数的功能、流程图
dwall():画墙
wall():画组成墙的砖
Speed():选择贪吃蛇的速度
line():画线函数,画砖的线条
gotoxy():定位坐标
Play():调用各函数,开始完游戏
GameOver():结束游戏
6、程序的不足及改进
没有障碍墙,游戏过于简单;没有游戏奖励,游戏趣味性不高;
改进:设置障碍墙,蛇撞到墙也死;
代码:for(j=200;j<=300;j+=10)
{
wall(j,300);/*画横的障碍墙*/
}
for(j=300;j<=350;j+=10)
{
wall(300,j);/*画竖的障碍墙*/
}
不足:没有游戏奖励,游戏趣味性不高;
改进:增加生命值,蛇每吃到三颗食物,则增加一个生命值;
代码:定义food.level,在Play函授中初始化,在设置蛇每吃到一颗食物就增长一节身体的代码后加上
if(snake.node%3==0)
{snake.level++; /*除第一关外,其余每吃3
颗食物,就增加一个生命值*/
gotoxy(5,2);
printf("The level is %d",snake.level); /*左上角显示出生命值(级别)*/
}
7、加上注释、改进后的完整代码
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#include<conio.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
#define N 100/*贪吃蛇的最大长度*/
#define P 0x1970/*定义暂停功能键*/
int i,key;
int speed;/*游戏速度*/
struct FOOD
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int flag;/*标志是否要出现食物*/
}food;
struct Snake
{
int x[N];
int y[N];
int node;/*蛇的节数*/
int dir;/*蛇移动方向*/
int life;/*标志是死是活*/
int level;/*定义生命值(级别)*/
}snake;
void GameOver();/*结束游戏*/
void Play();/*玩游戏过程*/
void dwall();/*画墙*/
void wall(int x,int y);/*画组成墙的砖*/
int Speed();/*选择贪吃蛇的速度*/
main()
{
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"");
speed=Speed();/*将函数返回值赋给speed*/
cleardevice();/*清屏*/
dwall();/*开始画墙*/
Play();/*开始完游戏*/
getch();
closegraph();/*退出图形界面*/
}
void wall(int x,int y)
{
int sizx=9;
int sizy=9;
setcolor(15);/*白色画砖的上边和左边*/
line(x,y,x+sizx,y);
line(x,y+1,x+sizx-1,y+1);
line(x,y,x,y+sizy);
line(x+1,y,x+1,y+sizy-1);
setcolor(4);/*红色画砖的右面和下面*/
line(x+1,y+sizy,x+sizx,y+sizy);
line(x+2,y+sizy-1,x+sizx,y+sizy-1);
line(x+sizx-1,y+2,x+sizx-1,y+sizy-1);
line(x+sizx,y+1,x+sizx,y+sizy);
setfillstyle(1,12);/*用淡红色填充砖的中间部分*/
bar(x+2,y+2,x+sizx-2,y+sizy-2);
}
void dwall()/*用前面画好的砖来画墙*/
{int j;
for(j=50;j<=600;j+=10)
{
wall(j,40);/*画上面墙*/
wall(j,451);/*画下面墙*/
}
for(j=40;j<=450;j+=10)
{
wall(50,j);/*画左面墙*/
wall(601,j);/*画右面墙*/
}
for(j=200;j<=300;j+=10)
{
wall(j,300);/*画横的障碍墙*/
}
for(j=300;j<=350;j+=10)
{
wall(300,j);/*画竖的障碍墙*/
}
}
int Speed()/*选择贪吃蛇运行的速度*/
{ int m;
gotoxy(20,10);
printf("level 1\n");
gotoxy(20,12);
printf("level 2\n");
gotoxy(20,14);
printf("level 3\n");
gotoxy(20,16);/*增加一个速度选项*/
printf("level 4\n\t\tplease choose:");
scanf("%d",&m);
switch(m)
{
case 1:return 60000;
case 2:return 40000;
case 3:return 20000;
case 4:return 10000;
default:
cleardevice();
Speed();
}
}
void Play(void)/*游戏实现过程*/
{
srand((unsigned long)time(0));
food.flag=1;/*1表示需出现新食物,0表示食物已存在*/
snake.life=0;/*标志贪吃蛇活着*/
snake.dir=1;/*方向向右*/
snake.x[0]=300;snake.y[0]=240;/*定位蛇头初始位置*/
snake.x[1]=300;snake.y[1]=240;
snake.node=2;/*贪食蛇节数*/
snake.level=1; /*生命值(级别)初始化*/
do
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.flag==1)/*需要出现新食物*/
do
{
food.x=rand()%520+60;
food.y=rand()%370+60;
food.flag=0;/*标志已有食物*/
}while(food.x%10!=0||food.y%10!=0);
if(food.flag==0)/*画出食物*/
{
setcolor(WHITE);/*设置食物的颜色*/
setlinestyle(3,0,3);
rectangle(food.x,food.y,food.x+10,food.y+10);
}
for(i=snake.node-1;i>0;i--)/*实现蛇向前移动*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
switch(snake.dir)
{
case 1:snake.x[0]+=10;break;/*向右移*/
case 2: snake.x[0]-=10;break;/*向左移*/
case 3: snake.y[0]-=10;break;/*向上移*/
case 4: snake.y[0]+=10;break;/*向下移*/
}
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;
}
}
if(snake.x[0]<60||snake.x[0]>590||snake.y[0]<50||
snake.y[0]>440)/*蛇是否撞到墙壁*/
{
GameOver();/*游戏结束*/
snake.life=1; /*蛇死*/
break;
}
if(snake.y[0]==300&&snake.x[0]>200&&snake.x[0]<=300)
/*蛇是否撞到横的障碍墙*/
{
GameOver();/*游戏结束*/
snake.life=1; /*蛇死*/
break;
}
if(snake.x[0]==300&&snake.y[0]>300&&snake.y[0]<=350)
/*蛇是否撞到竖的障碍墙*/
{
GameOver();/*游戏结束*/
snake.life=1; /*蛇死*/
break;
}
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*判断是否吃到食物*/
{
setcolor(0);/*用背景色遮盖调食物*/
rectangle(food.x,food.y,food.x+10,food.y+10);
snake.node++;/*蛇的身体长一节*/
if(snake.node%3==0)
{snake.level++; /*除第一关外,其余每吃3
颗食物,就增加一个生命值*/
gotoxy(5,2);
printf("The level is %d",snake.level); /*左上角显示出生命值(级别)*/
}
food.flag=1;/*需要出现新的食物*/
}
setcolor(YELLOW);/*画蛇(设置蛇的颜色)*/
for(i=0;i<snake.node;i++)
{ setlinestyle(0,0,1);
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]+10);
}
delay(speed);
setcolor(0);/*用背景色遮盖蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]+10);
} /*endwhile(!kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循环*/
break;
key=bioskey(0);/*接收按键*/
if(key==UP&&snake.dir!=4)/*判断是否往相反的方向移动*/
snake.dir=3;
else
if(key==DOWN&&snake.dir!=3)/*判断是否往相反的方向移动*/
snake.dir=4;
else
if(key==RIGHT&&snake.dir!=2)/*判断是否往相反的方向移动*/
snake.dir=1;
else
if(key==LEFT&&snake.dir!=1)/*判断是否往相反的方向移动*/
snake.dir=2;
else
if(key==P) getch();/*若按P键,则游戏暂停*/
}while(key!=ESC);/*ESC键退出游戏*/
}
void GameOver(void)
{
cleardevice();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(50,200,"GAME OVER,BYE BYE!");
sleep(3);
}
计算机实习报告姓名:班级:学号:小班序号:指导老师:题目:贪吃蛇(运行环境:visual,studio2010)邮箱:题目贪吃蛇实…
实验报告课程名称:Windows程序设计实验名称:贪吃蛇设计成员:##专业年级:20##级软件工程填写时间:20##/12/24贪…
C语言程序设计实训报告姓名专业班级指导教师20##年7月14日目录1实训的目的和要求.11.1实训的目的.11.2实训的要求.12…
三实验步骤1编程环境的选择本程序采用MicrosoftVisualC60的英文版本进行编译VisualC60是Microsoft公…
20xx年计算机实习报告计算机实习报告姓名向睿班级07班学号10210197小班序号11指导老师方莉题目贪吃蛇邮箱hgjngh12…
程序设计基础课程设计C课程设计报告贪吃蛇院系:计算机学院网络工程系班级:122班姓名:指导教师:20##年12月25日程序设计基础…
贪吃蛇游戏C程序设计报告目录一设计要求2二设计的作用目的2三课题分析21贪吃蛇游戏功能分析22游戏界面分析33设计思路分析3四设计…
贪吃蛇游戏C程序设计报告目录一设计要求2二设计的作用目的2三课题分析21贪吃蛇游戏功能分析22游戏界面分析33设计思路分析3四设计…
计算机实习报告姓名:班级:学号:小班序号:指导老师:题目:贪吃蛇(运行环境:visual,studio2010)邮箱:题目贪吃蛇实…
目录一软件设计要求和规范2二软件制作过程2三收获和体会13参考文献13一软件设计要求和规范11设计要求通过游戏程序设计提高编程兴趣…
电子与信息工程系开放性实验报告JAVA程序设计开放性实验报告专业班级学号姓名实验报告实验2贪吃蛇游戏设计4学时1实验内容1创建软件…