精力过剩 打打飞机
自从微信将打飞机游戏更换为“全民飞机大战”后,我就再没有下载玩耍了。把玩手机时,有时会想起过去那种手指划过屏幕,指挥小飞机穿插在千军万马中,努力为提高排名而奋战的时光。无聊时偶尔会找电脑版来玩 玩,但电脑版玩起来感觉完全不对,于是决定自己设计一个,一来怀怀旧,二来检验下VB设计简单平面游戏的能力,三来为MH370上的乘客祈福,游戏里飞机没了可以重来,MH370看来永远回不来了,一路走好!(这个有点扯 ,权当提醒各位:珍惜当下,珍爱生命吧)。设计该游戏所需的素材还是比较容易找的,大都用于JAVA游戏设计用。素材可以通用,算法才是你自己的。原本打飞机游戏是苹果公司放在自己的平板系统中的,后被唯利是图的腾讯公司山寨进来吸引用户,并被改成苹 果版和安卓版了,电脑版的打法都是类似安卓版的,我用的是苹果手机,当然要按照苹果版来设计了,这两种版本有两处区别:一是出子弹的方式,苹果版每次出一颗子弹,子弹不消失不出子弹,因此此你越抵近打击,子弹 频率越快,安卓版子弹连续出,频率不变;第二个区别是随机出敌机的方式,我觉得苹果敌机出的更谨慎,而安卓一下子就有大飞机出来了(我真不知道狗屎的腾讯公司怎么还把这两种方式放在一起排名,安卓随随便便可打 300万以上,而我在苹果里大都100万左右就挂了)。
闲话少叙,还是说游戏设计。我这次提供的压缩包里有游戏资源(图片、声音)、我编辑好的游戏所需图元信息文件、一个图元编辑程序和该程序使用说明、一个编译了的打飞机游戏(未完成无敌版)、一个VB工程文件 ,工程文件只有基本控件,代码我打算逐步添加,以供初学者参考(我也是第一次设计即时战斗游戏,望得到有经验者指正,互相学习)。该游戏用到的所有图片单元(以下简称图元)是放在一张shoot.png的图片里,我没找到vb读png文件的相关资料,所以我用ps对该图片进行了处理,形成两个文件,一个是图元集合图片shoot.jpg,一个是图元遮罩图片shootmask.jpg,利用遮罩图片的留白部分完成对应图元不透明的处理,我专门写了个提取各图元信息的程序,并对图元归类命名,这些信息放在pel.dat文件中,各位可以运行“图元编辑.exe”,看看我编辑了哪些图元,怎么命名的。
显然,我们不能过多妄想用VB来写图形处理代码,否则运行速度直接让你崩溃。其实很多大佬已经用VB调用DX来做游戏了,这个游戏不需要,调用GDI做图形处理就足够。我这里用到了几个API,分别是:StretchBlt剪切缩放拷贝图片,BitBlt剪切拷贝图片(可以比StretchBlt快点),CreateCompatibleDC、CreateCompatibleBitmap、SelectObject、DeleteDC、DeleteObject等内存场景相关调用,用内存场景操作图像比在控件里操作图像要快。我的思路是:首先把所需的图片文件调入相应的内存场景DC中,建立一个缓冲DC,所有缓冲算法是对缓冲DC操作,最后定时把缓冲DC的图形刷到窗口里显示。由于大多用API调用完成,窗口里安排的控件比较少,我的设计窗口如下图:
控件说明:一个MMControl控件数组mmc1(0),用来完成声音及音效播放;两个timer控件,分别是FreshDC和Proce,主要用来每20毫秒刷新显示和每半秒产生随机图元;一个picturebox控件pic1,主要调图片的过渡用,因为我没有找到直接把图片调入内存场景方法(GDI+有,但转换、初始化等手续多,懒得弄),该图片过渡完后,一定要使用 set pic1.picture=nothing,语句释放资源。下面是我的变量、数据结构以及函数声明的代码及工程压缩文件,暂时写到这里。
经典飞机大战.zip
(2.82 MB)
程序代码:
Private Type CutPelInfo '图元剪裁信息 Name As String '图元名称 Index As Integer '动画系列号 X As Single Y As Single '剪裁左上角坐标 w As Single h As Single '剪裁大小(宽高) End Type Private Type DefPel '自定义绘制图元的数据结构 State As Integer '图形性质0:无图元,1:无害图元(如爆炸残骸) 2:敌机图元 3:我方图元 Name As String '对应声音文件名 AniIndex As Single '图元动画编号索引 AniStep As Single '图元动画步进速率 AniCir As Boolean '动画循环标志,True时循环显示,否则显示完该图元即消失(爆炸动画即如此) Strength As Integer '抗击打力,敌机每中弹一次该数据减1,为0即爆炸消失。敌小机1,敌中机5,敌大机12 Score As Integer '击毙得分,敌机设置该项,敌小机1000,敌中机6000,敌大机30000 X As Single Y As Single 'XY是图元中心点位于显示场景坐标, xStep As Single yStep As Single '图元运动方向和速率,如xStep<0则向左运动,0不运动,>0则向右运动,数越大则越快 w As Single '图元宽 h As Single '图元高,每次在场景中显示时获取,主要用于判断该图元是否跑出边界 End Type Private Declare Function StretchBlt Lib "gdi32" (ByVal hDc As Long, ByVal X As Long, ByVal Y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, _ ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long Private Declare Function SetStretchBltMode Lib "gdi32" (ByVal hDc As Long, ByVal nStretchMode As Long) As Long Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, _ ByVal dwRop As Long) As Long Private Declare Function DeleteDC Lib "gdi32" (ByVal hDc As Long) As Long Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDc As Long) As Long Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDc As Long, ByVal nWidth As Long, _ ByVal nHeight As Long) As Long Private Declare Function SelectObject Lib "gdi32" (ByVal hDc As Long, ByVal hObject As Long) As Long Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Dim Zoom As Single '缩放比例 Dim BgDc As Long '背景内存场景 Dim BgMove As Integer '背景移动计数,用于循环移动背景 Dim ShootDc As Long '源图像内存场景 Dim MaskDc As Long '源图像掩码内存场景 Dim BuffDc As Long '内存缓冲场景,防止图像显示闪烁 Dim CutPel(100) As CutPelInfo '存储图元剪裁信息数组 Dim DispPel(100) As DefPel '显示图元,0、1子弹,2-4保留,5-85随机,86我方战机,87暂停,88保险,89-90保险数,91-100显示得分 Dim PlayTime As Long '游戏时间计数(每半秒计数一次) Dim DifftyData As Integer '难易程度,最高为100 Dim CanMove As Boolean '能否移动我方战机标志 Dim AmmoState As Integer '弹药状态,不为0时为双弹(蓝弹) Dim UnconTime As Integer '无敌计时,0:我战机常态 >0则无敌 Dim Score As Long '成绩 Dim PauseFlg As Boolean '暂停标志 Dim BombNum As Integer '保险数量 Dim MyNum As Integer '我战机数量,数量为0时GameOver
[ 本帖最后由 lowxiong 于 2014-4-6 06:37 编辑 ]