东南大学自动化学院 鲁瑜亮 汪 帆
基于Matlab GUI的RPG游戏的设计与实现
东南大学自动化学院鲁瑜亮汪帆
简要介绍了RPG游戏的要素和玩法,Matlab GUI的优点,作用和使用。本文设计的游戏立意于环境保护,通过主人公的旅途,通过四个不同的场景经历的故事,宣传绿色世界的主题。本文梳理了整个游戏的总体设计和实现,着重介绍了变量初始化,游戏对战部分,键盘输入部分,外部文件的载入(包括角色,存档,配置,媒体)。
RPG游戏;Matlab GUI;游戏对战;配置文件;存档
RPG,即角色扮演游戏(Role-playing game)。在游戏玩法上,玩家扮演一位角色在一个写实或虚构的世界中活动。玩家负责扮演这个角色在一个结构化规则下通过一些行动令所扮演角色发展。MATLAB 是美国MathWorks公司出品的商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境。图形用户界面是指由窗口、菜单、图标、光标、按键、对话框、和文本 等各种图形对象组成的用户界面。它让用户定制用户与Matlab的交互方式,而命令窗口不是唯一与Matlab的交互方式。Matlab的GUI(图形用户接口设计)采用面向对象的技术,MATLAB具有丰富的函数库,强大的图形处理能力,界面设计更加简洁、快捷、直观。
本文将RPG与Matlab GUI结合,研究使用Matlab开发游戏的方法。
2.1总体设计
角色扮演游戏可简化为开头,各章节和结局,而结局在所有章节载入完成后触发。根据这一原理我们可以设计一个程序流程。图2-01为本程序流程图。
图2-01 程序流程图
程序界面部分使用MATLAB的GUI来设计。MATLAB的GUI窗口化界面可方便开发。
2.2变量初始化
在程序第一次运行时应初始化好一些必要变量,以便各函数作为参数调用。一些特殊的变量在初始化完成后不允许修改。这类变量在初始化时被添加到handles中,并规定除了初始化函数GAFrame_OpeningFcn,其他各函数严禁使用guidata函数。这可以保证这类变量不被误修改。
经常需要修改的变量不储存在handles中,而是存在各控件的UserData中。用get函数获得变量,用set函数储存变量。这类变量的获取及更新代码写法如下所示:
DialogData=get(handles.textDialog,'userdata'); %从UserData中获得变量
set(handles.textDialog,'userdata',DialogData); %储存变量到UserData中
2.3对战部分
任何游戏都少不了对战部分。本游戏参考UNDERTALE游戏的对战部分,将对战环节设计为躲避类游戏。游戏中各个元素用Axes的子类Line和Patch实现,Line可方便实现元素的移动,Patch便于修改元素外形。对战部分流程图可简化为如图2-02所示。
游戏中使用timer作为计时器,用于定时执行游戏操作,包括移动元素位置及进行逻辑判断。计时器初始化、启动及关闭的示范代码如下所示:
hTimer=timer; %定义一个定时器
set(hTimer,'ExecutionMode','FixedRate'); %周期执行模式
set(hTimer,'Period',0.018); %周期18ms
set(hTimer,'TimerFcn',{@ExecuteGame,handles}); %定时器的执行函数
start(hTimer);%启动timer
stop(hTimer); %停止timer
对战部分效果图如图2-03所示。
图2-02 对战部分流程图
图2-03 对战部分效果图
2.4键盘输入部分
GUI自带的回调函数KeyPressFcn在键盘被按下任意值时触发,用这一函数可以实现人机互动。当KeyPressFcn函数响应时,从figure的currentcharacter属性中可获得键位值。
游戏在不同的状态对按键的响应一般是不一样的。为了实现不同状态下按键响应不同,可以使用一个非只读变量记录当前状态,并在KeyPressFcn函数中用switch对不同状态值实现不同操作。
游戏的外部文件一般与程序部分是分开的。不同的外部文件程序采用不同的载入策略。
3.1角色载入
作为一款角色扮演游戏,自然少不了其他角色来烘托剧情。为了将角色形象载入到游戏中,我们使用Axes控件来储存角色图片信息。修改Axes控件的Position属性就可以实现修改角色的位置和大小。
Axes控件本身不能载入图片,但它的子类Image可以储存图片,且Image有很多实用的属性。本程序载入角色图片的代码写法如下所示:
[A,map,transparency]=imread(NPCData.NPCPic{1});
NPC.Image=image(A, 'parent', axesNPC{num},'visible','off');
if(~isempty(transparency))%如果有透明度则载入透明度
set(NPC.Image,'AlphaData',transparency);
end
3.2存档载入[4]
存档文件可以保存游戏记录,是游戏非常重要的一个组成部分。为了保存玩家游戏记录,我们特别设计了用于保存游戏记录的存档文件。在MATLAB中我们可以用fopen函数和fclose函数打开和关闭文件句柄,用fwrite函数向文件写入存档信息。将存档保存到文件的代码写法如下所示:
fid=fopen(filename,'w');%打开文件句柄
fwrite(fid,saveData.chapter); %保存章节信息
fclose(fid); %关闭文件句柄
存档文件应在游戏启动时就载入到游戏中。MATLAB的fread函数可以实现从文件中读取数据的功能。从存档文件中读取数据的代码写法如下所示:
fid=fopen(filename,'r'); %以只读方式打开文件
saveData.chapter=fread(fid,1); %读取章节信息
fclose(fid); %关闭文件句柄
为了保证存档被正确载入,在存档时,我们特意在存档文件开头写入存档文件的大小。游戏在载入存档时先检查一下文件大小,大小正确则继续载入存档,若不正确应立即停止载入,防止程序出错。MATLAB 的fseek函数可以设置文件指针,实现从文件指定位置读数据。
存档文件载入成功后游戏将从上一次玩家退出游戏的地方开始载入游戏。
3.3配置文件载入
为了更好的维护代码及更新剧情,本游戏独立设计了配置文件。配置文件的作用是指导系统如何加载对白、图片及音乐这类的外部素材文件。我们设计了两种配置文件,一种是初始化配置文件,用于初始化系统参数。另一种是章节配置文件,用于初始化章节信息。
MATLAB可以用fgetl函数一次读取一行文本内容,用strtok函数可以提取配置文件的指令及参数。用strtok函数提取指令及参数的代码如下所示:
string=fgetl(fid); %一次从文本文件中获得一行数据
[str, remain] = strtok(string, '< >'); %str变量储存命令指令
[para1,para2] = strtok(remain, ‘ > = ‘);
parameter=[para1,para2]; %parameter变量储存参数
提取到指令及参数后,可以用switch选择模块选择不同操作。为了忽略指令的大小写,可以用lower函数将所有接受到的指令改为小写。
3.4媒体文件载入
大部分游戏都是有音乐、图片、视频等媒体信息的,本游戏也有音乐和图片媒体。图片媒体的载入与角色载入一样,都是用Axes控件的子类Image来储存图片信息。至于音乐媒体,可以使用MATLAB的audioread函数读取音频文件,用audioplayer函数装载音频信息,用play函数播放音乐,用stop函数停止音乐。音频文件载入的示范代码如下所示:
[y,Fs]=audioread(inputData.BGM{index}); %读取音频文件
BGM=audioplayer(y,Fs); %装载音频信息
play(BGM); %播放音乐
stop(BGM); %停止播放
本文所实现的游戏,可玩性极佳,作品是多剧情多结局模式,有及时存档功能,可切换背景音乐,满足RPG游戏所需的所有基本要素,这个游戏最大的亮点在于脚本文件的实现,若要扩充剧情无需修改代码,只需要修改配置文件,不用重新编译程序,后续的工作量能减小。
[1]陈子为.基于Matlab GUI扫雷游戏的设计与实现[J].现代电子技术,2008,24:85-88.
[2]张贤明.MATLAB语言及应用案例[M].南京:东南大学出版社,2014:165-195.
鲁瑜亮(1994-),男,浙江长兴人,现就读于东南大学自动化学院。