飞行棋游戏的设计与实现

更新时间:2023-07-18 11:12:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

哈尔滨师范大学

学 年 论 文

题 目 飞行棋游戏设计与实现 学 生 俞学君 指导教师 邢恺 讲师 年 级 2008级

专 业 计算机工程与应用 系 别 计算机科学与技术 学 院 计算机科学与信息工程学院

哈尔滨师范大学 2011年 6 月

论 文 提 要

关于飞行棋发明的年代和发明人,在网络上似乎还没有相关的线索。比较一致的意见是他至少发明于大约二战以后,因为它是关于飞行的(FLIGHT GAME)。但也有人认为这一点没有说服力,因为它有可能是先有了规则再被冠上了飞行棋的名字,在飞机发明前就出现这一游戏是完全可能的。再说,它可以跟飞机(PLANE)没有直接关系,因为它的名字只是提到飞行(FLIGHT)。

飞行棋

这个应该是国人的原创,是中国玩具公司生产的,据说是为了纪念二战时飞虎队的卓越功勋,是pachisi游戏的变种。

飞行棋这种转圈式的路程设计来自于空战中的“拉弗伯雷圆圈”。法国人拉弗伯雷对德国的"大圆圈编队"战术作了改进,使参加编队的飞机不但保持在一个水平面上飞行,而且可绕圆圈盘旋爬高。这样就可以利用防御队形进行盘旋以取得高度优势,伺机进行攻击。这就是著名的"拉弗伯雷大圆圈"。当时人们发明这种棋,是用一种先进的空战战术。

飞行棋游戏设计与实现

俞学君

摘 要:本文所实现的是一个简单的飞行棋游戏, 该飞行棋以 Visual Basi作为开发

语言,采用Visual Basic自带的Image控件显示游戏所需的各种图片,采用最基本的

飞行棋游戏规则,游戏中四个玩家均由人来操作! 关键词:飞行棋 设计 visual basic

一 、规则及目标

飞行棋游戏的主要道具由:棋盘一张,红、黄、青及绿色的棋子各四颗, 骰子一

个组成。本文中所要实现的游戏程序主要包含:游戏的交互界面、用户交互规则判定过程和 相关的服务模块。其中飞行棋的规则介绍如下:

起飞

只有在掷得6点后,方可将一枚棋子由“基地”起飞至起飞点,并可以再掷骰子一次,确

定棋子的前进步数。

连投奖励

在游戏进行过程中,掷得6点的游戏者可以连续连掷骰子,直至显示点数不是 6点或游

戏结束。

迭子

己方的棋子走至同一格内,可迭在一起,这类情况称为“迭子”,并可以叠著行进。 敌 方的棋子不能在迭子上面飞过;当敌方的棋子正好停留在“迭子”上方时,则允许敌方停于迭 子上面。 若其它游戏者所掷点数大于他的棋子与迭子的相差步数,则敌方棋子逐回停机坪。

撞子

棋子在行进过程中飞过的一格中,若已有敌方棋子停留,可将敌方的棋子逐回基地。

跳子

棋子在地图行走时,如果停留在和自己颜色相同格子,可以向前一个相同颜色格子作跳 跃。

飞棋

棋子若行进到颜色相同而有虚线连接的一格,可照虚线箭头指示的路线,通过虚线到前 方颜色相同的的一格后,再跳至下一个与棋子颜色相同的格内;若棋子是由上一个颜色相同 的格子跳至颜色相同而有虚线连接的一格内,则棋子照虚线箭头指示的路线,通过虚线到前 方颜色相同的的一格后,棋子就不再移动。如果棋子在准备通过虚线时有其他棋子停留在虚 线起始处到通往终点线路的巡航

圈上:A、如果对方是一个棋子,则将该棋子逐回基地,本方棋子继续行进到对岸;B、

如果对方是两个棋子重叠则该棋子不能穿越虚线、继续绕行。

终点

“终点”就是游戏棋子的目的地。当玩家有棋子到达本格时候,表示到达终点,不能再控 制该棋子。传统飞行棋规则里,玩家要刚好走到终点处才能算“到达”,如果玩家扔出的骰子 点数无法刚好走到终点出,多出来的点数,棋子将往回走。

二、 游戏的实现

整个游戏界面在一个 Form窗口中实现。控制部分由事件响应组模块组、游戏规则

判断和计算模块组、坐标计算与转换模块组三部分构成。

(一)、棋盘和界面的设计与说明

游戏界面主要由一个基本的游戏控制 菜单和18个 Image对象组成。 飞行棋棋

盘用作图软件绘制,存为Jpg格式后加载到

对象中。 该棋盘由 机场、战场、返航线、 飞行线组成,其中机场分布在棋盘的四个 角落。 战场围绕棋盘一圈,允许每一个玩 家的棋子在条件满足时进入,并在其中战 斗直到被击落或者退出战场进入返航线为 止。 返航线是玩家棋子安全退出战场获得 胜利的唯一渠道,只有抵达返航线的终点 才能判定玩家棋子任务结束。

游戏控制菜单,包括开始游戏和退出游戏两个选项。 用16个Image2对象组成的1维

数组,作为红、黄、青及绿色的棋子,每种颜色四颗。 Image3 对象 作为骰子用来模拟

掷骰子时的动作。其他几个label对象用来显示游戏中玩家的状态信息。 Text2对象用来显

示游戏的操作记录。

(二)、 游戏数据的定义与初始化

在游戏正式开始以前必须要清理掉没用的和错误的数据,为后面的正常运行准备一 个“干净”的环境,这样程序的正确运行也为调试带来方便。 1 全局变量GmData

首先我们要设置一个实现该游戏必需的一些通讯数据

Private GmData As Mtp_Game_Common, MovieStat As Movie_stat

其中 GmData 存储着游戏的主要状态信息,存储着包括棋盘坐标和棋子信息在内的各种关键数据,

整个程序就是为了正确的操作这个数据集而作。

当游戏开始时,用一个专门的子程序 Int_GameData()对它进行初始化, MovieStat 用来存储实现一些简单动画所需的临时信息。

2 Int_GameData()专用的初始化程序 本模块用来对GmData进行初始化操作。

Private Sub Int_GameData() '游戏数据初始化

Dim Player As Long, Plan As Long

Randomize Timer() '初始化随机数生成器

GmData.PlayNow = 0 '当前玩家为 0 号(红色)

GmData.Num_Round = 52 '属于战场的总格数

GmData.Try_Landing = 49 '连接战场和返航线的拐点索引号

For Player = 0 To 3 '*初始化玩家数据 GmData.Player(Player).Start = Player * 13 '起始坐标

GmData.Player(Player).CntRound = 0 '连掷次数统计

GmData.Player(Player).CntKilled = 0 '杀敌次数统计 GmData.Player(Player).CntDown = 0 '被杀次数统计 For Plan = 0 To 3 '初始化棋子 GmData.Plan(Player, Plan).Stat = Complete '完成任务

GmData.Plan(Player, Plan).Idx_Abs = -1 '棋子绝对坐标 -1 SetRlat_Idx Player, Plan '棋子相对坐标 Next Next

GmData.Player(Player).CntPoint = 0 '骰子点数统计

GetMapXYFromFile '从文件中读取属于战场的棋盘坐标 End Sub

3 GetMapXYFromFile()从文件中读取属于战场的棋盘坐标

基本思路:利用 Fos对象打开文件并读取文件的内容,将它存入到全局变量GmData下。

Private Sub GetMapXYFromFile() '从文件中读取属于战场的棋盘坐标数据

Const ForReading = 1, ForWriting = 2 '定义读和写操作的常量

Dim fso, MyFile '利用 FSO 对象进行文件读去操作

Dim Idx As Integer '一个临时变量,用来遍历战场的棋盘索引。 Set fso = CreateObject("Scripting.FileSystemObject")

Set MyFile = fso.OpenTextFile(".\RingXY.txt", ForReading) '打开文件

For Idx = 0 To 51 '遍历属于战场的索引,并读取所需的棋盘坐标。

GmData.Ring_Pos(Idx).Y = MyFile.ReadLine Next

GmData.Ring_Pos(Idx).X = MyFile.ReadLine

MyFile.Close '关闭刚打开的文件

Set MyFile = Nothing '将对象注销

Set fso = Nothing End Sub

4 intImage()棋子与骰子的初始化

Private Sub intImage() '图片框初始化

For Player = 0 To 3 For Plan = 1 To 3

Image2(Player * 4 + Plan).Picture = Image2(Player * 4).Picture '载入相关

的棋子图片

Next Next

Image3.Top = Image1.Top + (Image1.Height - Image3.Height) / 2 '将骰子放到棋盘的 中间

Image3.Left = Image1.Top + (Image1.Width - Image3.Width) / 2 End Sub

Dim Player As Long, Plan As Long '玩家和棋子临时计数器

5 Form_Load()窗体的加载过程

每一个 windows 程序基本上都是从窗体开始加载的。在这个模块中,可对游戏进行必 要的初始化操作。使游戏处于复位状态,为稍后的游戏作准备。 6 Start_Click()和Exit_Click()菜单动作

本文中的菜单很简单,只有开始和退出两个选择,对应的模块为:Start_Click()和 Exit_Click()。 (三)、骰子的模拟与控制

对于骰子的模拟与控制 主要是实现以下四点

1、骰子随机性的模拟,可以用Vb中的随机函数来模拟。

2、骰子使用状态的控制,可以通过设置Imagede Enable属性达到目的。

3、骰子在棋盘上的坐标计算与定位。

4、骰子翻转动画的过程模拟,可以通过不断加载不同的骰子图片来实现。 1 Dice()生成骰子的随机点数

机函数构成的表达式 Rnd * 6 会产生一个0~5之间的随机数,用Fix()取整后加1就产

生了 1~6之间的随机整数,其中随机种子已经由Randomize在 Int_GameData()中设定了。

2 Dice_Show()加载骰子图像

根据数字显示对应的骰子图像可以用LoadPicture 实现。

Sub Dice_Show(ByVal num As Long) '加载骰子图片

num = (num) Mod 6 '使 Num 在 0~5 之间循环变化

Image3.Picture = LoadPicture(".\" & num + 1 & ".Ico") '加载骰子图片 End Sub

3 Dice_Run_Timer()实现抛掷骰子的动画效果

要实现骰子的连掷动画则需要Timer控件的帮助了,通过timer控件循环加载骰子图像,

并作适当延迟,就产生了骰子连掷效果。经过试验,骰子延迟50 毫秒,滚动一6~12次效果

最佳。

4 PutDice2Map()控制骰子的移动

指定骰子移动到指定玩家的机场中。

Private Sub PutDice2Map(Player_now As Long) '将骰子移动到指定玩家的机场

Dim StPS As TP_XY, EdPS As TP_XY

MovDice.Enabled = False '此时禁止玩家掷骰子

GetDice_XY (Player_now) '得到骰子需要到达的那一点的坐标

StPS.X = Image3.Left '得到当前骰子的坐标

StPS.Y = Image3.Top

EdPS.Y = Image1.Top + Image1.Height / 17 * GetDice_XY(Player_now).Y '计算每次 移动所需的偏移量

EdPS.X = Image1.Left + Image1.Width / 17 * GetDice_XY(Player_now).X MovDice.Enabled = True '动画开始

SetMovie 0, StPS, EdPS, 50 '设置实现图片移动动画所需的参数

End Sub

5 GetDice_XY()查询骰子在各玩家机场上的坐标

根据不同的玩家编号返回对应的坐标,以确定骰子在棋盘上的位置

6 SetMovie()设置实现图片移动动画所需的参数 设置实现图片移动动画所需的参数 计算并设置实现图片移动动画所需的偏量。

Private Sub SetMovie(Img_Idx As Long, Start_Pos As TP_XY, End_Pos As TP_XY, ImgStep As Long)

'设置实现图片移动动画所需的参数

MovieStat.PlanImgIdx = Img_Idx 'img 索引号,仅供移动飞机用

MovieStat.Ylimt = (End_Pos.Y - Start_Pos.Y) / ImgStep 'Y方向位移偏移量 MovieStat.Finish = False '动画完成设记 End Sub

MovieStat.Xlimt = (End_Pos.X - Start_Pos.X) / ImgStep 'X 方向位移偏移量

7 MovDice_Timer()骰子移动效果的实现

实现骰子的移动效果和实现骰子的连掷动画一样也需要Timer控件的帮助,通过timer

控件不断的改变骰子图片的位置,就产生了骰子移动的效果。经过试验,以20毫秒的频率

不断修改骰子坐标,效果还可行。

8 Image3_Click()对玩家抛骰子操作的响应过程

这个模块在接到玩家点击骰子动作后,产生一个抛骰子动画,并显示一个1~6的整

数来模拟现实中的骰子,并且在后台统计相关信息。

9 Unable_Dice()与Enable_Dice()骰子的锁定与要锁过程

通常在游戏中在抛骰子的时候是不能移动棋子的,反之也一样,下面两个程序就是模拟这个约束条件。

(四)、玩家的控制与切换

在实现玩家控制与切换时,稍微麻烦一点的就是 如何判断下一位玩家是谁?同时 把骰子放到那个玩家的机场中,剩余的就是 对玩家的棋子进行锁定与要锁。

1 Unable_Player()与Enable_Player()玩家棋子的锁定与要锁过程 2 To_NextPlayer()玩家控制控的转移

Private Sub To_NextPlayer() '得到下一个玩家的编号,并把骰子传给下一个玩家

Dim p As Long '临时计数器

If GmData.Dice <> 6 Then '如果骰子不是六点,则需要把控制控交给下一个玩家

Unable_Player GmData.PlayNow '锁定玩家棋子 Do

p = (p + 1) Mod 4

Loop Until CntPlanStat(p, Complete) <> 4 '查找还有棋子的玩家 PutDice2Map GmData.PlayNow

Else '如果骰子显示六点则原来玩家继续控制该轮的骰子

Enable_Dice End If

ShowMsg '更新相关的状态信息 End Sub

p = GmData.PlayNow '初始化临时计数器

GmData.PlayNow = p '把找到后的结果给系统变量

(五)、游戏中所需文字信息的处理

对游戏中出现的各类文字信息进行简单的处理,主要包括 信息格式的转换与显示等。

1 ShowMsg()显示玩家状态

此模块除了显示玩家状态以外还担负着游戏结果判断的额外任务。 2 GetPlayerColor()将玩家的索引号转换成对应的颜色名称

(六)、棋子的响应与处理

1 Image2_Click()分析玩家的操作,不同情况作出不同处理

本模块在接到玩家操作棋子的动作后,分析玩家所选的棋子状态后,做出对应的动作。 比如:

被选择的飞机在机场则只需判断是否允许起飞。

被选择的飞机已准备起飞秩序判断,能飞多远,是否要击落其它玩家的飞机,有无坠毁 可能。

2 SetAbs_Idx()设置棋子的绝对索引号和相对索引号 为其他服务程序计算棋子状态作好数据准备

Private Sub SetAbs_Idx(Player_Idx As Long, Plan_Idx As Long, Dice_Num As Long)

'根据骰子点数设置棋子的绝对索引号和相对索引号

If GmData.Plan(Player_Idx, Plan_Idx).Stat = Landing Then '着陆航线上坐标计算

GmData.Plan(Player_Idx, Plan_Idx).Idx_Abs GetLanding_Idx(GmData.Plan(Player_Idx, Plan_Idx).Idx_Abs, Dice_Num)

Else '巡航航线上坐标计算 GmData.Plan(Player_Idx,

Plan_Idx).Idx_Abs + Dice_Num End If Plan_Idx).Idx_Abs

GmData.Plan(Player_Idx,

SetRlat_Idx Player_Idx, Plan_Idx End Sub

3 SetRlat_Idx()根据绝对索引号计算相对索引号 根据各棋子的偏移量和绝对索引号计算得出结果

Private Sub SetRlat_Idx(Player As Long, Plan As Long)

If GmData.Plan(Player, Plan).Stat = OnTheWay Then

GmData.Plan(Player, Plan).Idx_Rlat = (GmData.Player(Player).Start

GmData.Plan(Player, Plan).Idx_Abs) Mod GmData.Num_Round '棋子相对坐标

Else End If End Sub +

GmData.Plan(Player, Plan).Idx_Rlat = -1

4 GetLanding_Idx() 计算

主要是完成一个棋子回走的功能

Private Function GetLanding_Idx(Idx_Abs As Long, Dice As Long) As Long

GetLanding_Idx = Idx_Abs + Dice

If GetLanding_Idx > 55 Then '回走 End If End Function

GetLanding_Idx = 110 - GetLanding_Idx

5 Attack() 攻击一定范围内的其他玩家棋子

这是飞行棋中关键的模块之一,此模块根据玩家所选的棋子,攻击指定范围内的其 他玩家棋子,并作相关统计

6 MovePlan() 移动棋子

这是飞行棋中关键的模块之一,此模块负责移动玩家所选的棋子,并执行移动后可能 对遇到的特殊动作。

7 DoFlyAndJump()、DoJump()、DoFly()飞行和条约相关模块

在游戏中,飞行和跳跃有一定的共同点,不同的是触发条件和优先级有所区别而已, 因此用一个DoFlyAndJump() 来统筹这个功能,下面的DoJump()和 DoFly()仅仅是为方便前

者而写

8 FallingDown() 让指定棋子坠毁 让指定棋子坠毁

指定的棋子坠毁后更新玩家相关数据,并且该棋子自动回到机场,等待下次起飞。

9 Is_Fly() 判断棋子是否可以飞行

Private Function Is_Fly(Player_Idx As Long, Plan_Idx As Long) As Boolean '是否可以跳 跃

Is_Fly = False

If GmData.Plan(Player_Idx, Plan_Idx).Idx_Abs = 17 Then Is_Fly = True End If End Function

10 Is_Jump() 判断棋子是否可以跳跃

Private Function Is_Jump(Player_Idx As Long, Plan_Idx As Long) As Boolean '是否可以 跳跃

Is_Jump = False

If GmData.Plan(Player_Idx, Plan_Idx).Idx_Abs < GmData.Trn2Landing And GmData.Plan(Player_Idx, Plan_Idx).Idx_Abs Mod 4 = 1 Then

Is_Jump = True End If End Function

11 IS_Complete() 判断某玩家棋子是否全部胜利

Private Function IS_Complete(Player_Idx As Long, Plan_Idx As Long) As Boolean '是否 全部胜利

IS_Complete = False

If GmData.Plan(Player_Idx, Plan_Idx).Idx_Abs = 55 Then GmData.Plan(Player_Idx, Plan_Idx).Stat = Complete IS_Complete = True End If End Function

12 GetForwardTest() 判断棋子能否走到骰子所示的点数

指定棋子前面的 Range 范围内 安全则返回 Range,否则返回一个小于 Range 的整数。

13 CntFormation() 统计迭子数量

Player_Idx 在 Idx_Rlat 上有多少迭子,返回 1~4 之间的一个整数

Dim Plan As Long, T As Boolean CntFormation = 0 For Plan = 0 To 3

If GmData.Plan(Player_Idx, Plan).Stat = OnTheWay Then

If GmData.Plan(Player_Idx, Plan).Idx_Rlat = Idx_Rlat Then

CntFormation = CntFormation + 1 End If End If Next End Function

Private Function CntFormation(Player_Idx As Long, Idx_Rlat As Long) As Long

14 CntPlanStat()统计某玩家出于某种状态的棋子数量

Private Function CntPlanStat(Player_Idx As Long, Stat As Plan_Stat) As Long

Dim Plan_Idx As Long CntPlanStat = 0 For Plan_Idx = 0 To 3

If GmData.Plan(Player_Idx, Plan_Idx).Stat = Stat Then

CntPlanStat = CntPlanStat + 1 End If Next End Function

4.6.14 CntComplete() 统计某位玩家完成任务的棋子数量 Private Function CntComplete(Player_Idx As Long) As Long

Dim Plan_Idx As Long CntComplete = 0

CntComplete = CntPlanStat(Player_Idx, Complete) End Function

(七)、棋子图片在窗体上的定位

1 PutAllPlantomap()将所有棋子图片放到窗体的棋盘上

对所有玩家的飞机进行遍历,然后利用 PutPlantomap 和 GetMap_XY 模块将飞机移动 到棋盘上

2 PutPlantomap()将特定棋子放到窗体中棋盘的对应位置上

查询指定指定棋子的棋盘坐标,并利用该棋子的图片放到窗体对应的位置上

三、 性能测试与分析

(一)、系统开发环境 硬件平台:

CPU Intel(R)Pentium(R)M processor 2.0 GHz 内存1G

硬盘80G

软件平台:操作系统 Windows XP professional sp2,

开发工具:Microsoft Visual Basic 6.0 (二)、 系统测试

在开发本系统时,为了使系统能够稳定运行,对本系统进行了有针对性的全面测试, 采取的方式是:

1模块测试:为了保证每个模块能够正确实现系统设计的功能,我把相关的基础数据,基本上全部输入到本系统中,并反复进行了增加、删除、修改等操作,保证了模块功能的 实现。

2数据跟踪:完成模块测试后,我又对系统内的每一个数据进行了跟踪。

3棋合测试:在以上测试的基础上对系统功能进行了整体的测试,依次来检验系统 功能是否符合系统设计的要求。

测试结果:本系统基本完成了设计要求。

四、结束语

经过几个月的设计与实践,基本完成了飞行棋的功能,经过这次的游戏开发实践让我得 到了充足的锻炼,尤其是在遇到麻烦的时候,能够积极向老师寻求帮助,以及求助于网络上 的游戏制作爱好者,在这过程中也结交了很多朋友,在很多方面我们都能够一同进步!经过 这次的游戏制作,使我的编程水平得到了提高,以及游戏架构的能力得以加强,同时也对游 戏制作产生了浓厚的兴趣!希望以后的学习中能够更加的完善自己!

参考文献:

[1]国家863中部软件孵化器:《Visual Basic从入门到精通》人民邮电出版社 2010 年3月12日。

[2]黄石:李志远《游戏架构设计与策划基础》清华大学出版社2011年1月。

学年论文(设计)成绩表

本文来源:https://www.bwwdw.com/article/3wr1.html

Top