您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Linux下基于SDL图形库的贪吃蛇游戏
浙江大学硕士学位论文序言II中文论文题目:在LINUX平台下实现贪吃蛇英文论文题目:GameofSnakeunderLinux姓名及手机号:学号:指导教师:浙江大学硕士学位论文11个人简历3在LINUX平台下实现贪吃蛇摘要:本文主要展示了在LINUX平台下实现贪吃蛇。主要应用了双向链表、二维结构数组等数据结构,采用了SDL图形库。建模、设计算法完毕之后,在Linux下进行了运行和调试。关键词:贪吃蛇链表苹果SDLGameofSnakeunderLinuxAbstract:ThispapermainlyshowsthegameofsnakeunderLinux.Themaindatastructuresaredoublelinkedlistandtwo-dimensionalarray,andIusedtheSDLtoprintthesnakeandapple.Aftermodelingandcompletedthecodes,IrunthegameunderLinux.KeyWords:snakelinked-listappleSDL1.引言贪吃蛇是一款家喻户晓的小游戏,受到众多青少年的喜爱,在手机上,在电脑上,我们都可以方便的下载到这款小游戏。而在linux系统下,一样可以利用GNUgcc编译器,使用C语言编程,调用linux自带的图形库函数来完成贪吃蛇的制作。我在制作本程序时,没有参考任何相关代码,完全独立设计。2.建模与算法问题一、贪吃蛇的表示注意到贪吃蛇是一条蛇,而且它的身体的长度是一节一节的,每一节身体都应当存储坐标与其他数据,显然我应当使用一个链表这个数据结构来处理贪吃蛇的主要程序结构。链表结构如下图所示:NILdata1nextprevdata2nextprevdata3NIL为了起到更好的遍历和数据读取的效果,我采取了双向链表的方式,允许head浙江大学硕士学位论文10附录4让后一结点方便快捷地获取前结点的相关信息。头的prev指针和尾的next指针被设置为NIL。初始的蛇结构仅有两段身体,即头和尾。其中,这个双向链表的data数据有三个,一个是当前方块在对应可活动区域的的相对坐标x,另一个是坐标y,有了这个x和y,当此身体节点方块移动以后,我们可以根据其x和y的值画出相应的蛇结构。另外一个数据储存了prev结点在之前移动过的方向,这样,当蛇头朝某个方向前进一步时,后面的身体结点就可以根据前一结点移动过的方向来移动自己。有了这三个数据,我就可以呈现整条蛇头改变方向,后面的身体移动到prev结点的位置的动态效果了。问题二、墙体和某方块已被占据的表示这是贪吃蛇结构的又一个难点,由于双向链表仅仅表示了蛇的身体结构,仅仅通过蛇的坐标表示,程序是无法获取四周的墙壁信息以及是否撞到了自己的身体这些信息的。由于整个蛇体可活动区域被分成了块状区域,蛇的着色和移动都是方块化的,那么很容易就可以分析出来整个区域类似于一个表格,可以用一个二维数组来定义每个方块是否被蛇或者墙占据。如果某个方块在二维数组上对应的值是0,那么说明当前方块为空,贪吃蛇可以移动到此方块上来;如果对应的值是1,那么说明当前方块是墙壁或者是贪吃蛇自己的身体,若蛇头移动到了这个位置则游戏失败。问题三、苹果的设置众所周知,贪吃蛇通过吃苹果来增加自己的身体长度,那么就会产生一些问题。首先是苹果如何放置,因为我们已经通过二维数组将蛇的可活动区域划分成了表格的形状,因此我们可以调用随机函数,在可活动区域中随机选择一个位置来放置苹果。但是如果这样放置的话,可能会出现苹果放在了蛇的身体位置,或者放在了墙上。因此,需要进行一个循环判定,如果数组的值是1说明不可放置苹果,重新获取随机数,直到选择了可放置的位置。但是,当蛇头遇到苹果的时候,如何判定贪吃蛇吃到了呢?这个问题有多种解决方案:(1)可以令苹果的坐标参数为全局变量,然后当蛇头移动时,在某个函数里判断蛇头的相对坐标和苹果的坐标是否相等,如果相等则可以扩张链表。(2)可以将二维数组中的每个元素都设置多个数据,即定义一个结构,多设置一个变量,该变量默认的值为0,当有苹果放在二维数组的对浙江大学硕士学位论文11个人简历5应位置时,该值更改为1;当苹果被贪吃蛇吃掉的时候,更改为0。(3)不改变二维数组的数据结构,但是把二维数组里苹果对应的坐标的值更改为2,即它不是墙也不是可移动区域,而是苹果,当蛇头移动到该位置时候,若发现对应二维数组的值是2,则吃到了苹果。在本程序里,我选择了第二种方案,将二维数组定义为二维结构数组。问题四、算法设计数据结构设计完毕,我们就开始了算法的设计。本程序中,需要实现的功能有:游戏界面的设计、贪吃蛇身体结构的展现、苹果的设置、贪吃蛇的移动、移动速度的更改等。(1)游戏界面的设计由于是在linux下完成,因此我将会用到linux的图形库函数,来完成贪吃蛇可活动区域的建立、游戏名称、分数界面和一些提示的展现。首先,我选择的视频模式是640x480x16位色,然后,我在屏幕上选择了一块400x400的区域用来当做贪吃蛇的可活动区域。在这块区域的边界处,我设置了一个矩形框,用来提醒玩家这里是墙,不可碰撞。这400x400的区域被1600个小矩形所分割,每个矩形的大小为40x40,以横向为x轴,纵向为y轴,就可以看成一个40x40的二维数组,每个数组对应位置的坐标都是0。但是由于在可活动区域外还有一堵墙存在,因此二维数组需要被设置为42x42,最外围一圈的标记值为1。而在剩下的空白处,我显示了一些标题文字、按键提醒文字。整个游戏界面就初步建立了。(2)贪吃蛇身体结构的展现在数据结构的建立中,我将贪吃蛇设置为一个双向链表,而双向链表里存储的数据,就是贪吃蛇的身体在40x40的区域内,每个结点的相对坐标,范围为(0,0)到(40,40),初始的蛇只有头尾,其坐标分别为(20,20)和(19,20),只要将这两个点转化为绝对坐标,把队应的10*10的小矩形区域修改成一定的颜色,就可以画出一条蛇。当蛇的身体移动或者变长的时候,每个身体节点的对应的坐标值也相应改变,再重新打印这条蛇即可。(3)苹果的设置前文已经提到,只需要通过rand函数,获取两个0-40的随机数的值,分别浙江大学硕士学位论文10附录6对应苹果的x坐标和y坐标,并通过一定的循环避免苹果设置在蛇的身体上或者墙上即可。(4)贪吃蛇的移动在程序中,我用一个snake*move()函数来实现蛇的移动,而这个功能的实现也是整个程序的核心。在双向链表数据结构中,我定义了一个重要的变量Dir来表示本方块的移动方向。比如程序从键盘中断读入RIGHT按键之后,贪吃蛇向右移动一步,那么Dir的值就会被赋为RIGHT,其中RIGHT是键盘上向右键的ACSII码值,已经过宏定义。之后,当蛇头移动一步之后,蛇身除蛇头以外的方块都会读取prev结点的Dir值,并移动到prev结点的位置。对于蛇头来说,有了这个Dir变量之后,在键盘没有输入任何按键时,它会读取自己的Dir的值并作出相应的移动,相当于不更改方向,直线前进,知道键盘输入了某个方向,它才会作出相应动作并改变Dir。贪吃蛇的移动同样有许多方法。更加简便的一种是只需要将蛇的最后一个结点移动到蛇头的前一个结点,并使它成为头结点。当然,前一个方法更加直观,在算法上也更加有“蛇”的效果,因此采用了前者。还有一个贪吃蛇移动的小问题,注意到贪吃蛇是不可以向后走的,即连续两次的移动方向不可以相反,否则蛇头就会沿着自己的身体前进,直接造成“撞墙”,从而GameOver,而这是我们不愿意看到的,因此要考虑避开这种情况。而贪吃蛇移动时,移速的改变可以依靠一个全局变量dtime,蛇的每次移动都延时dtime的时间,初始化的贪吃蛇的移动速度为1500ms,则只要将dtime的初值设置为1500,在蛇每次吃到苹果时将dtime的值减少10,就可以做到不断加速的效果。3.实验程序设计代码如下:#includestdio.h#includetime.h#includestdlib.h#includeSDL/SDL.h#includeSDL/SDL_draw.h浙江大学硕士学位论文11个人简历7#defineMX(x)((x)*10+121)#defineMY(y)((y)*10+41)structmysnake{intx;inty;intDir;structmysnake*next;structmysnake*last;//prev};struct{intflag;intpoint;}Point[42][42];intesc=0;intHdir=SDLK_RIGHT;SDL_Surface*screen;intdtime=180;voidSetGame();voidProgress();voidSetApple();structmysnake*Move(structmysnake*head,structmysnake*tail,intmovex,intmovey);浙江大学硕士学位论文10附录8voidClean(structmysnake*head);voidSnake(structmysnake*head);intmain(void){if(SDL_Init(SDL_INIT_VIDEO)0){fprintf(stderr,Initvideofailed:%s\n,SDL_GetError());exit(1);}screen=SDL_SetVideoMode(640,480,16,SDL_SWSURFACE);if(screen==NULL){fprintf(stderr,Setvideomodefailed:%s\n,SDL_GetError());exit(1);}atexit(SDL_Quit);SetGame();getchar();return0;}voidSetGame(){inti,j;for(i=0;i42;i++)for(j=0;j42;j++){浙江大学硕士学位论文11个人简历9Point[i][j].flag=0;Point[i][j].point=0;}for(i=0;i42;i++)Point[0][i].flag=1;for(i=0;i42;i++)Point[41][i].flag=1;for(i=0;i42;i++)Point[i][0].flag=1;for(i=0;i42;i++)Point[i][41].flag=1;Draw_Rect(screen,129,49,402,402,SDL_MapRGB(screen-format,0,0,255));Draw_FillRect(screen,130,50,400,400,SDL_MapRGB(screen-format,255,255,255));SDL_WaitEvent(NULL);Progress();}voidProgress(){structmysnake*head,*tail;intkey;SDL_Eventevent;head=(structmysnake*)malloc(sizeof(structmysnake));tail=(structmysnake*)malloc(sizeof(structmysnake));浙江大学硕士学位论文10附录10head-next=tail;head-last=NULL;head-x=20;head-y=20;head-last=NULLhead-Dir=RIGHT;Point[20][20].flag=1;tail-next=NULL;tail-last=head;tail-x=19;tail-y=20;tail-Dir=RIGHT;Point[19][20].flag=1;Snake(head);SetApple();while(!esc){SDL_Delay(dtime);while(SDL_PollEvent(&event)){if
本文标题:Linux下基于SDL图形库的贪吃蛇游戏
链接地址:https://www.777doc.com/doc-5912717 .html