实战Flash游戏开发

作者简介:
  Christopher Griffith  Blockdot公司高级游戏开发师,拥有近十年的Flash应用及游戏开发经验,客户包括乐高、微软、美国航空公司、百事等知名企业。

译者简介:
  李鑫  资深CG动画讲师及插画师,深度关切游戏与拉布拉多,喜欢研究小逻辑,最近空闲时在制作原创动画《瑜的门票》。相信交互式媒体的发展如一切美好事物般会在不经意间抹上眉梢,沿路风景比站台重要。

评论:
  “这本书介绍了许多其他书都没有提到的内容,如事件传播、E4X、getter/setter方法。另外,作者还指出了如何在游戏开发中避免养成坏习惯。我推荐每一位游戏开发人员都备一本,它定会让你受益匪浅。”
“我从1998年就开始用Flash开发游戏了,看过的相关图书无数,Christopher的这本书无疑是其中的珍品。书中不但介绍了游戏开发过程中需要注意的重点事项,而且详尽阐述了游戏开发流程,探讨了当前流行的一些游戏设计元素的使用问题。”


内容简介:
  Flash因其插件文件尺寸小、性能优秀而得到全球网民的青睐,这也使得Flash成为网络休闲游戏开发的首选平台。
游 戏开发融合了很多技术与表现风格,除了要有高质量的代码、迷人的艺术设计和良好的用户界面,很重要的一点是要让玩家觉得好玩。本书就是要让读者利用 Flash设计出这样的游戏。从游戏开发基本术语和概念,到整个游戏流程的规划,再到音频和可视化资源的管理和游戏逻辑的处理,乃至一些关于代码及库的组 织方式,本书无所不包。作者以自己近10年的Flash开发经验为基础,总结了一些实用的游戏开发原则。本书最后还介绍了在大型游戏开发中如何与团队其他 成员共享资源,以及一些Flash优化方法。
本书配套网站www.flashgamebook.com上提供了书中全部的源文件,读者可以借用这些资源来开发自己的产品。

 

作者简介:
  Christopher Griffith  Blockdot公司高级游戏开发师,拥有近十年的Flash应用及游戏开发经验,客户包括乐高、微软、美国航空公司、百事等知名企业。

译者简介:
  李鑫  资深CG动画讲师及插画师,深度关切游戏与拉布拉多,喜欢研究小逻辑,最近空闲时在制作原创动画《瑜的门票》。相信交互式媒体的发展如一切美好事物般会在不经意间抹上眉梢,沿路风景比站台重要。

评论:
  “这本书介绍了许多其他书都没有提到的内容,如事件传播、E4X、getter/setter方法。另外,作者还指出了如何在游戏开发中避免养成坏习惯。我推荐每一位游戏开发人员都备一本,它定会让你受益匪浅。”
“我从1998年就开始用Flash开发游戏了,看过的相关图书无数,Christopher的这本书无疑是其中的珍品。书中不但介绍了游戏开发过程中需要注意的重点事项,而且详尽阐述了游戏开发流程,探讨了当前流行的一些游戏设计元素的使用问题。”


内容简介:
  Flash因其插件文件尺寸小、性能优秀而得到全球网民的青睐,这也使得Flash成为网络休闲游戏开发的首选平台。
游 戏开发融合了很多技术与表现风格,除了要有高质量的代码、迷人的艺术设计和良好的用户界面,很重要的一点是要让玩家觉得好玩。本书就是要让读者利用 Flash设计出这样的游戏。从游戏开发基本术语和概念,到整个游戏流程的规划,再到音频和可视化资源的管理和游戏逻辑的处理,乃至一些关于代码及库的组 织方式,本书无所不包。作者以自己近10年的Flash开发经验为基础,总结了一些实用的游戏开发原则。本书最后还介绍了在大型游戏开发中如何与团队其他 成员共享资源,以及一些Flash优化方法。
本书配套网站www.flashgamebook.com上提供了书中全部的源文件,读者可以借用这些资源来开发自己的产品。

 

第1章 计算机科学并不适合所有人


1.1 一些基础知识
  在深入介绍Flash之前,了解一点游戏开发的基础知识是很重要的,这样我们就能理解在本书其余部分中所使用的术语了。如果以后你忘了某个术语的含义或者不明白它在特定情况下的用法,那就请重新翻开本章。要是你对所有这些长单词与抽象概念有些不知所措,也请不要担心!我们得承认,游戏开发本来就是一项复杂工程(尤其对于高效且熟练的开发而言)。要知道每个编写游戏的家伙都经历过同样的焦虑和困惑。如同生活中的任何事情一样,只有不断练习并加以实战才能变得精通。因此,拿起一杯你喜爱的能提神的饮料,让我们开始游戏编程之旅吧!
1.2 常见游戏类型
  尽管有许多不同类型的游戏(有些自身无法被简单归类的游戏甚至还以此为荣),但多数游戏却可被归为下列类别之一。
1.2.1 冒险类游戏
  冒险类游戏(见图1-1)通常是由背景故事为导向而展开的,并且一般会有一个或多个主角。从玩家感觉上来说,玩这些游戏和看电影最为相像(有些游戏据说已经快要拍成电影了),它们大量依靠剧情对白、搜寻探险以及解决逻辑谜题来推动玩家的游戏进程。在20世纪80年代末与90年代初,冒险类游戏非常流行,其中LucasArts公司和Sierra(雪乐山)公司都出品过一些堪称绝佳典范的冒险类游戏。由于其开发流程非常依赖美术基本功,并且通常对系统配置的要求也较低,用Flash制作的这类游戏又开始流行起来。
1.2.2 动作类游戏
  此类游戏(见图1-2)可能会涉及许多游戏玩法以及子类别,但就一般而言,动作类游戏考验的是一个玩家的机敏程度、反应时间以及在面临压力时头脑是否灵活。第一人称射击游戏、横向与纵向滚轴游戏及格斗游戏都可归入动作类游戏。Flash平台可以很好地支持动作类游戏中的一些子类别,特别是那种年代较早的动作类游戏,比如像《太空入侵者》或《超级马里奥兄弟》那样的游戏。
 
1.2.3 益智解谜类游戏
  想想《俄罗斯方块》、《宝石迷阵》(Bejewled)还有《数独酷》(Sudoku)吧!像这样的游戏还可以列出很多。凡是涉及逻辑推理、解谜、图案匹配,或者包含以上所有这些构成元素的作品都可归入此类游戏。这类Flash游戏很多,原因主要有以下两方面。首先,创作一款简单的益智解谜类游戏所需要的美术工作一般较少,这意味着独立开发者经常靠自己就可以将其制作完成。另外,网上主要的休闲游戏玩家年龄都偏大,他们一般比较喜欢节奏慢些的益智解谜类游戏。
1.2.4 词汇类游戏
  这类游戏可被认为是益智解谜类游戏的一个子类,但是创建方法却大为不同,所以我将它们划为独立的体系。寻找单词、纵横拼字迷、拼字游戏以及回文构词 ,都属于此类游戏的范畴(见图1-3)。基于和其他益智解谜类游戏相同的原因,Flash平台是此类游戏的最常见载体。
1.2.5 策略与模拟经营类游戏
    我承认,把这两类游戏归并为一类确实有偷懒之嫌。但这两者有一些共同点。策略类游戏一般需要精心筹划、资源管理以及决策制定,比如说规划一个城市,或者组建一支庞大的军队。策略类游戏与模拟经营类游戏的区别经常可用玩家需要维持的游戏元素细节程度来界定。有些游戏会非常复杂,以至于要想进行宏观管理,玩家可能就要用到游戏提供的全部选项。而更多休闲型策略类游戏(比如像用Flash创建的多数策略类游戏)则采用一些措施来简化游戏玩法,比如通过削减可用选项以及只关注一些主要任务。塔防类游戏可算是休闲型策略类游戏的一个常见特例。在这种游戏中,玩家要策略地摆放各种不同的武器来阻止敌人通过防线。见图1-4。
1.2.6 角色扮演游戏
    角色扮演游戏(RPG)类似于冒险类游戏,但通常对主角在游戏故事进程中不断成长的历程描述得更多。传统上,RPG游戏都发生在幻想设定的故事背景中,并且它注重于玩家统计数据的进展,比如力量、智力或敏捷这样可增长的角色特性参数。近来最流行的RPG游戏是大型多人在线RPG游戏(也叫作MMORPG),玩家可以在这种游戏中通过相互间的对抗或合作来使角色成长。由于网站社会化与网页载体的需求,一些由Flash构建的MMORPG游戏也开始崭露头角。但由于这类游戏通常耗资巨大并且开发周期很长,游戏厂商在开发时尚且要冒更多的风险,对于独立开发者来说则更不可行。
1.2.7 驾驶类游戏
    顾名思义,这类游戏都会让玩家操控某种交通工具,这些交通工具可能会在陆地上行驶,可能是在水域中航行,或者也可能在天空与太空中飞行。为了获取真实效果,这些游戏通常会以第一人称或第三人称视角来进行。由于系统配置需求以及在Flash中搭建全三维(3D)环境的复杂性,多数此类游戏一般都采用二维视角。
1.2.8 桌面式和卡牌式游戏
  这种类型的游戏通常是现实世界此类游戏的数字式呈现,比如国际象棋、国际跳棋、二十一点和德州扑克(见图1-5)。 因为系统配置需求较低,所以Flash平台极为适合创建大多数桌面式和卡牌式游戏,关于这点,网上大量存在的赌场式游戏站点可为之佐证。
1.3 常用开发术语
  计算机科学这个领域很深奥,绝对不适合那些只想做游戏的人。但了解一些基本的核心概念与编程知识有助于我们以后对游戏的逐层分析。确实,它不仅枯燥,而且偶尔会显得很乏味,但我可以向你保证,理解了这些内容之后,好玩的东西多着呢!
1.3.1 伪码
  伪码只不过是用标准语言对一系列编程步骤所作的解释,有点像是一种逻辑总结。你以后就会看到,在本书的一些例子中,我会在编写实际的ActionScript程序之前先用伪码来分解游戏逻辑。因为伪码容易紧扣编程语法并忽略逻辑缺陷,所以在将问题付诸实际代码之前,我们先用英语来对它们的逻辑进行拆分,这样做几乎总能使问题的处理变得更为简单。我所用的函数和属性的名称大多来源于我写的伪码。
1.3.2 算法
  算法就是定义了问题解决方式的一系列指令与判断。它们不是代码或特定语言,因此用直白的英语来表述会较易理解。例如在一个程序里,我们要按照单词的长度来对它们进行排序,算法可能会跟程序的处理过程一样简单。下面就是用伪码写出的算法:
for all in wordlist
  sort by length
sort by length (word A, word B)
  if A.length > B.length
    return B
  else
    return A
1.3.3 过程式编程
  许多早期的编程语言如(Basic或Pascal)都被称作过程式语言。过程式编程可被抽象理解为编写一系列任务(或者叫作子程序)的过程。这些子程序的执行次序是随意的,但所有命令都是由一个主逻辑控制语句来驱动,有时我们也把它叫作主循环语句。本书的范例将会融合过程式编程技术与下面我们将介绍的面向对象编程技术。
1.3.4 面向对象编程
  过程式编程关注的是一组待解决的任务,然而面向对象编程(OOP)则专注于“对象”间的交互。OOP是一个非常复杂的课题,你可能很难全面理解它,但现在你只需知道的是:每个对象都是一个独立实体,它能够定义属性,发送与接收从其他对象传递来的消息,以及处理自身内部逻辑。例如,在OOP中,一个人可以是一个对象,而他的一个朋友则是另一个对象。他们共享一些组件,他们都是人,但也都有各自唯一的特征。而且他们彼此间会使用一种通用语言来传递消息进行交流。ActionScript的有些方面是以OOP的方式运作的,我们稍后会在书中予以详述。
1.3.5 设计模式
  目前谈论较多的是关于软件工程中的设计模式。关于这一课题有很多冗长的解释,并且还可以用一整套的理论专著来予以阐述。就本书而言,你只需把设计模式看成一种代码模板即可。它是你编写代码构建游戏时所用的蓝图,特别对于面向对象编程来说更是如此。在游戏业界内有很多公认的设计模式,有些模式对于Flash游戏开发非常有效,而有些则根本不适用。我会在第12章介绍我所发现的最有效的Flash游戏开发设计模式及其实现方法。
1.3.6 类
  在OOP中,类是充当对象基本单元的一种代码。你可以将其理解为一种模板,程序中使用的所有对象都衍生自这种模板。类定义了对象的所有属性与函数(也被称作方法)。在Flash编程中,类的使用是很重要的,主要原因如下。首先,在你定义类时,需要更多地考虑游戏的构建方式。这是件好事,没有清晰描绘的蓝图将导致日后开发中的盲目猜测与重复劳动。如果木工要盖房子,而建筑师除了一张草图外什么规划也没有给,那么这房子可能就没法盖,或许他就只能在建造过程中不断靠“拍脑门儿”来解决问题,这样盖出的房子会非常不牢靠,它没准就根本不能住人。以后我会详细介绍类结构的知识,因为大多数游戏开发都要使用类。下面列出了一个简单的类,我们用它来定义游戏角色。
package {
  import flash.display.MovieClip;
  public class Player extends MovieClip {
    public const jumpHeight:Number=10; //像素
    public const speed:Number=15; //每秒像素

    public var health:Number=100;//百分比
    public var ammo:int=20;//单元

    public function Player() {
      //初始化
    }
  }
}
  此刻你不一定能理解全部代码,但是我希望你能看出这里定义的是一个玩家角色,它带有预定义的角色跳跃高度与移动速度,并且包含了用于表示角色生命值与护甲值的变量。当然,仅靠这点代码无法实现任何功能,但这毕竟为建立更多功能与特性创建了一个基础。
1.3.7 Public、Protected、Private和Internal
  这4种前缀符(也称作类成员属性)可以放在类中的属性和方法之前,它们是用来界定一个类中何种项目可被其他类访问的。关于它们的用法,Flash的帮助文档里全都有,不过这里让我们简要总结一下。
    Public(公共)方法与变量可从任何位置访问,它们是类与类交互功能的基石;当一个类扩展(extend)自另一个类时,被扩展类的所有公共方法与变量也就一起被继承下来。
    Protected(受保护)方法与变量只能从其所属类内部访问,它们能够被继承。
    Private(私有)方法与变量只能从其所属类内部访问,它们不能被继承。
    Internal(同一包内部)方法与变量能够被其所属包内的所有类访问到。
技术随笔
  还有一种称作static(静态)的类成员属性,它能与以上列出的其余4种类成员属性中的任何一种共同使用。当一种方法或变量为静态时,它就只会有一个副本,并且可以通过类来直接访问,而无需创建类的对象。换句话说,Game类的静态属性version可以被这样访问:Game.version。如果你试图从Game类的一个实例来访问它就会出错。
1.4 游戏特有的开发术语
  现在继续介绍一些更有趣的开发术语。我们会在随后章节中直接将本节介绍的概念用于创建游戏。
1.4.1 人工智能
  人工智能(AI)一般指的是程序制定的一套用来模拟人类决策方式的逻辑决策。AI可能会很简单(就像在接球游戏中让计算机一方朝球移动球拍那样),但也许会非常复杂(像《光晕2》中那样,使敌方在感知危险时能够闪避寻找掩护并作出相应的反应)。对于本书而言,由于Flash无法用别的方式来处理,相对来说我们开发的多数AI都不是很复杂。
1.4.2 游戏循环(或者说“主循环”)
  该术语通常指的是根据输入、AI或其他一些主观逻辑来确定游戏下一阶段行为的主要代码段。它的任务只是调用其他一些逻辑函数,并核查某种条件是否已满足(比如说玩家是否已经胜利)。
  下面的范例是某个游戏中的一个简单主循环的伪码:
on enter frame
  move player
  move enemies
  check for collisions
  check for win or lose
  在像C这样的编程语言中,主循环确实是一种代码循环(如while循环或for循环),只有当满足某种条件时它才运行。主循环有时也被称作状态机(state machine),因为这种逻辑能确定游戏所处的“状态”(游戏开始前、游戏进行中以及游戏结束后等状态),并且会执行相应的函数。而在ActionScript中,你却必须要以不同方式来创建主循环,因为周期性的代码循环会将Flash Player一直锁死到游戏结束。由于Flash原本是一款动画制作软件,它的工作方式离不开帧,这点和电影很相像。Flash可以定义帧速率或者说每秒帧数。每经过一帧,Flash都会更新屏幕,此时非常适宜执行游戏逻辑。这对于惯用其他编程语言的开发者来说似乎有点别扭,但人们很快就能习惯它。我以后再讨论游戏循环,因为它们是游戏代码的驱动力。
1.4.3 游戏视角
  我们能用多种视角来表现游戏,游戏类型一般就决定了它所采用的视角,但也未必。很多现代动作游戏都采用第一人称或第三人称视角,这使你能以角色本人的视角或者以角色身后的视角来观察游戏世界。而休闲型动作与冒险类游戏更多会采用侧视角。其他类型游戏(如策略类或竞速类游戏)可能会采用从上方来查看游戏动作的视角。游戏是否引人入胜并好玩跟你所选用的视角有部分关系。动作类游戏往往需要角色快速运动,并且有大量的障碍,如果采用鸟瞰视图,游戏就会变得既困难又乏味;但假使采用第一人称视角,那么随之而来的实时且强烈的视觉感受就将打消玩家的不信服感。有些游戏视角要比其他游戏视角更适合在Flash游戏中使用。由于受到Flash技术性能所限,多数包含3D环境的视角都不适用于Flash游戏,但以后我会向你介绍一些令人信服的模拟3D效果的窍门与技术。
1.4.4 卷动背景
  通常游戏的背景都会超出游戏的可视范围。比如在《超级马里奥兄弟》这款游戏中,背景延伸了一定距离,但你每次只能看到一小部分的背景。因此,游戏会水平地前后卷动背景图像,这使得玩家角色保持在主要的可视区域内。这种效果既可水平使用也可垂直使用,比如说可以用在驾驶类游戏或策略类游戏中。
  有一种技术可以使卷轴游戏环境更具有深度感和3D观感,那就是让不同的环境层以不同的速度卷动。这种技术被称作视差卷轴法。它与真实世界很类似,出现在远处的物体(比如像山脉或建筑)的移动速度要比在前景中的物体慢。我们在第6章会详细介绍一个侧卷轴动画的范例。
1.4.5 区块式游戏
  一些游戏环境可以被分解为一个个网格,比如像迷宫类游戏或策略类游戏。那么就可用一些尺寸预定的区块来创建游戏的艺术形象。尽管在编程最后阶段需要做更多的工作来开发一种有效的区块映射系统,但游戏却能创建关卡编辑器,最终用户可以用它来建立自定义地图。《星际争霸》与《魔兽争霸》这两款游戏中的地图编辑器的区块系统就做得非常出色。我们将在第10章介绍一个区块式游戏引擎。
1.5 Flash程序开发术语
  在结束本章内容之前,我再介绍几个本书会不断提到的术语。要想以后创建出良好的游戏程序代码,关键就是要理解每个术语的内涵。在第4章中我们会更加深入地研究这些概念,目前先简要概述一下。
1.5.1 舞台
  在Flash中,舞台就是主要的创作内容区,所有的东西都建于其上。所有其他的可视化对象一旦被添加进舞台就会位于舞台的顶层。你可把舞台看成游戏的画布。
1.5.2 显示对象
  显示对象就是对象的可视化表现形式,它们可以被放置到舞台中。在Flash中有很多不同类型的显示对象;对有经验的开发者来说最熟悉的就是按钮、Sprite对象及影片剪辑了。甚至舞台本身就是一种特殊的显示对象。显示对象有很多共同点;它们都有一个在屏幕上的x、y和z坐标位置,同时也有缩放与旋转属性。在任何一个特定时间,Flash都维持着屏幕上所有显示对象的列表,这使得人们可以很方便地去访问与操控这些显示对象。
1.5.3 事件和侦听器
  事件是在ActionScript 3中对象间通信的主要方式。它们就是Flash中的对象广播或者分发的消息。任何设置好侦听这些消息的对象都会接收到事件。这些事件可能是关于用户输入的通知,也可能是关于所加载的外部数据的信息等。Flash有很多处理常见任务的内建事件,并且也完全有可能(也鼓励这样做)为自定义对象(比如像游戏)创建新的事件。事件可以包含任何与事件类型相符的数据,所有事件都含有以下一些基本属性:
    名称或类型
    目标——分发事件的对象
    当前目标——当前侦听或处理事件的对象
  事件是一种非常强大的工具,后续章节中将会大量地用到。
1.5.4 包
包就是一种类与函数的集合,用于管理类与函数。因为Flash中内建有很多不同的类(更不要说所有那些我们将要创建的类了),所以最好将它们归入一个逻辑集合中。例如,在Flash中直接处理显示对象的所有类都在一个叫作flash.display的包中。所有的事件都存在于flash.events包中。包的标准命名规范是全部字母为小写。如果要在一个特定的包中使用类,我们要使用import命令来访问它们。
package mypackage { 
  import flash.display.MovieClip;
  public class MyClass() extends MovieClip {
  }
}
1.5.5 创作时事件、编译时事件及运行时事件
  这些术语指的就是改变或检查Flash数据的不同阶段。本书中将介绍一些发生在Flash创作环境内的事情,这指的就是创作时事件。在Flash创建SWF文件的过程中发生的事件或错误被称为编译时事件。最后,一旦SWF开始运行,运行时事件就会发生。
1.6 醒一醒
  喔,本章到此为止!虽然你可能不会完全理解这里所讲的概念,但你会在后面章节中逐渐接触到它们,随后就能慢慢地明白了。想想看,你很快就能在闲聊中蹦出一两个像“多态”这样的词儿,听起来你就像是一位成熟老到的……呃……软件工程师了。

第5章 管理资源与使用图像

  尽管代码是多数游戏中的重点部分,但一般来说代码所操控的资源(绘制的图像、声音以及文本)同样也很重要。大多数编程语言都将资源放入单独的文件与代码分开,而每个Flash文件都连接着一个库,库中包含了在编译时要归并入SWF文件的所有资源。一旦将资源导入库中,除非要对它进行更新,否则就不再需要外部的资源文件了。由于大多数情况下Flash只需使用FLA文件即可,所以开发者们能更容易地访问资源。你当然可以创建一个全部由代码组成的SWF文件,并且在运行时加载进它所需的全部资源,但这却有悖于Flash的自身特点,并且这样做几乎在任何情况下都会得不偿失。另外,Flash能为资源添加额外的压缩层,而由外部访问资源文件却达不到这一点,这就意味着包含全部所需资源的单个SWF文件要比所有单独的资源文件合起来的尺寸小。在本章余下部分中,我将为你介绍各式各样的资源,在开发Flash游戏时需要知道如何利用这些资源。
  在本章中,我将持续关注资源文件的尺寸。在一些Flash开发者圈子中,人们一般认为最关键的是最终产品,也即最终SWF文件的尺寸。我看到过很多FLA源文件大约有30 MB到50 MB那么大,那还是相对比较简单的游戏。这就有问题了,原因有以下几点。其一,如果你每次都使用一定类型的备份或版本控制系统,那么新版本就会占据相当多的空间。更重要的是,Flash乐于接受稍小的、内存占用较少的FLA文件,这样就远不会造成死机或崩溃,你只需在开发过程中定期地执行“保存并压缩”操作即可(见图5-1)。如果在Flash中改动了资源(添加、更新以及删除),Flash就会存储一个历史记录,以便你能尽可能地取消这些行为。久而久之,这些“供取消的备份”就会使文件体积增大,因为它们储存了在几次重复操作之前业已从库中删除的资源。“保存并压缩”操作会检查FLA文件,然后清除所有的取消行为数据。我曾见过有的库文件在执行完该操作之后,其尺寸立刻下降了75%,原因仅仅在于原先的库文件保存了太多版本所遗留下来的历史记录。注意,假如你用的版本控制系统在每次保存时都保存为一个新文件并且递增文件名(而不是我推荐的文件名),那么当选择“另存为”操作时,Flash就会自动压缩文件。
5.1 小议组织库元件
  如果久做Flash开发,你可能时常会需要打开别人的FLA文件。我发现不同开发者库的组织方式很少能够保持一致。有那么一段时间,大家流行按照类型来排列库中的资源,所以会出现标明为MovieClip、Buttons以及Bitmaps等的文件夹。有些人则喜欢按照用途来排序,图5-2就展现出这种文件夹结构。
  你一定要记住这一点:有组织性就总比没有强,你所使用的最佳结构总是要由项目的复杂性来决定。我通常将前述两种方法混合起来使用。我会将可视化资源(影片剪辑、图像、视频)按照用途来分类,然后在其相应的文件夹下又按照类型来排序。另外对于像声音或字体元件这样的资源,我完全按照类型来排序。这样做的理由在于,你终于能在Flash CS4中编辑多个同类型元件的属性了,而将这些库元件彼此相邻地放置就会更易选取它们。
5.2 使用图像
  现在已远非《乓》游戏时代,游戏质量的门槛已经提高了。游戏都要具有漂亮美观的图像以及自然流畅的动画才行,Flash游戏也不例外。我将在本节中简要地介绍一下最佳游戏图像格式以及动画时间轴的用法。我不会谈论有关图像绘制方面的内容,原因如下。首先,我不是艺术家。其次,因为Flash游戏已经变得越来越精良了,单凭一个人很难在游戏开发中包揽编程与美工这两个角色。不过,如果你是独立开发者,或者你对Flash游戏的图像设计感兴趣,我建议你去读读Robert Firebaugh编写的Flash Professional 8 Game Graphics一书。虽然它所讲解的内容已经滞后了几个Flash版本,但对于学习如何绘制Flash所用的高效能图像来说,该书依然很有价值。
  Flash CS4既支持矢量图又支持光栅图像(位图)。在游戏开发中这两种格式各有其优缺点。矢量图像能够调整大小,不会造成任何质量损失,文件尺寸也比光栅图像要小得多,而且你能在时间轴上利用它们创建出非常流畅的专业级卡通动画(前提是不在乎所耗费的时间)。然而,大量的矢量图像或由矢量图像构建的大型对象会对CPU造成沉重的负担。虽然可以通过Adobe Illustrator这样的创作工具来完成,但我们一般最好直接在Flash中创建矢量图像,因为Flash会自动在绘制矢量图中使用尽量少的点来对其进行优化。而对于Illustrator这样的设计软件来说,它看重的是准确性以及完美的像素质量,而非矢量优化,这就将导致最终绘制的矢量图异常复杂,以至于将其导入到Flash后我们还需要做很多的清理工作。如果你正在开发的项目使用的全都是矢量图像,那么构成矢量图像的点越少,渲染速度就会越快,文件尺寸也会越小。
  几乎人人都熟悉并使用过光栅图像,至少也用它们设置过电脑桌面。光栅图像有矢量图像所不具备的一些优点。首先,它们能提供照片级真实感,而这得需要非常复杂的矢量图形才能办到。许多不同的图像设计软件(包括多数3D软件)都能够渲染出图像,然而只有几个软件能够生成为Flash所兼容的矢量图像。另外,将光栅图像渲染到屏幕上所需的运算量也要少得多,因为Flash会将其与一个矢量长方形以同等复杂度对待。但光栅图像也并非完美无缺。当像素增加时,光栅图像的文件大小会急剧呈指数级增加,并且在Flash中不可能做到质量无损地调整光栅图像的大小。另外,在Flash中渲染透明图像要比渲染不透明图像更耗费运算资源。
  这时,你可能会说:“既然这两种方案都不完美,那我该用哪一种呢?”就跟选择如何组织库元件的方法一样,它一般要由具体项目来决定。能够用于所有情况的唯一正确选择是不存在的,我在工作中很少只用到其中一种方案。即便如此,在游戏开发中,我还是更偏重于使用光栅图像而非矢量图像。很多游戏都需要在屏幕上快速地渲染出游戏对象,这才能让玩家有一种淋漓酣畅的游戏体验,而如果使用带有大量细节的矢量图像,则会因为渲染太慢而无法达到这一点。通常在我参与开发的游戏中,美术设计部分的80%是由光栅图像来实现的,而矢量图像则会占到20%。游戏角色、背景、粒子效果等全都是由光栅图像来完成的,而菜单、游戏内的各种显示界面与文本则都是由矢量图像来完成的。
5.3 常用的光栅图像格式
  Flash常用的两种最佳的光栅图像格式是JPEG与PNG。当图像不需要有任何透明部分时,用JPEG就很不错,因为你可通过外部程序如Photoshop来处理图像,而这要比在Flash内部处理具有更低的压缩率及更好的图像质量。由于它们缺少透明通道,所以也会降低Flash渲染器的开销。而当你需要图像的透明通道时,PNG格式则是不二之选,但其文件尺寸及所占用的运算能力也会变大。
  多数项目会混合使用这两种格式。任何资源,只要其可以作为一个矩形形状来使用,并且不包含任何透明通道,那么就对其使用JPEG格式吧(见图5-3和图5-5)。这样的资源包括以下几种。
    游戏与菜单界面的背景。
    在位图填充中被用作材质的图像。
    遮罩形状所覆盖的图像。
    在游戏中用作某种图像特效的覆盖层,比如静电干扰或无线电干扰效果。
  便携式网络图像(PNG)(见图5-4和图5-6)是表现空白透明效果的不二之选,且更适用于表现较小的游戏元素,这些元素包括以下几种。
    游戏角色,特别是那些运动角色。
    需要与背景分离的游戏内元素。
    用户界面元素,比如按钮及其他不规则形状。
    有着细致边线的图像,这种图像需要达到像素完美(pixel-perfect)的精确性(JPEG有变模糊的倾向,或者说图像的像素细节很模糊)。

  技术随笔:带有透明通道的8位PNG
  PNG图像分为两种——32位(包含1600万色并带有一个完整的8位透明通道)与8位(256色)。有一点似乎不为人所知,那就是Adobe Fireworks能够生成一种特殊的PNG图像,它带有一个8位颜色通道与一个8位透明通道(有时也被称为PNG8+8)。如果你想使用一种颜色相当少的图像,或者说是一种减少颜色数目也不会降低太多品质的图像,那么选用这种格式就很不错。尽管这会使文件尺寸减少一多半,但它却能使图像保持细致清晰的边界与透明效果,而这就多亏了其准确的透明通道。事实上,这种格式的图像尺寸往往会比Flash内部生成的经压缩的32位PNG图像尺寸还要小,其最终图像也更为美观。这种格式可望最终会出现在Photoshop的“储存为Web格式”功能中。不过在此之前,可以一直用Fireworks将32位PNG图像批处理为8位PNG图像(见图5-7)。
    当然这些仅是参考,并非硬性规定,但如果组合使用预先考虑好文件尺寸的格式,则会在优化阶段节省大量的时间。有关光栅图像的另一方面问题是Flash在编译游戏时会如何处理它们。Flash有几个不同的图像导出选项,游戏的观感取决于此。在库中只需双击一幅图像即可查看它的属性。你也可以同时选择多个图像(CS4中的新功能)并同时调整所有图像的属性(图5-8)。
  图5-8 你可通过“位图属性”面板来调整一幅特定图像或多个图像的属性
5.3.1 压缩
  当你导入一个已经用另一程序优化过的JPEG文件时,Flash默认情况下会照其原样来使用它。PNG图像却不一样。如果图像是256色或更少的颜色,Flash会自动将其降低为8位的PNG文件,文件尺寸立刻降低,然而其品质无损(也称为无损压缩)。如果图像包含的颜色超出了256色,Flash就会在编译该文件时将其转为Flash所自有的JPEG压缩格式。压缩率可以在文档中通过“发布设置”来进行控制(默认为80%)(见图5-9),并且这是针对每个图像进行压缩的。对于一段时间内在屏幕上保持静止的一些图像来说,我建议将压缩率设置为70%~80%,这样可保证其品质不会降低太多。而对于用在快速运动的动画序列中的图像,比如角色动画,我建议将其压缩率降低为50%,因为你根本注意不到由此产生的品质下降。事实上,当每秒30帧时,人眼是察觉不到足够多细节的,JPEG经压缩后形成的自然模糊效果就会带来良好的运动模糊感觉。永远不要使图像压缩率超过90%,除非要将游戏显示到一个分辨率极高的显示器上,而且你可能判断不出由此造成的品质差异,但文件尺寸却会飙升。
5.3.2 平滑
  默认情况下,当你在舞台上对图像施加任何方式的形变时(包括倾斜、缩放甚至旋转——以任何不能被90整除的角度进行旋转),Flash都不会重新渲染它们。由此导致在运动较慢的图像上产生很明显的锯齿块状效果。如果游戏需要时不时地旋转一些图像或调整其尺寸,那么你可以考虑在它们的“位图属性”(Bitmap Properties)面板中选中“允许平滑”(Allow Smoothing)选项(见图5-10)。尽管这样做后图像看上去边缘更为平滑,但确实会更耗费计算资源,所以要少用这个选项。如果游戏在以后测试时开始变得迟滞,就要考虑在一些图像中禁止使用这个选项。
5.3.3 解块
  这是CS4中的新功能。当你启用了解块功能后,它能对那些JPEG品质被设得极低(如被设为30或更低)的图像使用一些额外的平滑操作以改善图像品质。除非所用图像被极度压缩,否则你可能根本不会用到这个功能。
5.3.4 外部的图像编辑工具
  与我共事的美工通常会使用Adobe Photoshop与Adobe Fireworks来创建游戏的光栅图像。这两种软件能将JPEG压缩得极好,并且能使生成的PNG文件十分整洁。如果因预算有限而买不起Photoshop(或不需要其所有高端功能),那么你可选用Fireworks,它会让你十分满意的。截至本书写作时,它的价格是300美元。
  关于矢量图像,我曾认识几个美工,他们能用Flash中的工具做出非常好的矢量效果。在Flash中创建矢量图像不需要额外任何工具,矢量图像在创建时就能被自动优化。另外,Fireworks有一套非常好的矢量工具,它能将做好的矢量图像轻松地导入到Flash中。多年来,我也曾跟一些喜欢用Adobe Illustrator的美工一起工作过,但我发现对于大多数游戏所需的图像细节程度而言,Illustrator确实有点大材小用。另外,用其做出的效果(如复杂的混合与渐变效果)并不都能很好地转化到Flash中。
5.4 要点
  在编辑大量游戏图像时,它们很容易就会乱套,不仅混乱无序,而且文件大小也不理想。所以你要记住以下几点。
    要在整个开发过程中密切关注图像。
    在库中用文件夹来组织图像。
    文件系统中的图像要有条理,以便能在Flash中“更新”图像,这样你就不会在图像发生了任何改变时不得不再将其全部重新导入。
    宁可让图像的尺寸与文件尺寸更小一些,特别是对于制作全帧速率(full-frame-rate)动画来说。
  想想吧,若是直到最后时刻你才急忙降低所有图像的JPEG压缩率,将文件尺寸缩减,游戏往往会变成一团糟。相比之下,一丝不苟地预先对图像进行优化就要好得多。最终,你不懈的努力也会带来圆满的回报。


posted @ 2011-05-23 15:04  我的IT技术  阅读(440)  评论(0编辑  收藏  举报