第一篇:贪吃蛇游戏 实习报告
课程设计报告
贪吃蛇游戏设计
专业 电子信息工程 杜 运 福 B电子062 0610620224 曹 妍 2008年8月30日 学生姓名 班学级 号
指导教师 完成日期
盐城工学院本科生课程设计报告(2008)
贪吃蛇游戏设计 摘要:本设计主要围绕贪吃蛇游戏展开。众所周知,贪吃蛇游戏一直以来是比较流行的。传统的贪吃蛇游戏功能比较少,对蛇的控制仅限于向左转和向右转,而现在的贪吃蛇游戏已经发展的相当好;具有更多的功能和友好的界面。例如,最近流行的免费的3D版的贪吃蛇游戏,界面相当的美观,有很强的立体效果,真实感更强,食物也为立体的且颜色绚丽。在3D版贪吃蛇游戏里面,墙壁是真实的墙壁,障碍物比较多,如树、土丘等。此外,其功能更多更强,可以选择难度。不过,总而言之,3D版与传统的贪吃蛇游戏有共性,即娱乐性与益智性。这些也是贪吃蛇游戏的优点。本人因水平有限,只能设计简单的贪吃蛇游戏。不过,在功能上,比传统贪吃蛇游戏更丰富。蛇可以反向运动,操作起来,显得更为灵活。界面的颜色选用绿色,不易使眼睛疲劳。关键词:3D版;传统;灵活; 2
贪吃蛇游戏设计
目录
1、概述
1.1、用TC设计程序的方法 1.2、简要说明
2、设计要求
3、系统分析与模块设计 3.1、算法设计 3.2、数据结构 3.3、模块设计 3.4、模块枝干图
4、程序流程图 4.1、图形驱动 4.2、开始画面 4.3、显示食物 4.4、蛇向前移动 4.5、判蛇死
4.6、吃到食物后处理 4.7、判蛇反向移动 4.8、游戏结束 4.9、图形结束
5、程序设计及关键源代码
6、运行结果分析
7、实习心得
盐城工学院本科生课程设计报告(2008)
贪吃蛇游戏的设计 1.概 述 1.1、用TC设计程序的方法
首先应了解设计要求,然后按照功能设计模块,每个模块完成特定的功能,要使模块间的耦合性小,内聚性高;设计模块是相当重要的一个环节。模块的数量不宜太多,也不宜太少,要使每个模块都能比较简单的转换成流程图。模块设计完成后,就该给每个模块绘制流程图了。流程图要简单,容易理解,多用中文。不宜写过长的代码,增加理解难度。流程图与模块枝干图均可用绘图软件绘制,可适当加些背景色,用以区分。此外,流程图应容易转换成代码。绘制好了流程图,就要编写代码了。直接在TC环境里输入代码,然后运行测试,检查错误,最终,将设计出可行的程序。1.2、简要说明
我设计的贪吃蛇游戏具有很多独特性。例如,墙壁不用实体,而用中空的墙,颜色为绿色,显得更美观,且不易使眼疲劳。操作上,做了些简化,游戏开始时便可以自动运行,且速度较快,属中等难度。玩游戏的过程相当简单,只需按键盘上的上下左右方向键,便可改变蛇的行进方向。食物随机产生。贪吃蛇吃到一个食物后便得到10分。得分显示在左上角。当蛇撞到墙壁或自己时,蛇死,游戏结束,输出得分。
2.设计要求
外观为矩形,食物随机产生,添加注释,统计得分、每吃到一个食物获得10分。蛇碰到自己或墙壁,游戏均结束。游戏结束时输出得分。画出模块枝干图与每个模块的程序流程图。修改某些代码,改变其外观及功能。游戏操作应尽量简单。
界面美观,让人看了觉得舒服。
3、系统分析与模块设计 3.1、算法设计
玩游戏过程采用递归算法,由WHILE(1)控制循环过程,可使游戏重复玩,在蛇死之前不停的玩。判断蛇死的算法是通过判断蛇有没有碰到自己及墙壁。使蛇向前移动采用递归算法,通过递归将蛇的每一节依次向前移动,横坐标与纵坐标依次向前赋值,从而达到使蛇前移的目的。蛇的前进方向通过IF结构判断。
贪吃蛇游戏设计
3.2、数据结构
蛇与食物信息分别用两个结构体存储与表示。将食物的横坐标X、纵坐标Y和判断是否要出现食物的变量YES分别作为食物的结构体的成员。蛇的横坐标数组X[N],纵坐标数组Y[N],蛇的节数NODE,蛇的移动方向DIRECTION、蛇的生命LIFE分别作为蛇的结构体的成员。结构体内每个成员的存储类型均为整型。3.3、模块设计
模块应具有高内聚性,低耦合性。这样,程序运行才更稳定,效率更高。据功能将贪吃蛇游戏划分成四个大模块,九个小模块。每个模块均具有自己的功能,而且,比较容易画出各个模块的流程图。3.4、模块枝干图
简要说明:图形驱动即完成初始化图形系统功能;开始画面模块的主要作用是根据设置绘制出玩游戏区域四周的墙壁;玩游戏的过程是游戏此游戏程序的核心,又可细分为好多小的功能模块;其中,显示食物模块仅完成显示食物功能;蛇前移模块即通过递归算法实现蛇的向某方向移动;判蛇死模块的功能是通过判断蛇是否碰到自己或墙壁来判断蛇有没有死亡。吃到食物后小模块只有蛇吃到食物后才起作用。即当蛇吃到食物后,蛇自身延长一节并绘出蛇,同时加10分。通过键盘操控来玩游戏主要由判反向移动模块完成,即当蛇不是反向移动时,按照键盘上方向键指示移动。游戏结束模块功能简单,仅完成输出得分与提示语功能。最后图形结束模块完成关闭图形功能。
4、程序流程图
4.1、图形驱动
盐城工学院本科生课程设计报告(2008)
4.2、开始画面
贪吃蛇游戏设计
4.3、显示食物
盐城工学院本科生课程设计报告(2008)
4.、蛇向前移动
贪吃蛇游戏设计
4.5、判蛇死
盐城工学院本科生课程设计报告(2008)
4.6
、吃到食物后处理
贪吃蛇游戏设计
4.7、判蛇反向移动
盐城工学院本科生课程设计报告(2008)
4.8、游戏结束
贪吃蛇游戏设计
4.9、图形结束
5、程序设计及关键源代码
定义上下左右控制方向:
#define LEFT 0x4b00 #define RIGHT 0x4d00
盐城工学院本科生课程设计报告(2008)
#define DOWN 0x5000 #define UP 0x4800 #define ESC 0x011b
设定游戏速度:
int gamespeed=60000;
用结构体定义食物与蛇:
struct Food { int x;/*食物的横坐标*/ int y;/*食物的纵坐标*/ int yes;/*判断是否要出现食物的变量*/ }food;/*食物的结构体*/ struct Snake { int x[N];int y[N];int node;/*蛇的节数*/ int direction;/*蛇移动方向*/ int life;/* 蛇的生命,0活着,1死亡*/ }snake;主函数:
void main(void){ Init();/*图形驱动*/ DrawK();/*开始画面*/ GamePlay();/*玩游戏具体过程*/ Close();/*图形结束*/ } 图形驱动:
贪吃蛇游戏设计
void Init(void){ int gd=DETECT,gm;initgraph(&gd,&gm,“c: c”);cleardevice();}
开始画面,左上角坐标为(50,40),右下角坐标为(620,460)的围墙:
void DrawK(void){ setcolor(10);/*绿色*/ setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/ for(i=50;i<=610;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(611,i,620,i+10);/*右边*/ } }
玩游戏具体过程:
void GamePlay(void){ randomize();/*随机数发生器*/ food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/ snake.life=0;/*活着*/ snake.direction=1;/*方向往右*/ snake.x[0]=100;snake.y[0]=100;/*蛇头*/ snake.x[1]=110;snake.y[1]=100;
盐城工学院本科生课程设计报告(2008)
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(BROWN);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];} /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/ switch(snake.direction){ 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 贪吃蛇游戏设计 { if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]){ GameOver();/*显示失败*/ snake.life=1;break;} } if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55|| snake.y[0]>455){ GameOver();snake.life=1;/*蛇死*/ } if(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.x[snake.node]=-20;snake.y[snake.node]=-20;/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/ snake.node++;/*蛇的身体长一节*/ food.yes=1;/*画面上需要出现新的食物*/ score+=10;PrScore();/*输出新得分*/ } setcolor(4);/*画出蛇*/ for(i=0;i 盐城工学院本科生课程设计报告(2008) } /*endwhile(!kbhit)*/ if(snake.life==1)/*如果蛇死就跳出循环*/ break;key=bioskey(0);/*接收按键*/ if(key==ESC)/*按ESC键退出*/ break;else if(key==UP&&snake.direction!=4)/*判断是否往相反的方向移动*/ snake.direction=3;else if(key==RIGHT&&snake.direction!=2)snake.direction=1;else if(key==LEFT&&snake.direction!=1)snake.direction=2;else if(key==DOWN&&snake.direction!=3)snake.direction=4;}/*endwhile(1)*/ } 游戏结束: void GameOver(void){ cleardevice();PrScore();setcolor(GREEN);settextstyle(0,0,3);outtextxy(200,200,“ Game over!Try!”);getch();} 输出成绩: void PrScore(void){ char str[10]; 贪吃蛇游戏设计 setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(5);settextstyle(0,0,2);sprintf(str,“score:%d”,score);outtextxy(55,20,str);} 6、运行结果分析 通过运行,我对自己的设计比较满意。运行结果正如我所料,此贪吃蛇游戏具有易操作性及充满活力的外观。 截图及描述: 图6-1 开始画面 此图为开始画面图,蛇有三节,墙壁颜色为绿色,显得较有活力。 盐城工学院本科生课程设计报告(2008) 图6-2 蛇吃到两个食物后 蛇吃到食物后,得分为20分,蛇延长两节。 图6-3 游戏结束画面 贪吃蛇游戏设计 7、实习心得 在大一学习期间,我就知道在大二暑假期间,有程序设计实习。从那时起,我就期盼着这一天早点到来。只因我对编程有浓厚的兴趣。我是我们班第一个通过江苏省计算机VB二级考试的。我的VC++成绩也还可以。 转眼间,程序设计实习就如期而至了。实习的第一天是充满好奇与兴趣,当实习回来时,就感觉得这次实习并非想象中的那样。我本以为,程序设计实习应该是开放性的,让我们参照某些课题,自主、自由地设计程序。我想,那样更能促进我们学习和提高我们的动手能力。 这次实习中,我们都被给了程序的源码,而且有详细的功能说明。表面上看,我们几乎不需什么努力就能完成,而实际上,并非如此。因为那些程序大多是基于16位DOS执行的,并且,里面包含许多DOS下图形处理的函数,我从未涉及过,所以,很难看懂代码,即使有那样详细的注释。 通过坚持上机实习,我对代码的认识越来越多。我还上网找了些资料,如TC函数详解等等。我更多的了解了各种TC函数的功能。我通过一步步的学习,终于弄懂了整个程序,并且对程序做了些修改。如外观、大小、输出成绩等。通过修改程序代码增加游戏的功能,我也从中获得了自信。 通过使用Win-TC1.9设计程序,我更多的了解了TC函数的功能与用法,也了解了在TC环境下调用DOS绘图及处理的常用方法。 在上机实习的过程中,还绘制了模块枝干图与程序流程图,我感觉到,画模块枝干图并不是件容易的事。只有在弄懂程序后才能将整个程序划分成数量适宜的模块。划分模块确实挺重要的,原来我将玩游戏过程划为一个模块,后来发现太复杂,很难画出流程图。模块的数量直接关系到绘制程序流程图的难度。从中,我更深入了解了程序设计的整个过程,这也是我最受益的地方。 在实习过程中,遇到不懂的问题,时而查阅以前学过的书籍,也等于我做了复习。这也能提高我将理论付诸实践的能力。 此外,实习期间,你将我们划分成小组;这促进了我们的相互合作与相互学习。总之,通过这次实习,我学到了好多书本以外的知识!我同样很感谢老师,您! 参考文献 [1] 张岳新《Visual C++程序设计》。 [2] 张岳新《Visual C++程序设计基础实验指导书》。[3]沈被娜 刘祖照 《计算机软件技术基础》 一场好玩的“贪吃蛇”游戏作文 今天下午,我们在百思特门口进行了一个小比赛—贪吃蛇。 人员到齐以后,老师按照报数的顺序分好了小组,单数为一组,双数为二祖。老师说完比赛规则后,比赛开始了。两名同学快步走到纸箱前,选好气球,跑回下一个同学那里。接着第二个、第三个、第四个……直到全组都拿到气球。激烈的比拼后,老师说:“第一名和第二名已知晓,二组获得了第一,接下来,还有一个把气球放回去的游戏。” 放气球游戏开始了,我们排成一条小蛇,把气球慢慢地放回箱子。开始时我们放错了,看着二组一个有一个的将气球放进箱子里,我们着急地说:“快点!”排头也着急的快步起来。 到张博文了,他把球一放,那球好像在帮我们赢一样,张博文放一下,它就被弹出来,连放了三次,都被弹出来了,最后他把气球轻轻一放才放好,就在他刚放完,我们已经反败为胜了。 比赛结束了,我们胜利了,我明白了一个道理,团结的力量是无限强大的。 [一场好玩的“贪吃蛇”游戏作文]相关文章: import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Snake extends JFrame { private JPanel contentPane;//窗体内容网格 private JButton btnStart = new JButton(“开始”);//游戏开始按钮 private JButton btnPause = new JButton(“暂停”);//游戏暂停按钮 private JButton btnExit = new JButton(“退出”);//游戏退出按 private JPanel pnlTop = new JPanel();//顶部按钮和分数面板 private JPanel pnlLeft = new JPanel();//左侧面板 private JPanel playPanel = new JPanel();//游戏区面板 private BorderLayout borderLayout1 = new BorderLayout();//容器布局管理器 private BorderLayout borderLayout2 = new BorderLayout(); private GridLayout rbtnLayout = new GridLayout(10, 1, 1, 1); private static final int UP = 1,LEFT = 2,DOWN = 3,RIGHT = 4;//蛇运动方向 private static final int ROWS = 30;//游戏区行数 private static final int COLS = 50;//游戏区列数 private boolean isPause = false;//游戏暂停标志 private boolean isEnd;//游戏结束标志 private SnakeBody snake;//贪食蛇 private int score = 0;//当前得分 SnakeThread thread = new SnakeThread();//游戏主线程 private GridLayout grid1 = new GridLayout(ROWS,COLS,0,0);//游戏区布局 private JButton[][] blocks;//游戏区的所有方块 JPanel jPanel2 = new JPanel(); JLabel jLabel1 = new JLabel(“得分:”); JLabel lblScroe = new JLabel(“0”); ButtonGroup buttonGroup1 = new ButtonGroup(); JRadioButton rbtnLow = new JRadioButton(“初级”, true); JRadioButton rbtnMid = new JRadioButton(“中级”); JRadioButton rbtnHigh = new JRadioButton(“高级”); public Snake(){ super(“贪食蛇游戏”); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); contentPane =(JPanel)this.getContentPane(); contentPane.setLayout(borderLayout2); this.setResizable(false); this.setSize(new Dimension(512, 414)); keyAction keyAct = new keyAction(); this.addKeyListener(keyAct); btnStart.addKeyListener(keyAct); btnPause.addKeyListener(keyAct); btnExit.addKeyListener(keyAct); rbtnLow.addKeyListener(keyAct); rbtnMid.addKeyListener(keyAct); rbtnHigh.addKeyListener(keyAct); btnAction btnAct = new btnAction(); btnStart.addActionListener(btnAct); btnPause.addActionListener(btnAct); btnExit.addActionListener(btnAct); rbtnLow.addActionListener(btnAct); rbtnMid.addActionListener(btnAct); rbtnHigh.addActionListener(btnAct); pnlLeft.setLayout(borderLayout1); playPanel.setLayout(grid1); playPanel.setBackground(Color.white); playPanel.setBorder(BorderFactory.createEtchedBorder()); jPanel2.setLayout(rbtnLayout); buttonGroup1.add(rbtnLow); buttonGroup1.add(rbtnMid); buttonGroup1.add(rbtnHigh); rbtnLow.setSelected(true); pnlLeft.add(playPanel); pnlLeft.add(jPanel2, BorderLayout.WEST); jPanel2.add(“f1”, rbtnLow); jPanel2.add(“f2”, rbtnMid); jPanel2.add(“f3”, rbtnHigh); pnlTop.add(btnStart); pnlTop.add(btnPause); pnlTop.add(btnExit); pnlTop.add(jLabel1); pnlTop.add(lblScroe); contentPane.add(pnlTop, BorderLayout.NORTH); contentPane.add(pnlLeft, BorderLayout.CENTER); //创建并初始化游戏区方块 blocks = new JButton[ROWS][COLS]; for(int i = 0;i < ROWS;i++){ for(int j = 0;j < COLS;j++){ blocks[i][j] = new JButton(); blocks[i][j].setBackground(Color.lightGray); blocks[i][j].setVisible(false); playPanel.add(blocks[i][j]); } } } public static void main(String[] args){ Snake app = new Snake(); app.validate(); app.setVisible(true); } public void start(){ snake = new SnakeBody();//创建蛇身 if(rbtnLow.isSelected()) snake.setSpeed(300); if(rbtnMid.isSelected()) snake.setSpeed(200); if(rbtnHigh.isSelected()) snake.setSpeed(100); score = 0; isPause = false; isEnd = false;// btnPause.setText(“暂停”); //初始化游戏区 for(int i = 0;i < ROWS;i++){ for(int j = 0;j < COLS;j++){ blocks[i][j].setBackground(Color.lightGray); blocks[i][j].setVisible(false); } } //在游戏区内随机放置豆 int x =(int)(Math.random()* ROWS); int y =(int)(Math.random()* COLS); while(blocks[x][y].isVisible()){ x =(int)(Math.random()* ROWS); y =(int)(Math.random()* COLS); } blocks[x][y].setBackground(Color.yellow); blocks[x][y].setVisible(true); try { thread.start(); } catch(IllegalThreadStateException illegalThreadStateException){} } class SnakeBody { public int row[]; public int col[]; public int len = 3, direction = RIGHT, lastdirection = RIGHT; public long speed = 300; public SnakeBody(){ len = 3; direction = RIGHT; lastdirection = RIGHT; row = new int[ROWS]; col = new int[COLS]; for(int i = 0;i <= len;i++){ row[i] = 1; col[i] = len1]; col[i] = col[i-1]; } //根据蛇身运动方向,决定蛇头位置 switch(direction){ case UP: { if(lastdirection == DOWN) row[0] += 1; else { row[0]-= 1; lastdirection = UP; } break; } case LEFT: { if(lastdirection == RIGHT) col[0] += 1; else { col[0]-= 1; lastdirection = LEFT; } break; } case DOWN: { if(lastdirection == UP) row[0]-= 1; else { row[0] += 1; lastdirection = DOWN; } break; } case RIGHT: { if(lastdirection == LEFT) col[0]-= 1; else { col[0] += 1; lastdirection = RIGHT; } break; } } //当蛇头碰到墙时,蛇头碰到蛇身时,游戏结束 if(row[0] >= ROWS || row[0] < 0 || col[0] >= COLS || col[0] < 0 || blocks[row[0]][col[0]].getBackground().equals(Color.green)){ isEnd = true; JOptionPane.showMessageDialog(null, “游戏结束!”); } //吃豆 if(blocks[row[0]][col[0]].getBackground().equals(Color.yellow)){ score += 100; lblScroe.setText(Integer.toString(score)); if(score % 2000 == 0 && speed > 100){ JOptionPane.showMessageDialog(null, “恭喜你过关了,准备进入下一关”); speed-= 100; if(speed == 200) rbtnMid.setSelected(true); if(speed == 100) rbtnHigh.setSelected(true); } } //吃豆后,蛇身加长,并随机显示下一个豆 if(blocks[row[0]][col[0]].getBackground().equals(Color.yellow)){ len++; int x, y; x =(int)(Math.random()* ROWS); y =(int)(Math.random()* COLS); while(blocks[x][y].isVisible()){ x =(int)(Math.random()* ROWS); y =(int)(Math.random()* COLS); } blocks[x][y].setBackground(Color.yellow); blocks[x][y].setVisible(true); } blocks[row[0]][col[0]].setBackground(Color.green); blocks[row[0]][col[0]].setVisible(true);//显示蛇头 } } class SnakeThread extends Thread { public void run(){ while(true){ try { Thread.sleep(snake.speed);//控制移动速度 if(!isEnd &&!isPause){ snake.move();//移动蛇身 } if(isEnd){ //游戏结束 btnStart.setEnabled(true); } } catch(Exception ex){} } } } class keyAction extends KeyAdapter { public void keyPressed(KeyEvent e){ if(!isEnd &&!isPause){ //根据用户按键,设置蛇运动方向 if(e.getKeyCode()== KeyEvent.VK_UP){ snake.direction = UP; } if(e.getKeyCode()== KeyEvent.VK_DOWN){ snake.direction = DOWN; } if(e.getKeyCode()== KeyEvent.VK_LEFT){ snake.direction = LEFT; } if(e.getKeyCode()== KeyEvent.VK_RIGHT){ snake.direction = RIGHT; } } } } //按钮监听响应处理类 private class btnAction implements ActionListener { public void actionPerformed(ActionEvent ae){ Object source = ae.getSource(); if(source.equals(btnStart)){ btnStart.setEnabled(false); start(); } if(source.equals(btnPause)){ if(isPause == true){ btnPause.setText(“暂停”); } if(isPause == false){ btnPause.setText(“继续”); } isPause =!isPause; } if(source.equals(btnExit)){ System.exit(0); } if(source.equals(rbtnLow)){ snake.setSpeed(300); } if(source.equals(rbtnMid)){ snake.setSpeed(200); } if(source.equals(rbtnHigh)){ snake.setSpeed(100); } } } } 高级语言程序设计 课程设计报告 Experiment Designing reporter 课程名称:高级语言程序设计 英文名称 : C Program Experiment Designing 专业:自动化 111 学号: XXX 姓名: XXX 指导教师: XXX 日期: 2012 年 6月 17日至 2011 年6 月 20 日 山东工商学院信电学院 一:课程设计内容 程序功能介绍 贪吃蛇游戏是一个经典小游戏,深受众多玩家喜爱,其规则是:一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,同时记10分,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。此游戏不仅能锻炼人的思维敏捷性,而且还可以提高玩家的逻辑判断能力。设计思路 我们小组称设计本次课题——贪吃蛇的思路为“贪快速上手贪吃蛇三步曲”: 第一步: 寻找到一个真正可以运行的已用C编好的贪吃蛇。因为我们毕竟从未看到过用C编游戏的程序,让我们两手一抹黑的开始编写是有一定的困难的,如果我们自己找一个已经设计好的程序,以此为跳板实现我们想要达到的效果,那么肯定是高效的。所以我们组统一决定,去寻找一个可以运行的C编译的贪吃蛇。第二步: 运行游戏并了解游戏程序。 我们认为,只有你运行并了解一个游戏,才能知道游戏里需要什么样的改进和创新,如果你自己本身就没玩过这个游戏,那么你就是再有技术,你也永远改进和改编不了一个游戏,因为你根本不知道你在干什么。 同样重要的是了解游戏程序。因为只有看懂了程序,才能实现对他的改编,才能游刃有余。第三步: 寻找模块并分类,而后进行改编。 寻找到你想要改变的游戏内容的控制模块,比如,我想要增加一堵墙,那么就应该找到 void DrawK(void){ setcolor(11); setlinestyle(SOLID_LINE,0,THICK_WIDTH);for(i=200;i<=500;i+=10) rectangle(i,200,i+10,209);} 然后要找到:改变蛇初始长度、颜色、初始位置的模块,改变苹果出现位置的模块,让蛇见墙死的模块,让蛇吃苹果加长的模块„„„.并且进行分类,这样下次再想实现某个目标时,可以一目了然的进行改编。对于找到的模块如何进行改编呢?怎么才能知道某个数值或函数代表什么呢? 我们有两个方法: 1.)看名字,比如snakecolor(),很明显他的意思是蛇的颜色。2.)控制变量猜想,比如设置墙的时候for(i=200;i<=500;i+=10); rectangle(i,300,i+10,309);中的200,500,300,209 代表什么呢?我们可以猜想:它很像是坐标上的(x,y)的格式,是不是呢?可可以先让其他数值不变,只让309改变,改变后发现上面的墙变粗了,由此可见这个数字控制的是一堵墙的最下面一行的坐标。 关于该程序的相关分析思路答题模板: 1.贪吃蛇程序流程图如下: 二.贪吃蛇程序的改编: 经过小组成员的认真研究我们对其进行了如下改编 第一步加墙 void DrawK(void){ /*setbkcolor(MAGENTA);*/ setcolor(5);// 可以改变颜色 setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/ 横向上的墙: for(i=100;i<=600;i+=10)// 本行代表行坐标上:100代表墙的初始位置,i<=600代表墙的结尾。 { rectangle(i,60,i+10,69);//本行代表纵坐标上:60代表墙的最上面一行的位置,69代表墙最下面一行的位置。69-60=9,9代表墙块的厚度 } 纵向上的墙: for(i=100;i<=400;i+=10)//本行代表纵坐标上:100代表墙的初始位置,i<=400代表墙的结尾 { rectangle(100,i,109,i+10);//本行代表纵坐标上:100代表墙的最左边面一行的位置,69代表墙最右面一行的位置。69-60=9,9代表墙块的宽度 } 我们认为本模块最重要的是for语句控制的坐标代表的意思。只要明白了坐标的意思,就可以实现对游戏的改编。 第二步就是进行对新加入的墙蛇是否撞上死亡 让蛇撞墙死 if(snake.x[0]>190&&snake.x[0]< 510&&snake.y[0]>=200&& snake.y[0]<=215) /*其中,对x,y范围的控制,实际是对蛇撞击的死亡区域的限制。*/ { GameOver();/*本次游戏结束*/ snake.life=1;/*蛇死*/ } 相应的新添加的墙。 for(i=200;i<=500;i+=10)/*画围墙*/ { rectangle(i,200,i+10,209);/*指定位置*/ 第三步食物的定点出现 if(food.yes==1)/*需要出现新食物*/ 这里说明一下:rand()产生0-65535的数,在limits.h里有定义%400后产生一个0-399的数+60 则为 60 –459,即:%400+60意思是在60~399之间随机产生一个数。 { 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;/*画面上有食物了*/ } 如果将food.x=(常数a)那么食物就会出现在x=a行的随机列,对于food.y=(常数b)那么食物就出现在y=b列的随机行。 第四步对食物墙壁的颜色以及对蛇的运动速个性化调节 setcolor(4);// 对颜色的调整 int gamespeed=50000;/*游戏速度自己调整*/ 通过改变变量的值,就可以个性化选择自己喜欢的颜色,这将是一场别开生面的游戏界面。* 红色代表解析浅蓝代表提示 三.课程设计总结 有言曰:“实践出真知”,在这几天的课程设计实践中,我们组三人真正的体会到了这句话的真谛。 在经历了一学期的C语言学习后,我们从以往的“纸上谈兵”直接过渡到“实际作战”。我们实现了让静态的程序变成动态的游戏效果,虽然我们只是改编了一下别人做好的程序,但我们同样由此获益匪浅,感触颇深,当然也发现了许多自己的不足。 首先,在我们刚刚进行第一步“寻找程序”的时候,就被搁浅了,因为我们发现,在网上能找到一个真正符合我们使用标准的程序很难,就是找到了几个也没有能运行它们的程序。我们花费了前两天的时间来寻找能够使用的程序和软件,但最后还是一无所获,正当我们一筹莫展的时候,我们的导师——杨老师给我们带来了曙光,使得我们在黑暗中找到了希望的光明,杨老师给我们传来了一个上届师哥做好的程序,并且把它的运行软件也给了我们,这对我们来说无疑是雪中送炭,得到这个程序后,我们三个人看到了C语言运行一个游戏的流程和方法,我们脑中也大概有了一个思路。我们三个人以此程序为跳板,直接开始对程序模块进行挑选,因为我们已经浪费了两天,所以我们决定进行分工作业,分别去寻找:筑墙模块,加苹果模块,撞墙死模块。最后我们用了一下午时间完成了三大步中的前两大步和第三步的第一部分,剩下的就是最重要而充满挑战的改编了,从以上的操作中,让我们明白了找对一个平台的重要性,这个平台就是老师给我们的程序,就是我们的前进方向。没有了方向了的征程,一开始就是个错误。在我们寻找程序模块的时候,我们对于程序中的很多东西都是模模糊糊的概念,比如struck是什么,比如for语句的使用,以及for语句的循环体是什么,当然我们也发现了定义字符在长的程序中的方便与重要性。还有就是我们发现程序在编写时的规范性很重要,比如同级别花括号的位置的对应,对应好了,模块就好找,对应不好就很乱。还有定义函数及变量的时候,函数名字和变量名最好是见名知意,比如我们所看的程序中,gamespeed,snakecolour,food.....在最后的攻坚阶段,为了实现对程序的改编,我们使用控制变量猜想法是正确的选择,比如设置墙的时候for(i=200;i<=500;i+=10); rectangle(i,300,i+10,309);中的200,500,300,209 代表什么呢?我们猜想:它很像是坐标上的(x,y)的格式,是不是呢?我们先让其他数值不变,只让309改变,改变后发现上面的墙变粗了,由此我们知道这个数字控制的是一堵墙的最下面一行的坐标。我们用这个方法知道了其他很多数值的用途。我们用这种方法先是知道了如何设置一堵墙,在我们欣喜设置一堵墙以后才发现:蛇撞了墙后不死。在我们进行了全局来看以后才知道,原来设计一堵墙,都要再设计一个if语句来使得蛇在这个范围内会死亡。并且我们发现在设计这个if语句的时候,不仅要计算好墙的坐标,而且还要用好逻辑语言(&&,||!)同时语句的运算顺序也很重要。刚一开始我们忽略的&&和关系运算符级别的高低,使得我们设计的墙,总是撞不死蛇,为此我们很是恼火,着急的组员还在这里发生了点小摩擦,由此可见C语言的严谨性! 最后我们又通过在网上查找信息,知道了随机数发生器randomize()的用法:rand()=x%+d 意思是说在d~(x-1)之间随机产生一个数字。我们很自然的联想到,如果把food.x等于常数a;把food.y等于一个;x%+d的随机数,那不就能固定只在某一行出现苹果了吗?所以我们觉得,充分利用手边的资源也是很重要的,毕竟C语言很高深,课本上的东西总是有限的,要想知道更多的东西还需多练习,多查阅资料。总之:革命尚未成功,通知还需努力啊!四个人感受: 汤X: 就我个人而言,这次课程设计,我觉得我最大的收获就是:我明白了,我们其实真的没那么厉害,我们真的还有很多东西不会,我们真的连课本上的基本东西都没掌握,课本上的东西,真的也只是C语言这个大海中的一滴水而已。而在我本人还没有掌握好课本的知识点的情况下,做起这个程序自然很费事,一个简单的课本P293讲到的struct结构体,我一开始竟然忘记它是什么意思,不知道它是什么,就更不用谈怎么用它了。还有逻辑语言的使用。我想,现在肯定有很多同学还不知道逻辑运算的优先次序吧?这个问题我本人在使用逻辑语言的时候也不太会,还查看了书。像这些小的知识点,我个人认为如果掌握不好的话,是不可能让整个大程序运行起来的。还有比如我在遇到程序显示“else多余”的警告时候不不知所措,问了老师才知道是if()后面加了“;”而且if没有用“{}”来固定范围,这个错误原因是分号使得if语句结束了,孤立的else当然是多余的了。一个小小的分号使得程序无法运行,由此可见在今后的编程中,一定要注意谨慎,仔细。同时要注意记住平时编程的时候,出现的错误指示是什么意思。比如这次的“else多余”就是因为if后多了分号。还有在编程时候,书写一定要规范,特别是if语句的花括号的位置要对应起来,因为位置决定范围。注意定义变量和函数要使用规范的英文单词,这样才能见名知意,为以后修改找变量节省时间。对于这次课题中,“设计一个墙,就要对应一个函数舍得蛇撞墙死”,让我明白,C语言程序中各部分的联系性,牵一发而动全身,所以在编程时一定要注意全局的把握。我们最后还要说说在编程中,好好利用网络资源,因为课本里的东西总是有限的,而C语言又那么高深,像随机数发生器,还有颜色的定都是我第一次接触,这些东西的用处可是颇大,以后一定好好学习。多看,多练,多总结。最后还要感谢指导老师,杨老师对我学习的帮助和指导。徐XXX: 刚开始拿到题目时候什么也不会一片茫然,从网上找了一个程序一看,太吓人了,这么长怎么看啊,而且还是错误的。没办法只能硬着头皮去改了,但是在改的过程中才发现其实c语言没有想象的那么难而且还很有意思,只是自己平时没有好好学所以在改的时候非常吃力,有很多简单的知识都不知道,没有记住。没办法只能借助与课本了。但是几天下来发现自己已经不再像以前那样是个菜鸟了,虽然很多知识还没掌握。同时在编改程序的时候切记不能烦躁要静心慢慢来,好几次自己都因心燥出现了很多不该出现的错误浪费了很多时间。 对键盘的熟悉在编程时也是很重要的,自己在写的时候往往就是跟一指禅差不多眼睛盯着键盘打,打错了也不知道最后导致整个程序都是错误的,就因为一个打错了一个字母。 总的来说这次课程设计收获很多,也知道了自己的不足,在以后的学习中要多实践,实践很能提高自己的能力。刘XX: 4天的C语言课程设计上机学习让我感受颇多,每天都发现新的问题,又不得不绞尽脑汁解决问题,心情就像正弦函数,随着问题的出现和解决一起一伏。刚开始接触贪吃蛇的C语言成寻时,看着C-free上面出现的有十几个错误的程序,一片茫然不知所措。只能继续在网上搜索错误较少的程序,并结合书上的基础知识查看错误所在,最终发现是 作为小组中唯一的女生,明显感觉有压力,打字速度不如另外两个男生,对游戏和程序的敏感也不如他们强,有种小小的挫败感。旁边小组的同学也给我很大的压力。他们自己编写程序,我很佩服他们,越是这样想。心里越着急,越不能解决问题,每当感觉有压力的时候,就提醒自己心静,认真的看程序。在学习过程中,深深的发现了自己的不足之处,对于C语言,只学了一点点皮毛东西,想要学好C语言,编好程序,还要付出很多的努力,还要用更多的时间来学习C语言这门深奥的学科。现在只能借用别人已经写好的程序,在别人的基础上,一点点进步和学习,比如程序中筑墙,需要仿照已有的程序,结合逻辑运算,关系运算和数学知识才能让蛇撞墙死。苹果位置的出现也同样需要进一步的搜索,通过更改食物的横纵坐标以及出现的概率来确定食物的位置。编写程序时,也发现书上的东西对于程序的某些部分来说,没有什么作用,显得太浅显,想要实现老师给出的一些要求,还需要实践,通过上机学习,自己摸索才能成功。一次次修改,一次次失败,就像贪吃蛇想方设法吃苹果会Game over,我们只有认真学好基础理论,并结合实践经验才会取得进步。 在这次学习过程中,我很感谢我的组员,虽然有时我们的意见出现分歧,但是通过大家的共同努力,我们收获了很多,一起讨论,一起研究怎样解决问题,对老师提出的要求个个击破,我们拧成一股绳共同应对问题,让我感受了团队的力量希望在以后的学习过程中,我们依然能够互相帮助,共同进步。 五 课程设计修改后的程序.加墙 for(i=200;i<=500;i+=10)/*画围墙*/ { rectangle(i,200,i+10,209);/*指定位置1*/ } for(i=120;i<=200;i+=10)/*画围墙*/ { rectangle(100,i,109,i+10);/*指定位置2*/ } 2.指定位置加苹果 if(food.yes==1)/*需要出现新食物*/ { food.x=rand()60; food.y=rand()%200+60; while(food.x%10!=0) food.x++; while(food.y%10!=0) food.y++; food.yes=0;3.指定地方撞墙死 if(snake.x[0]>190&&snake.x[0]< 510&&snake.y[0]>=200&& snake.y[0]<=215) { GameOver();/*本次游戏结束*/ snake.life=1;/*蛇死*/ } if(snake.x[0]>90&&snake.x[0]<110&&snake.y[0]>=110&&snake.y[0]<=215) { GameOver();/*本次游戏结束*/ snake.life=1;/*蛇死*/ } } 贪吃蛇游戏程序设计报告 贪吃蛇游戏设计 姓名: 张力 学号: 1002032 3完成日期: 月 日1 贪吃蛇游戏程序设计报告 一、设计目的 贪吃蛇游戏程序功能的实现主要是建立在二维数组和图形界面的应用上,通过编写游戏程序能够熟悉掌握相关数组和图形函数的运用,提高编程水平,增加编程的兴趣 二、总体设计 主函数 ↓ 图形驱动Init 画界面DrawK 游戏具体过程GamePlay 图形结束Close ↓ 游戏结束GameOver 输出成绩PrScore 三、详细设计(项目成员及分工、模块功能说明(如函数功能、入口及出口参数说明,函数调用关系描述等) ①主函数main(): 定义使用的常数,全局变量及函数原型说明,并调用Init()函数初始化图形系统;然后调用DrawK()函数画界面,调用GamePlay()函数实现游戏的具体过程,游戏结束后调用Close()函数关闭图形系统结束程序。 ②画界面函数DrawK(): 主界面是一个密封的围墙,用两个循环语句分别在水平方向和垂直方向输出连续的宽度和高度均为10个单位的矩形小方块,设置成淡青色,背景颜色为黑色。 ③游戏具体过程函数GamePlay(): 算法过程: a.设置初始值。为防止食物出现在一个位置上,要设置随机数发生器,真正产生随机数。初始时,蛇只有蛇头,设定一个开始方向; b.循环执行,直到按Esc键退出; c.没有按键的情况下,循环执行。 如果没有食物,随机出现食物;食物的随机出现要确保它的位置在10的倍数位置上,因为蛇的坐标都是以10为模的;如果有食物,则显示食物,蛇 贪吃蛇游戏程序设计报告 移动身体,根据蛇的方向改变坐标值,并判断蛇是否撞到了墙或自己吃到了自己,如果出现这两种情况之一,则蛇死;调用游戏结束函数GamePlay(),结束本次游戏; 判断蛇吃到食物的方法是蛇头的坐标和食物的坐标都相等;如果蛇吃到了食物,蛇身体长一节,数组元素增加一个,身体节数、分数都进行相应的改变。 在新位置画出蛇。采用的方法是每次移动的时候从最后一节开始到倒数第二节,将前一节的坐标赋值给后一节的坐标,移动后只要把最后一节用背景色去除即可。 D.如果有按键,则识别按键值。如果按键为Esc键则结束游戏,程序运行结束;如果所按键为方向键,则根据该键改变蛇方向的变量direction的值,相反方向键无效。 ④游戏结束函数GameOver(): 游戏结束,清除屏幕,调用输出分数函数PrScore(),并显示游戏结束。 ⑤输出分数函数PrScore(): 在指定位置利用sprintf()将整数转换为字符串,用outtextxy()输出,、bar()函数的应用是为了覆盖原来的值。 ⑥图形结束函数Close(): 在显示游戏结束信息的画面时,按任意键关闭图形系统,程序结束。 四、调试与测试:调试方法,测试结果的分析与讨论,测试过程中遇到的主要问题和采取的解决措施等; 将源文件在TC3.0环境下调试运行,前期发现错误为游戏界面静止。 五、源程序清单及执行结果: #include 贪吃蛇游戏程序设计报告 #define UP 0x4800 #define Esc 0x011b #define N 200 /*定义全局变量*/ int i,key;int score=0;/*得分*/ int gamespeed=50000;/*游戏速度可以自己调整*/ struct Food { int x;/*定义食物的横坐标*/ int y;/*定义食物的纵坐标*/ int yes;/*判断是否要出现食物的变量*/ }food;/*食物的结构体*/ struct snake { int x[N];int y[N];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 Init(void){ int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode,“D:TC30LIB”);} /*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/ void DrawK(void){ setbkcolor(LIGHTGREEN);setcolor(11);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);/*右边*/ } } /*玩游戏的具体过程*/ void GamePlay(void){ randomize();/*随机数发生器*/ food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/ snake.life=0;/*蛇还活着^ ^*/ snake.direction=1;/*方向向右*/ snake.x[0]=100;snake.y[0]=100;/*蛇头*/ snake.x[1]=110;snake.y[1]=100;snake.node=2;/*蛇的节数为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(GREEN); 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]; } /*1,2,3,4表示右左上下四个方向,通过判断这个来移动蛇头*/ switch(snake.direction) { 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 { if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) { GameOver();/*显示游戏结束*/ snake.life=1;/*蛇死了T T!*/ break; } } If(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)/*判断蛇是否撞到墙*/ { GameOver();/*游戏结束*/ snake.life=1;/*蛇死了T T!*/ } if(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.x[snake.node]=-20; snake.y[snake.node]=-20; /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/ snake.node++;/*蛇的身体长一节*/ food.yes=1;/*画面上需要出现新的食物*/ score+=10;/*加十分!*/ PrScore();/*输出新得分*/ } setcolor(4);/*画出蛇*/ for(i=0;i 贪吃蛇游戏程序设计报告 rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10); delay(gamespeed); 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==Esc)/*按Esc键退出*/ break;else if(key==UP&&snake.direction!=4)/*判断是否往相反方向移动*/ snake.direction=3;else if(key==RIGHT&&snake.direction!=2) snake.direction=1;else if(key==LEFT&&snake.direction!=1) snake.direction=2;else if(key==DOWN&&snake.direction!=3) snake.direction=4;}/*endwhile(1)*/ /*游戏结束*/ void GameOver(void){ cleardevice();/*清除屏幕*/ PrScore();/*输出得分*/ setcolor(RED);settextstyle(0, 0,4);outtextxy(200,200,“GAME OVER”);/*显示游戏结束*/ getch();} void PrScore(void)/*输出成绩*/ { char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);settextstyle(0,0,2);sprintf(str,“score:%d”,score);outtextxy(55,20,str);} 贪吃蛇游戏程序设计报告 void Close(void)/*图形结束*/ { getch();closegraph();} void main(void)/*主函数*/ { Init();DrawK();GamePlay();Close();} 8第二篇:一场好玩的“贪吃蛇”游戏作文
第三篇:贪吃蛇java课程设计
第四篇:c语言程序贪吃蛇课程设计报告
第五篇:贪吃蛇C语言课程设计报告