C#版贪吃蛇游戏的设计与实现

2015-01-18 01:46商利华
电脑与电信 2015年11期
关键词:蛇头内存绘制

商利华

(无锡城市职业技术学院,江苏 无锡 214153)

C#版贪吃蛇游戏的设计与实现

商利华

(无锡城市职业技术学院,江苏 无锡 214153)

本文基于C#开发环境,开发了一个界面美观、操作简单、功能更为齐全的贪吃蛇游戏。整个游戏包括单人游戏、联机对战、地图选择、音效播放等功能。通过本游戏的开发,达到学习C#技术和熟悉软件开发流程的目的。

贪吃蛇;C#;GDI+

1 引言

贪吃蛇是一款经典的小游戏。游戏规则是玩家使用方向键操控一条长长的蛇不断吞下金蛋,同时蛇身随着吞下的金蛋不断变长,当蛇头撞到蛇身或者蛇身撞壁时则游戏结束,如图1所示。

图1 蛇身及贪吃蛇游戏界面

2 设计思路

贪吃蛇的核心算法是如何实现移动和吃掉道具,从而解决蛇身移动、吃到道具后身体增长、减短、反向、减速、撞墙、死亡等问题,并且能够随时暂停或开始游戏。程序的关键是表示蛇的图形以及蛇的移动。本游戏用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。移动时必须从蛇头开始,所以蛇不能向相反方向移动,也就是蛇尾不能改作蛇头。如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝着指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇。食物的出现和消失也是画矩形块和覆盖矩形块。

本游戏主要设计了snakeClass和snakeFood两个类。snakeClass是模型类,有长度、颜色、速度、方向、状态等属性,有蛇的移动snakeMove()、蛇的碰撞判断SnakeCollide()、蛇吃道具SnakeEatFood()等方法;snakeFood是食物道具类,其基本属性包括位置及状态,主要方法为道具的新建foodCreate()过程。道具的位置是随机的,蛇头每次触碰到道具,蛇身在加长的同时成绩加分数,这样累加,直到游戏结束,在显示结果的文本框内显示玩家最终的成绩[1]。

游戏的开始、结束、暂停以及加分功能均在窗体的代码事件中完成定义过程。开始是由用户通过单击命令按钮实现的;游戏过程中的任意时刻玩家只要按下空格键均可进行游戏的暂停状态,再次按下空格游戏继续进行;另外每吃掉一个道具,玩家的总成绩会加分,最终可以在文本框控件内累积出当前玩家的最高分。

3 游戏实现

本游戏在继承传统同类游戏规则的基础上,添加了地图选择、地图解锁、双人游戏、鼠标特效等功能,游戏规则包括蛇的运动范围、蛇的生命周期、分数统计、关卡判断,具体设计如下:

地图:蛇的运动范围是一个地图,蛇运动的地图抽象成为一个40*40的二维整形数组,每个数组值代表一个小方块的坐标值,这样,蛇只能在规定好的二维数组内运动。当蛇遇到数组左右边界值时,宣告蛇生命周期结束,贪吃蛇死亡。

蛇的生命周期:当蛇自己吃到自己身体的某一部分时,也宣告游戏结束,在程序里通过循环判断蛇头下一个前进方向的节点是不是蛇身上的某一部分节点即可,如果是那样蛇死亡,否则继续运行游戏。当蛇撞上地图上任意一个障碍物时要么蛇死亡,否则继续运行游戏。当蛇穿过闪电并且身体长度少于3时则蛇死亡,否则继续运行游戏。

分数统计:分数统计算法的思想是每次蛇吃到一个果实时,相加的分数为自身的长度,这样可以随着游戏难度的增加,分数值也随之增多。关卡功能设置通过与分数相关联体现,初始化游戏分数为0,关卡由玩家自己选择,地图预先设置在程序中。地图中包含了闪电,但蛇移动到闪电区域触发闪电时会截去闪电以后的身体部分,当身体长度小于3时则判定死亡。

3.1 游戏界面设计

图2 游戏LOGO、游戏主菜单、游戏子菜单、游戏初始化、游戏排名

本游戏在传统贪吃蛇的功能基础上,进行了全新的界面设计和音效设计,整款游戏界面简洁美观,色彩鲜明,音效丰富,部分界面效果如图2所示。

//地图选择,游戏的初始化代码,蛇的坐标初始化

3.2 蛇的显示

游戏中完整蛇形状的绘制:主要通过一个链表,其中存储蛇身体的每一节所需的坐标,当蛇移动时,将取出尾坐标将它变为头坐标加到头上实现蛇的移动,并创建一个平行的链表存储蛇对应每节所需显示的图片,再通过下述代码实现绘制,最后就是一条完美的蛇了,效果如图1蛇身所示。

3.3 道具

游戏中每当蛇吃到道具时,需要重置道具。道具分为八种,分别为:普通,加两格,加三格,减一格,减两格,加速,减速,隐身。如图3所示。

图3 道具

3.4 游戏开发过程中的问题

(1)画面的闪烁问题

在游戏开发前期图片采用多线程来分别绘制,然而在游戏编译运行的过程中发现,GDI+如果使用多线程来绘制图片,会产生非常严重的闪烁问题,后使用了双缓冲技术,把所有的图像刷新都放在内存中的一个缓冲区(Buffer)中,然后在游戏画面需要刷新的时候只需输出缓冲区中最终的图像信息就能够解决闪烁的问题[2-3]。下面是本游戏中采用的图像绘制代码:

//以Bitmap为缓冲载体:Bitmap FBuffer=new Bitmap (_ScreenWidth,_ScreenHeight);

//graphics绘制图像到Bitmap中:Graphics FPainter= Graphics.FromImage(FBuffer);

//绘制图片:Image map01=Image.FromFile("..//..//images// map01.png");

//绘 制 文 字:FPainter.DrawString(FMessage,FMessage-Font,FMessageBrush,new PointF(X,Y));

//最后在主程序中绘制包涵图片信息的Bitmap:FScreen. DrawImage(FBuffer,0,0);

(2)音频播放及内存资源占用过大的衍生问题

游戏先后使用了WindowsMediaPlayClass,winmm.dll的非托管方式来播放音频。后来发现如果使用WindowsMediaPlayClass提供的音频播放方法,一个音频文件还好,多个音频文件一起播放就会让内存占用量显著升高,在有的电脑上还会导致内存溢出的情况,初步认为是托管方式对于内存的回收方面并不是很完美,而且无法使用多线程播放音频。又使用了winmm.dll的非托管播放方式,发现内存占有量显著降低,但是没有前者所提供的音量操控等方法。最后取彼之长补彼之短,使用WindowsMediaPlayClass播放背景音乐这种非随机事件,用winmm.dll来播放菜单音效这种随机高频度事件,来达到中和的效果。

4 结语

本文开发的升级版贪吃蛇游戏除实现基本功能外,附加了许多趣味性新功能,牵涉到了图形界面的显示与更新、数据的收集与更新等,对开发类似的GDI+游戏有很好的借鉴作用。

[1](英)夏普.Visual C#2005从入门到精通[M].周靖,译.北京:清华大学出版社,2006.

[2]杨睿娜.C#开发贪食蛇游戏[J].电脑知识与技术,2011(18).

[3]雷丽娟,郑永彬.使用Java制作贪吃蛇游戏[J].科技视界,2013 (4).

Design and Implementation of Snake Game in C#Version

Shang Lihua
(Wuxi City College of Vocational Technology,Wuxi 214153,Jiangsu)

In this paper,based on C#development environment,a snake game is developed with beautiful interface,simple operation and complete functions.The game includes a single player game,online game,online map selection,audio playback and other functions.Through the development of the game,it can achieve the purpose to learn C#technology and familiar with the software development process.

snake game;C#;GDI+

TP311.52

A

1008-6609(2015)11-0065-03

商利华,女,江苏无锡人,本科,讲师,研究方向:.NET平台开发,数据库应用。

猜你喜欢
蛇头内存绘制
过山风(微篇小说)
蛇头与蛇尾
蛇头与蛇尾
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
“春夏秋冬”的内存
超萌小鹿课程表
放学后
穿越撒哈拉的“蛇头”(上)
内存搭配DDR4、DDR3L还是DDR3?
在转变中绘制新蓝图