第五章:Layout

我有个想法


你有没有想过你为什么要阅读本系列教程?

好奇?爱好?

是创造小世界的想法。

想法是万恶之源。也是你下定决心做游戏的动力源泉。有了想法,你开始思考:

千里之行,始于想法

直接把想法变为现实好比一步登天,谈何容易?但荀子说:“不积跬步,无以至千里;不积小流,无以成江河。骐骥一跃,不能十步;驽马十驾,功在不舍”,即把想法变为现实要一步步来,成功的路上没有天才与庸人,只有坚持不懈的苦行僧。

有没有捷径可走?有。不过请注意,这是你的另一个想法。

我们都知道上十层楼坐电梯要比双腿快得多,可见工具是一种捷径。使用工具并不容易,因为前提一是得知道它的存在,二是得知道如何使用它。好在我们已经知道了jME3的存在并且我们正在学习如何使用它:

另一个想法

但是你并没有直接学习jME3——事实上你想通过看我写的教程间接学习jME3。这是你再次使用“学习jME3有没有捷径可走?有”这套逻辑的结果。同时这是你的第三个想法:

陷入“XXX有没有捷径可走?有”的死循环

不久后,你可能就会:

忘记初衷

是的,你遇到了想法的天敌——遗忘。

随着时间的推移,想法变得模糊、灵感昙花一现。曾经的誓言变成了谎言,对游戏的炙爱已随冰冷的现实悄然熄灭。你会说:也许这就是成熟;依我看:好记性不如烂笔头。

起草


对抗遗忘最好的办法是把想法记下来。你可以经常看到,工程师在制造机械前会绘制工程蓝图;漫画家在构思人物时会绘制人物三视图线稿;主持人在承启节目中会翻看提前准备好的台词提纲。我喜欢一有想法就写进手机的备忘录里,然后过段我会整理这些新奇的想法,把有关联的想法统一用思维导图排版好。思维导图工具我最先使用的是ProcessOn,在线免费;后来是XMind,功能丰富;但是刚刚发现MindMaster貌似格调更高点,在此推荐给各位。

UI设计是思维导图确定下来后接着要做的事。“用户首先点击应用图标,来到加载界面;数据初始化完成后,界面从加载界面跳转到登录界面或是欢迎界面……”像这样大概构思一下系统会有哪几个界面,然后把它们大致画下来。绘制UI界面我使用的是PhotoshopCS6(提取码:4idc)。有能力你可以学一下Ai,据说要比Ps更适合做Logo等不同尺寸、颜色简单的图形。

UI布局设计图画好了、各个界面上的组件图片资源也有了之后,我们得想办法让程序识别并把它们变成一个个组件类对象。传统的做法是用Ps把全部美术资源导出为png格式的图片,然后放到程序目录下通过png格式图片加载器加载图片,接着手动把这些图片配置到组件中,最后设置组件的位置、组件间的关系。这种做法简单粗暴、通用性强,但是重复劳动量与图片数量成正比,维护性较差。

程序员的天职是让计算机代替人类。于是很自然地,我想:“为什么不直接让程序读取psd数据,然后自动生成组件?”。后来这成为了我的课题。事实证明计算机无法完全取代人类:目前没有算法可以100%按照人类的想法自动生成组件;让程序直接读取psd数据则是因为加载效率较低没有实用价值。最后折中的办法是我写了一个可视化UI编辑器。它开源、免费,界面也与Ps一样。你可以使用这个程序创建组件、配置组件与图片的映射关系、组件间的层级关系、提取psd数据生成j3o文件、生成xml格式的组件配置数据。使用简单,可以多次添加、删除、修改组件,使组件有了较高的维护性。

可视化UI编辑器


导入布局


编辑器生成的j3o文件是一个通用项目依赖库中的LayoutData类对象,你可以通过jME3的资源管理器加载它。组件配置数据由于是通用的xml格式文件,因此你可以使用dom4j解析它。请注意,到这为止我们只是把布局文件中的数据提取了出来,程序还是不知道该怎么创建组件。解放双手的关键步骤是我们可以写一个for循环,让计算机读取序列化的组件配置数据,根据配置信息创建对应的组件。

组件工厂(UIFactory)由此而生。UIFactory的实现类DefaultUIFactory会根据给定的组件类型和图层数据或子组件数据自动创建组件、移动到图层所在位置、设置相应属性、转换器和效果:

使用组件工厂创建组件

这样做的确可以做到自动创建组件。但是如果项目开发得多了你就会发现,总会有那么几个组件比较特殊、配置逻辑与众不同。“怎样设计才能既通用又可以自定义,还不破坏创建流程?”这是一个值得思考的问题。

于是,模板加载器(TemplateLoader)、布局(Layout)、布局组件创建者(LayoutHelper)接踵而至。我的思路是:把xml文件变成java文件,这样如果某个组件的配置信息比较特殊,就多加一行代码覆盖掉原来的数据。这和我们先写下String name="Alice";然后通过加一行代码name="Bob";改变name的值是一样的。Layout类就是这个java文件。TemplateLoader可以将xml文件中的信息原封不动地填写到Layout类中,并且可以更新维护Layout类:即每次往xml文件中添加修改删除数据时Layout类中的相应代码也会被添加修改删除,且不会影响用户写的代码。为了更方便的动态修改配置属性,我封装了创建组件的for循环,并起名为LayoutHelper。LayoutHelper由Layout内部创建并使用,为Layout提供创建组件的方法。

使用TemplateLoader将xml文件转变为java文件
LayoutHelper封装了创建组件的for循环


我们来总结一下生成布局组件的流程:

生成布局组件(1)
生成布局组件(2)

你可能感兴趣的:(第五章:Layout)