R语言游戏框架设计

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-game-framework/

r-game-framework

前言

本文继续上一篇文章 R语言游戏之旅 贪食蛇入门。当我们完成了贪食蛇游戏之后,我们应该把代码进一步整理,抽象出游戏中通用的部分,分离游戏框架代码和贪食蛇游戏代码。我们就可以提取出一个R语言的游戏开发引擎,当再开发新的游戏时,只要关心游戏本身的程序设计就行了。

目录

  1. 贪食蛇的面向对象改造
  2. 游戏框架定义
  3. 在框架中重新实现贪食蛇游戏

1. 贪食蛇的面向对象改造

我们可以利用面向对象的方法论,对贪食蛇游戏进行抽象整理,并实现代码的面向对象的改造。R语言支持3种面向对象的编程实现方式,我选择基于RC的面向对象编程,关于RC详细使用请参考文章:R语言基于RC的面向对象编程

由于我们之前的代码都是通过函数来封装的,所以代码重构还是比较简单的,只要把Snake对象的属性和方法定义清楚就行了。

1.1 定义Snake类

定义Snake类,画出类图,包括属性和方法。

class1

属性解释:

  • name:游戏的名字
  • stage:当前的游戏场景
  • e:游戏中的变量,environment类型
  • m:游戏地图矩阵
  • width:矩阵的宽
  • height:矩阵的高

方法解释:

  • initialize():构建函数,用于RC类的初始化
  • init():给stage1场景初始化游戏变量
  • fail():失败查询
  • furit():判断并生成水果坐标
  • head():生成蛇头移动坐标。
  • body():生成蛇尾移动坐标。
  • drawTable():绘制游戏背景。
  • drawMatrix():绘制游戏矩阵。
  • stage0():创建开机场景,可视化输出。
  • stage1():创建游戏场景,stage1()函数内部,封装了游戏场景运行时的函数,并进行调用。
  • stage2():创建结束场景,可视化输出
  • keydown():监听键盘事件。
  • run():启动函数

1.2 全局函数调用顺序图

接下来,根据UML规范画出顺序图,主要包括全局函数调用和stage1场景游戏环境调用。

全局函数调用关系。

  1. 通过run()函数启动游戏,进入stage0场景,注册键盘事件。
  2. 在stage0场景按任意键切换到stage1场景。
  3. init()出始化stage1场景的游戏变量。
  4. stage1()运行游戏
  5. 当游戏失败fail()或按q键
  6. 游戏进行stage2场景,显示游戏结束画面,
  7. 按空格键回到stage0重新开始,按q键退出程序。

seq1

1.3 stage1场景游戏环境函数调用顺序图

stage1场景游戏环境函数调用关系。

  1. 游戏进入stage1场景,按上下左右(up,down,left,right)方向键操作蛇头的前进路线。
  2. furit()函数检查,如果地图上水果被吃掉,生成一个新水果,记录到矩阵中。
  3. head()函数,通过上下左边键的操作,进行蛇头的移动,记录到矩阵中。
  4. fail()函数失败检查,no未失败继续,yes失败进行stage2场景。
  5. body()函数,蛇身体移动,记录到矩阵中。
  6. drawTable()函数,画出游戏背景画布。
  7. drawMatrix()函数,画出游戏矩阵。

seq2

利用UML的方法,通过类图和顺序图的描述,我们就把贪食蛇的游戏程序进行了面向对象的设计改造。不用着急去写代码,我们再想想如何进行游戏框架的提取。

2. 游戏框架定义

要设计一个完整、易用、有良好扩展的游戏框架是比难的,但我们可以基于贪食蛇的游戏,一步一步来做抽象。抽象过程就是把程序对象化,上面的我们已经做了;第二步再把公用的属性和方法提取封装,可以统一把公用的部分提取到一个Game的父类里面,让Snake类继承Game类,从而实现游戏框架定义。我们画出Game类和Snake类的类图。

class2

  • Game类公共属性,包括了所有的Snake类的属性,这是因为这些属性都是全局的,其他的游戏也会用到,而且每个游戏中的属性,可以在e中进行定义。
  • Game类公共方法,包括了游戏全局调用的方法,但不包括Snake游戏stage1场景中运行的方法。在Game类的方法中,我们主要实现的都是开发的辅助功能。
  • Snake类方法,同样还有Game类的方法,这是用到方法的重写技术。子类的方法,先调用父类的同名方法,然后再执行子类方法里的程序。

这样我们就简单地分离了游戏框架Game类和游戏实现Snake类,下面我们要做的就是把代码按照设计进行实现,看看我们的设计是否是合理的。

3. 在框架中重新实现贪食蛇游戏

Game类的代码实现,用R语言的RC面向对象编程进行代码编写。


Game

Snake类的代码实现,继承Game类,并实现贪食蛇游戏的私有方法。


# 引用game.r文件
source(file="game.r")

# Snake类,继承Game类
Snake0 | length(which(e$head>width))>0){
         fail("Out of ledge.")
         return(NULL)
       }
       
       # head碰到tail
       if(m[e$head[1],e$head[2]]==e$col_tail){
         fail("head hit tail.")
         return(NULL)
       }
     },
     
     # 随机的水果点
     furit=function(){
       if(length(index(e$col_furit))<=0){ #不存在水果
         idx0) { #如果有尾巴
         e$tail<0)
       px

最后,我们运行snake.r的程序,就完成了整个贪食蛇游戏。游戏运行效果,可以查看上一篇文章,R语言游戏之旅 贪食蛇入门 的游戏截图和动画。

对于贪食蛇游戏的开发,我们已经完成了,虽然界面还是比较土,而且没有时间维度的操作。那么我们换一个角度思考,如果不太要求画面效果,而且不需要时间维度的游戏,是不是R语言会表现的更好呢?当然,这类游戏也有很多,比如最近流行的2048。那么接下来,就用我们的游戏框架,再来做一个2048的游戏吧,试试在100行之内实现。

转载请注明出处:
http://blog.fens.me/r-game-framework/

打赏作者

This entry was posted in R语言实践, 游戏

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值