2010年4月 的存档

RPG风格的文本系统——Make an RPG-Style Text System for Your Next Game

在这个教程里面我们将要创建一个文本系统,它跟你见过的大多数角色扮演游戏的文本系统是一样的。我们的类要动态显示说话角
色的图标。并逐个字母的显示每块对话的内容。

最终结果的展示

下面这个例子就是我们将要制作的文本系统
RPG Style Text System (46)

第一步:建立你的flash文件
创建一个新的flash文件(actionscript 3).根据你的游戏具体情况设置影片参数,在这个演示中我设置影片大小为500*300,黑色

的背景,30帧/秒

第二步:添加背景图片
你通常会把游戏中的文本模块放到图像或动画的上面,在这个演示里我只用了一张图片把站在雪景里的所有需要的角色放到了一起。把背景图片放到单独的一层里面起名叫做“background”

第三步:创建RPGText影片剪辑
在舞台上创建一个新的影片剪辑(插入〉影片剪辑)命名为“RPGText”.在这个元件属性里面购选“Export for Actionscript”设

置类的名字为“RPGText”. 我们将使用这个类名链接代码和影片剪辑。设置完成单击ok。如果你看到这样的警告“定义的类可能没

有找到”。那是正确的,它的意思是还没有任何代码链接到这个元件上。
给你的影片剪辑实例命名为“rpgText”记住,当我们谈到大写的RPGText时,它表示的就是类或者是影片剪辑,如果是小写的

rpgText,那么它就是类的一个实例。

第四步:添加文字面板背景
在新建的RPGText影片剪辑里面画一个矩形。用它作为人物图标和说话框的背景。你也可以根据自己的嗜好来设计它,但必须保证它

的宽度能横跨整个影片并且高度大小不能覆盖太多的游戏空间。
我设置的大小是500像素宽(匹配我的影片)100像素高。我用从#666666到#999999(从暗灰到亮灰)的过渡色填充

快速提示:画一个特殊尺寸的矩形,选择矩形工具按住Alt键单击舞台你会得到一个对话框,可以输入矩形的尺寸。

第五步:角色图标的影片剪辑
在RPGText影片剪辑新添加一个层,命名为“icon”。创建一个新的影片剪辑命名为“characterIcon”并在icon层添加这个影片实例“characterIcon”。

并在新建的characterIcon影片剪辑里面创建两个新层“icons”和“labels” 。icon层包含所有的角色图标(一个图标对应一个关键桢)而labes层设置帧标签,设置帧标签的目的是为了准确定位角色。

导入(或者是在flash里面绘制)每个将要说话角色的图标,在这个演示里我做了75*75像素的jpg图片,把它们添加到图标层。为每一个新的角色做一个关键桢。他们的显示顺序并不重要。但必须保证每个图标的位置在x:0,y:0。因为只有这样做,当角色切换的时候才不会有跳动的感觉。

第六步:添加帧标签
现在为labels层创建关键帧。快速的方法是选择这些帧按F6键。
为每个关键帧添加显示在该帧上对应角色的名字。如果你添加一个空桢(F5),它可以很容易让你读取你的关键帧的内容,但是必

须保证你的标签在对应图标关键帧的上方。

而且必须保证每个标签的命名不一样。如果你有两个角色的名字是一样的你需要区别它们(例如:(‘John_L’ 和 ‘John_K’ )

第七步:画一个说话框
回到RPGText影片剪辑,创建一个新的层叫做“textBackground”。
画一个说话框。我用一个圆角矩形简单画了一个,你可以根据自己的需要做。让它充满大部分的背景。在角色图标的旁边。
选中你的说话框转换成为影片剪辑(修改->转换元件),现在他变成了影片剪辑,我们可以给它添加投影滤镜。我设置我的投影滤镜黑色,50%强度,5像素的模糊(blur),1像素的距离。

第八步添加动态文字区域
在RPGText中创建一个新的层叫做“text”,使用文本(text)工具在该层上画一个文本区域。让它的大小刚刚符合说话框的大小。
设置这个文本区域为多行,定义实例名为“txt”。记得嵌入字体。我使用的是13pt courier

第九步添加“下一个”按钮
我们需要一种方式让玩家在阅读完当前文字后能看到下一段文字,让我们在拐角处添加一个“下一个”按钮。
在RPGText上创建一个新的层叫做“button”添加一个新的按钮元件叫做“b_next”.给你的按钮设计四种状态。我使用的是一个下标的小箭头,因为我在很多的游戏中看到它,把它放在对话框右侧的角落里。不要担心给它一个实例名。我一会在解释

第十步创建一个文档类
创建一个新的actionscript文件叫做“Main.as”添加代码
package {
import flash.display.MovieClip;
public class Main extends MovieClip {

// CONSTRUCTOR
public function Main() {
}
}
}
在flash里面设置Main为文档类,如果你想快速重温文档类的使用方法,我认为威廉斯迈克尔的一片快速提示的文章是最好的选择。

第十一步添加文本区
如果你在开发游戏的时候,你会把文本区的处理放到别处,但是现在我要把它放到文档类里面。在Main类的构造方法里面添加这些代码
var textBlocks:Array = new Array(
["Kid",     "Look, a robot!"],
["Abe",     "BLEEP-BLOOP. I am an Autonomous Botanical Engineer. You can call me ABE."],
["Kid",     "Hi Abe. Meet Frosty the Snowman."],
["Frosty",  "Happy Birthday!"],
["Abe",     "BEEP-BIP. Hello, Frosty."],
["Abe",     "Does this frog belong to you?"],
["Frog",    "Ribbit..."],
["Kid",     "No I've never seen him before. Aren't you cold frog?"],
["Frog",    "Ribbit..."]
);

rpgText.textBlocks = textBlocks;
这里我们创建了一个二维数组(一个数组嵌套另一个数组)保存我们场景中用到的语言脚本。在你改变任何东西的时候,注意一下

它的结构,每个数组是一个分开的文本内容
它包含两个元素。第一个是角色的名字,第二个是角色要说什么。这个文本区列出的是在场景中出现的次序。
最后一行仅仅是把textBlocks数组赋值给rpgText影片实例。(记住,rpgText是影片剪辑RPGText的实例名)。更多的稍后再说。
来吧,编辑这段代码让它符合你自己的需要。但要格外注意的是角色的命名和你characterIcon影片剪辑里面的帧标签是否对应

第十二步创建RPGText类
我们终于开始写RPGText类的代码了
创建一个新的actionscript文件命名为“RPGText.as”,添加代码如下
package {
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.media.Sound;
public class RPGText extends MovieClip {
private const SPEAKER:int = 0;
private const TEXT:int = 1;
private var _currentTextBlockIndex:int=0;
private var _currentTextBlock:String;
private var _textBlocks:Array;
// CONSTRUCTOR
public function RPGText() {
}

}
}
这仅仅是一个基本的类结构。它不能做任何事情。但是我们先来看看他都包括了什么
前几行,导入我们需要的类库
定以这个类扩展自MovieClip类。我们需要这么做的原因是这个类要链接到库里面的RPGText影片剪辑。
我定义了两个常量,SPEAKER和TEXT,用他保存textBlocks里说话者的名字和内容
_currentTextBlockIndex变量追踪当前的显示对象
_currentTextBlock获得实际的文本内容
_textBlocks持有整个文本的数组
最后是一个空的构造器

备注:我是用带下划线的变量名表示私有变量

第十三步textBlocks设置方法
由于我们的_textBlocks是私有的所以我们需要一个方法把它传递出去,好让我们在Main类里面设置这个文本区域。我们创建一个

setter方法。添加在RPGText类构造方法的下面
public function set textBlocks(txt:Array):void {
_textBlocks = txt;
}
setters最酷的是可以通过方法把一个私有属性变成一个公共属性。我们在Main类的第11行是这样做的
rpgText.textBlocks = textBlocks;

第十四步添加updataText方法
在RPGText类里面添加这个方法
private function updateText(e:Event):void {
if(txt.text.length < _currentTextBlock.length){
txt.text = _currentTextBlock.substr(0, txt.text.length+1);
} else {
removeEventListener(Event.ENTER_FRAME, updateText);
fillText();
}
}
这个方法是这个类的核心功能,让我们自己看一下这都发生了什么。
第27行这个方法接收一个事件作为参数我们通过ENTER_FRAME事件调用它
第28行我们比较txt和_currentTextBlock里面的字母的数量
第29行如果是txt里面的字母数量少,则我们用substr方法获得从0到txt字母数量这么多个,把截得的字符串添加到文本区域里面实

现字符逐个添加到文本区域里面的效果
第31行如果txt和_currentTextBlock的字符数量相同则移除ENTER_FRAME监听事件。
第32行调用fillText方法。我们下面将要实现这个方法。

第十五步添加fillText方法
在RPGText类里面添加则个方法
private function fillText(e:MouseEvent = null):void {
txt.text = _currentTextBlock;
if(_currentTextBlockIndex < _textBlocks.length-1){
addEventListener(MouseEvent.CLICK, nextTextBlock);
}
}
这个方法的主要目的是通过变量_currentTextBlock(37行)填充文本区域。我们让updateText方法来控制动画的播放,这样做可以确保不会出现问题。我们也可以把方法挂靠到“next”按钮上,让玩家掠过文本动画直接显示文本内容注意这个方法接受一个鼠标事件作为参数,我们把它默认设置为null。我们可以让这个方法作为鼠标事件监听器,因为它可以接收事件,因为我们可以给事件一个默认值,当然我们也可以不需要发送任何事件直接在updateText方法的结尾处调用当我们填充完文本区域后,我们检查是否到达文本块所在数组的末尾。(看_currentBlockIndex是否小于_textBlock数组元素的个数 )如果没有到达末尾,我们就添加一个单击事件监听器调用nextTextBlock方法继续显示文本。

第十六步关于单击监听器
还记得开始在我们创建“下一步”按钮的时候,我曾经说个不要着急给这个按钮起实例名吗?你注意到最后一步我们如何链接单击监听器给RPGText 影片剪辑代替按钮?这样做可以让游戏者单击影片的任何地方继续。我们其实根本就不需要这个按钮,但是我觉得有这样一个按钮可以给用户一些提示内容。当然这也仅是个人意见。如果你想给这个按钮一个名字并且给它关联一个单击事件也没有问题,但我觉得让它有一个大一点的单击区域使用会很方便。

第十七步添加nextTextBlock方法

返回来,在RPGText类里面添加方法
private function nextTextBlock(e:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, nextTextBlock);
txt.text = “”; // clear the text
_currentTextBlockIndex++;
_currentTextBlock = _textBlocks[_currentTextBlockIndex][TEXT]; // set the text
characterIcon.gotoAndStop(_textBlocks[_currentTextBlockIndex][SPEAKER]); // set the character icon
addEventListener(Event.ENTER_FRAME, updateText); // start updating the text
addEventListener(MouseEvent.CLICK, fillText);
}
起始的三行很简单。移除鼠标移动事件监听,清除文本区域,增加_currentTextBlockIndex变量值并指向下一个文本块
第四十七行用TEXT常数从_textBlocks数组中取出当前的文本字符串给_currentTextBlock赋值。下一步我们用SPEAKER常量获得当前角色的名字。因为在characterIcon影片剪辑里面角色的名字和帧的标签是匹配的。我们可以用gotoAndStop设置角色图标显示的位置。最后我们添加一个事件监听器开始键入新的文本字符串并且增加一个单击事件执行fillText。

第18步添加startText方法
我们已经做完所有的一切,那么剩下要做的事情是添加一个方法让所有的一切开始。我们定义一个公共方法“startText”,因为他是一个公共方法,让我们把它放到RPGText头部,仅在的textBlocks设置器的下方
public function startText():void {
_currentTextBlock = _textBlocks[_currentTextBlockIndex][TEXT];
characterIcon.gotoAndStop(_textBlocks[_currentTextBlockIndex][SPEAKER]);
addEventListener(Event.ENTER_FRAME, updateText);
addEventListener(MouseEvent.CLICK, fillText);
}
是不是似曾相识?这个代码和nextTextBlock方法做的事情几乎相同。它设置当前文本和角色图标,为updateText和fillText添加监听事件。因为这个方法仅仅在文本第一次显示的时候使用,跟nextTextBlock方法不同的是我们不用清除这个文本区域或者是增加_currentTextBlockIndex。

第十九步调用startText方法
现在我们有一个公共方法可以让对话开始了。那么接下来我们把它放到程序里面。
在Main类构造方法的最底一行添加rpgText.startText();
这里仅仅是调用RPGText类的startText方法。这样所有的一切就开始了。

第二十步添加声音
你可能要测试一下你们的影片,看看它们是不是都已经正常工作了。那么现在就差一件事情了没有做了那就是声音。为文本显示的时候配一个声音,我们可以找一个或者是单独做一个。我们必须保证选择的声音比较短小,因为这个声音随着文本显示循环播放。一个小的“boop”或者是按钮单击的声音是最好的。
导入声音文件到flash文件,勾选 “Export for Actionscript” 给它一个类名字叫做“TypingSound”

让声音播放我们只需要在RPGText类里面添加两行代码。首先我们需要声音的实例。在类的开始其它三个私有变量的下面添加
private var _typingSound:Sound = new TypingSound();
现在我们向下找updateText方法添加一行让每次文本更新的时候都播放声音。
private function updateText(e:Event):void {
if(txt.text.length < _currentTextBlock.length){
txt.text = _currentTextBlock.substr(0, txt.text.length+1);
_typingSound.play();
} else {
removeEventListener(Event.ENTER_FRAME, updateText);
fillText();
}
}

第二十一步谈一下它的未来
上面做的所有工作,的仅仅是为这个例子服务的。如果你想把它整合到游戏里面,那么你好有好多工作要做。
首先,依据你自己游戏建立对话方式,你肯定会把文本块脱离文档类单独拿出来。你可能有一个场景类,用它来管理人物语言或者是一个字符串类保存所有对话。
其次,你可能会思考,文本模块在什么时候,怎么样出现在你的游戏中。你可能会添加一个过渡动画来实现如在对话开始和结束的时候让它在底部滑入滑出。你也可能想监听当对话结束后隐藏文本模块或者开始下一段对话。
因为我们已经校验最后的文本块是否进入fillText方法。所以你可以很容易添加对话结束时的处理方式。在这个教程里面并没有包含这些话题,因为你要根据自己的游戏去做这些事情。这些已经足够帮你开始做了。
我希望你能喜欢这篇教程!留下你的评语让我知道你们的想法。

网游审批流程图

繁杂的网游审批流程图:

Windows下安装配置SVN的正确方法

在windows下配置svn服务器

1.下载文件
下载最新版本subversion,我这里选择svn-1.6.4
到官方网站的下载二进制安装文件,来到二进制包下载部分,找到 Windows NT, 2000, XP and 2003部分,然后选择” this directory “,这样我们可以看到许多下载的内容,目前可以下载 Setup-Subversion-1.6.4.msi

下载 TortoiseSVN shell integration utility
TortoiseSVN是扩展Windows Shell的一套工具,可以看作Windows资源管理器的插件,安装之后Windows就可以识别Subversion的工作目录。
官方网站是TortoiseSVN ,下载方式和前面的svn服务器类似,在Download页面的我们可以选择下载的版本,目前的最高稳定版本的安装文件为TortoiseSVN-1.4.0.7501-win32-svn-1.4.0.msi

2.安装Subversion 服务器
由于我下载的是setup.exe版本,安装程序安装后会自动设置系统变量.如果你下载的是zip版就需要手动设置系统变量.
setup.exe版直接安装就可以了.安装到D:\Program Files\Subversion

首先创建SVN储存库(repository)

svnadmin create F:\svn\
repository创建完毕后会在目录下生成若干个文件和文件夹,dav目录是提供给 Apache与mod_dav_svn使用的目录,让它们存储内部数据;db目录就是所有版本控制的数据文件;hooks目录放置hook脚本文件的目录;locks用来放置Subversion文件库锁定数据的目录,用来追踪存取文件库的客户端;format文件是一个文本文件,里面只放了一个整数,表示当前文件库配置的版本号;

3.建立版本库(Repository)
运行Subversion服务器需要首先要建立一个版本库(Repository),可以看作服务器上存放数据的数据库,在安装了Subversion服务器之后,可以直接运行,如:

svnadmin create F:\svn\repository
就会在目录E:\svndemo\repository下创建一个版本库。

我们也可以使用TortoiseSVN图形化的完成这一步:
在目录E:\svndemo\repository下”右键->TortoiseSVN->Create Repository here…“, 然后可以选择版本库模式, 这里使用默认即可, 然后就创建了一系列目录和文件。

4.配置SVN服务器

这个位置就是在你建储存库的地方F:\svn
打开/conf/目录,打开svnserve.conf找到一下两句:

# [general]
# password-db = passwd
# anon-access = none
# auth-access = write

去之每行开头的#,其中第二行是指定身份验证的文件名,即passwd文件.anon-access = none 是匿名用户不能访问,必须要有用户名和密码。(注意:问题就出在这,一定要注意格式去掉注释后要顶格不能有空)

同样打开passwd文件,将

# [users]
# harry = harryssecret
# sally = sallyssecret

格式为“用户名 = 密码”,如可插入一行:admin = admin888,即为系统添加一个用户名为admin,密码为admin888的用户

5.运行SVN服务器
运行SVN服务
在命令行执行

svnserve --daemon --root F:\svn
服务启动,–daemon可简写为-d,–root可简写为-r,可以建立一个批处理文件并放在windows启动组中便于开机就运行SVN服务(注意:这是临时打开的服务,命令执行后不能关闭窗口)
用后台服务的方式可以设置开机自动执行。
D:\Program Files\Subversion\bin>sc create svnservice binpath= "d:\Program Files\
Subversion\bin\svnserve.exe --service -r F:\svn"

就可以用net svnservice stop 或者start来启动服务了 也可以在Sevices.msc来启动了。

6.初始化导入
来到我们想要导入的项目根目录,在这个例子里是f:\svn\目录下有一个readme.txt文件:

右键->TortoiseSVN->Import…
URL of repository输入“svn://localhost/”
ok
完成之后目录没有任何变化,如果没有报错,数据就已经全部导入到了我们刚才定义的版本库中。

需要注意的是,这一步操作可以完全在另一台安装了TortoiseSVN的主机上进行。例如运行svnserve的主机的IP是133.96.121.22,则URL部分输入的内容就是“svn://133.96.121.22

7.基本客户端操作
取出版本库到一个工作拷贝:
来到任意空目录下,在本例中是E:\svndemo\wc1,运行右键->Checkout,在URL of repository中输入svn://localhost/,这样我们就得到了一份工作拷贝。
在工作拷贝中作出修改并提交:
打开readme.txt,作出修改,然后右键->Commit…,这样我们就把修改提交到了版本库,我们可以运行。

察看所作的修改:
readme.txt上右键->TortoiseSVN->Show Log,这样我们就可以看到我们对这个文件所有的提交。在版本1上右键->Compare with working copy,我们可以比较工作拷贝的文件和版本1的区别。

8.用客户端访问
格式:svn:\\服务器IP
因为SVN有三种方式实现也就有三种不同的访问格式。

附上安装SVN Plugin到Flex Builder的方法:

选择 Help -> Soft Updates -> Find and Install,在弹出的窗口中选择“Search for new features to install”,然后创建新的”New Romote Site”,Name为“Subclipse”,URL是”http://subclipse.tigris.org/update_1.4.x/”,接下来就是一路next之类的了。

安装结束后,在Window->Perspective->Customize Perspetive中激活svn,就可以在File->New 中看到SVN的选项了。

敏捷开发应用于游戏原型创作

本文是于 2005 年时发表的文章,虽然距今已有三年以上的歷史,但绝对无损这篇文章的价值。同时,本文也与极具创意的优秀独立游戏作品《World of Goo》,有非常深的渊源以及关连性存在。
Kyle Gabler、Kyle Gray、Matt Kucic 与 Shalin Shodhan 是四位就读于卡内基美隆大学 (Carnegie Mellon University) 研究所的学生。在 1 个学期的时间内,他们仅仅凭藉着 4 个人的力量,完成了超过 50 个游戏的原型 (Prototype)!同时他们也设置了一个名为 Experimental Gameplay Project 的网站发表他们所制作的各款游戏原型;其中最受欢迎的游戏之一,就是由 Kyle Gabler 所制作的《Tower of Goo》,而这个游戏原型也正是《World of Goo》的前身作品! Gamelook|www.gamelook.com
为了达到 1 个学期之内完成 50 款游戏原型作品这项近似于不可理喻且不可思议的目标,他们将自己锁在房间内,遵循着以下三项规则进行开发工作:

  1. 每个游戏必须在 7 天以内完成。
  2. 每个游戏必须从头到尾以 1 人之力完成。
  3. 每个游戏必须立基于一般常见的主题,例如「重力」、「植物」或「群聚生物」等等。

7 天,1 人,以及 1 个主题,制作成为一个游戏原型作品。许多人好奇他们是如何在这么短的时间内完成一款游戏原型作品?又是如何能够维持上述规则与纪律,长达一整个学期之久?在此,四位作者共同将这段过程中所学习到的各种宝贵知识,包括正确以及不可行的尝试经验沈淀整理之后,分为准备、设计、开发以及游戏性四个项目,一一阐述如下:

准备:敏捷,是一种意向的状态
敏捷式原型开发 (Rapid Prototyping),不只是前置开发时期的有用工具,同时也可以是一种生活方式。从思维层面出发,首先要使自己的心理状态合乎「敏捷」的原则,才能够真正成为一位敏捷式的原型开发者。首先,第一步就是要乐于拥抱失败的可能性。
优秀的原型开发者能够瞭解,失败是一件可以接受的事情!而那也正是建立原型的目标,所以请大胆地放手去做吧!万一最终真的失败了,也能够从其中的过程学习到某些具有价值的经验,并且唯有藉由拥抱失败的可能性,才有可能得到有所回报的实验结果。在 Gray 所制作的《Mime After Mime》与《A Mime to Kill》中,很大胆地只使用位置性音源 (Positional Audio) 做为游戏性 (Gameplay) 的来源;虽然这两个游戏是全然失败的作品,但也充分证明了仅有音源游戏性的游戏设计概念,是一项不可行的作法。
坚持实行极短的开发週期,是另外一项快速开发的诀窍。开发者们似乎会很自然地说:「嘿,既然我们在 1 週内完成了一个很棒的游戏,那么如果我们花费 2 週的时间进行开发,我们将会得到一个 2 倍优秀的游戏作品!」事实上,他们发现一般来说,任何游戏性都能够有效地在一週内完成原型建置;额外的投入时间,总是会倾向于产生功效递减的结果。举例来说,有些原型仅仅花费一个晚上的时间组装完成,另外有些原型则使用了额外的一两週时间,而令人意外的是,每个原型所花费的时间,与其最终获得的成功程度,并没有相互关连性存在。
在他们所制作出的成功游戏原型中,多数都是出自于特定的主题,他们曾经探索过的主题包括了「重力」、「弹簧」、「演化」、「声音」、「植物」与「平衡」等等。不知为何,当有限制存在的时候,反而会更易于产生创意。另外,与团队成员同时进行某个特定主题的原型开发,某种程度上也能够避免着力于太过显而易见的游戏性,迫使所有人都必须接受挑战,探索在这个主题下的所有游戏性的可能性。如果缺少了稳固明确的主题限制,游戏将会花费更多的时间创造,同时也会减损团队的方向目标,以及那种使他们能够挤压出最后一滴创造能力的友善竞争感。
每一位团队成员都必须能够独立面对并且负责游戏开发的所有面向,包含程式、美术、声音以及其他所有将成为最终成品的必需品。但是个人的才能并不代表一切,团队成员必须体认到对于这种形式的开发方式来说,「设计」才是至高无上的准则,而包括程式、美术与所有其他的东西在内,都只是为了服务最终的设计结果而存在。一位不具备这种思维的优秀工程师,将不会比完全瞭解这项关键要点的平庸工程师来得更为成功。
当团队建立完成后,他们就开始停止与其他成员一起工作。「啥?这样还算是团队吗?」听起来或许有些奇怪,但是四个人分头并进,同时开发四个游戏原型的「不协同合作」方式有许多益处,像是减少风险(四个成品中至少会有一、二个成功的结果)、友善竞争感、更广阔的主题探索(避免设计出与别人相同的游戏性),以及相互分享彼此所习得的知识。在每个原型开发週期的起始和最终阶段,团队合作是最具有价值的期间,而当进入开发期之后,与其他成员一起工作只会造成分心,而无法产生良好的正面效应。
设计:创意以及脑力激盪之谜

A great idea takes a split second to happen, but waiting for that lightning to strike can be excruciating.8only.cn||创见未来

Tower of Goo
一个伟大的点子或许能够在须臾间诞生,然而等待那个被闪电击中的时刻,却会使人备受痛苦与折磨。各位应该都听过「脑力激盪」(Brainstorming) 这项引导创意思考的团体活动吧!他们曾排定脑力激盪的会议,尝试过各种不同的创意发想方法,最后在他们开发出来的全部游戏里,没有任何一个作品是出自于团体脑力激盪议程所得出的成果,这实在是一项相当令人挫败且震惊的结论。经过许多次的研究后,他们终于发现了一个事实:「你就是无法为创意安排时程。」(You just cannot schedule creativity.) 你不能够说:「嘿,我们的计画是在 4:15 时开始脑力激盪,然后到了 5:00 我们就能得到 4 个超杀的绝妙点子,然后就可以开始动手了!」不过,脑力激盪至少能够使团队开始进行思考。
做为脑力激盪方式的替代方案,他们发现蒐集美术与音乐材料,特别有助于创造出具有情感的目标。以《Tower of Goo》为例,这个游戏背后的想法,源自于当 Gabler 听完了《Tango Apasionado》(电影《春光乍现》的主题曲)曲目后,在回家的路上,想像在某一个小镇里,当太阳下山时,镇上的每个人都扛起他们的桌子椅子或其他东西走出房子,为了某个神秘的理由,试图堆叠建立起一座高耸入云的巨塔,毫不停歇地向上攀升;然而这些居民并不是很称职的工程师,所以玩家必须协助他们建造这座高塔。
为了制作出令人喜爱的游戏,你必须先在脑海中想像玩家们会如何发出「哇!」的赞嘆声,然后依循此目标由后向前进行各项设计与开发。对于他们多数充满乐趣且获得成功的游戏作品,其实并不是令人感到意外的结果。在最佳的状况下,甚至在动手开始写任何一行程式码之前,就已经能够明确知道游戏点子是否稳固,因为他们已经事先在自己的脑袋中运行了模拟与实验的程序。没有任何游戏是偶然或者意外成功的;在见到成品之前,最终的成果早已昭然若揭。
开发:没有人知道你如何达成,也没有人会在乎
当你想出了绝妙的游戏点子后,接下来就是要在很短的时间内开发出游戏原型。首先,必须从核心机制 (Core Mechanic) 开始着手动工,建造出一个「玩具」;所谓的玩具,应该是核心机制减去任何游戏层面的实质目标或决定。不论该原型的核心机制是弹簧系统、生物群聚行为、重力机制或者其他系统,最多只会花费几个小时的时间就能够建构完毕。玩具并不存在赢或输的状态,只是一个有趣且可供玩耍的小玩意儿。先打造出玩具,能够让开发者及早确认核心游戏性的稳固性,并且找出设计层面的潜在问题。
在专案的进行过程中,他们所学到最重要的一课就是:「正确」的解决方案,通常不是最佳的解决方案。策略性地使用伪装的方法,能够节省你的时间与金钱,使你能够更快速地制作游戏。当你能够使用可预先制作的贴图,就不要设置复杂的光影系统;当你能够使用同样的效果蒙混过去时,就不要设置样式辨识系统以分析图画;当你能够延展点阵图达到相同且快速的效果时,就不要画出 Spline 曲线或者制作向量图形函式库。请大方而且经常性地进行伪装吧!
刚开始进行游戏原型开发时,每个人都会有种想要拯救所有东西的渴望:「只要再多花一点点时间与努力,一定能够把一个本来很糟糕的游戏,转变成一个很棒的游戏成品!」然而事实并非如此。以「弹簧」主题的游戏原型为例,起先是以一个非常精巧的弹簧系统做为出发点,结果到最后反而无法使这个核心机制转化成为一个优秀的游戏。对于原型开发者来说,必须要能够迅速辨认出已走入死路的游戏点子,然后断然地终止花费于其中的损失,继续朝着下个目标前进。比起花费时间试图拯救既存的程式码,保持开发时程的纪律与自发性更为珍贵。
如果原型的游戏性差劲透顶,就不会有復原的方法,即使放入了许多精美而丰富的内容物,也无法使游戏获得救赎。所有的美术、音乐以及衍生物内容,都无法使糟糕的游戏性最终转变成一个优秀的游戏,玩家很快就会发现在精美的图像与动人的旋律中,其实游戏本身并没有深厚的内涵,而不过是虚有其表而已。虽然如此,但游戏的整体美学仍然很重要;一个经过仔细琢磨的游戏,的确能够使一个好游戏变得更具可玩性,提供给玩家更好的游戏体验。
需要再次提醒的是,一位优秀的工程师未必能够成为一位优秀的敏捷原型开发者。「正确性」或「復用性」的解决方案通常不是敏捷原型开发者所追求的目标。面对每个问题与挑战,敏捷原型开发者必须要能够想出一堆解决方案,并且从中选择最快的方法。如果陷入了过度工程 (Over-Engineering) 的迷思当中,最终成果很容易产出一般性的工具或是技术展示程式,而非一个真正可玩的游戏。请记得:对于游戏原型的最终使用者们来说,他们从不会看见你的伟大工程技术,而且他们也不会在乎。
游戏性:官能领域中的「多汁」乐趣
复杂的东西未必具有乐趣。如果人类能够在几千年来,以各种不同的「球与平面」发展成各种球类运动来娱乐我们自己,那么游戏开发者或许在游戏乐趣的尝试上太过于努力了。想想《Tetris》、《Pac Man》以及其他的经典机台游戏,我们完全有可能使用基本的元素制造出丰富的游戏乐趣。透镜炫光、凹凸贴图以及其他新技术很不错,但它们并不能使游戏变得更加有趣。请先向你自己证明,以一个简单的游戏原型来说,你的核心机制的确具有价值存在;当你确信之后,就可以更进一步地装扮它,使它变得更加闪亮动人。 8only.cn||创见未来
On A Rainy Day
在不断发想、制作以及发表原型作品的过程中,他们发现具有最高可重复游玩价值的游戏,是那些拥有某种创造或客制化层面的游戏,例如像是「用手和雨伞制造出一棵怪树」、「画出你的房子」、「建造你的高塔」或是「演化你的变异种族生物」等等游戏目标。只要提供给玩家独一无二的「所有权」感觉,就能够使他们满足而且想要获得更多的乐趣。实验并不意味着复杂。在这项计画的早期,他们所制作出来的游戏,往往远超过这些游戏应有的复杂度;不只是使用者介面令人困惑,而且按键对应至行动的方法也不够自然直觉。
对于以撰写程式为乐的人来说,请记得如果没有游戏性的目标,游戏原型就只是个「玩具」,而不是个「游戏」。所谓的游戏性目标,可以是任何东西,例如:在 X 时间内蒐集 Y 个元件,或是保持系统的稳定度,或是通过这个空间并且不触碰任何阻碍物体等等。而他们发现最佳的游戏目标,是如同《Tower of Goo》中与生俱来的游戏性,也就是不断地向上建造高塔而已。
最后,请记得让游戏看起来很「多汁」(Juicy)!「多汁」所代表的意思,就是游戏中接连不断而且丰富的「使用者回应」(User Feedback) 设计。当你碰触它的时候,多汁的游戏会跳动、摇动、喷射并且发出一点声响,让玩家感觉它像是活生生的,而且会对于你所做的每件事情做出回应。使用者回应是游戏中比较微小却非常关键的要素,能够让玩家感觉自己是真正掌控着游戏世界中的一举一动,并且藉由每次的互动行为,训练玩家逐渐熟悉游戏所制订的种种规则。
进行敏捷式的游戏原型开发,就像是孕育自己的小孩一样,或许未必每次都会有美好的结果,但你总是能够从每次的经验中学到些什么新的东西。无论如何,这些过程与结果通常都非常好玩!整理以上四项内容,可以归纳出下列纲要:

准备:敏捷,是一种意向的状态

  • 拥抱失败的可能性——它会鼓励开创性的风险承担
  • 坚持实行极短的开发週期(更多的时间不等于更好的品质)
  • 限制创意能够使你渴求更多
  • 召集优秀的团队成员以及一位客观的顾问——思维与才能同样重要
  • 平行开发以获得最大化的成果

设计:创意以及脑力激盪之谜

  • 正式的脑力激盪程序只有 0% 的成功率
  • 聚集概念美术与音乐以创造情感化的目标
  • 在你的脑袋中模拟——前置开发你的原型

开发:没有人知道你如何达成,也没有人会在乎

  • 首先建立玩具
  • 在可接受的情况下使用伪装
  • 终止你的损失并且学习如何断然捨弃
  • 着重于游戏内容物无法救赎差劲的设计
  • 整体美学仍然重要——运用有益的美术、声音与音乐
  • 没有人会在乎你的伟大的工程技术

游戏性:官能领域中的「多汁」乐趣

  • 复杂未必代表乐趣
  • 创造出所有权的感觉使玩家想要获得更多
  • 实验并不意味着复杂
  • 朝向具有良好定义的目标建置开发
  • 让它多汁!

在游戏开发领域中,游戏原型究竟具有什么样的重要性?在投入庞大的资源与人力之前,如果可以预先进行游戏概念或者核心机制的原型开发,不仅能够早期验证游戏设计的良窳与否,更有机会大幅降低专案开发时期的风险,避免到了专案中后期时才发现「这种玩法根本不有趣」的残酷事实,而只能够将已完成的游戏机制整个砍掉,然后重新来过。由知名游戏制作人 Will Wright 所主导的游戏《Spore》,在开发时期中甚至制作了上百款游戏原型,用以验证游戏中的各项设计机制与表现细节。他们也很大方地在游戏的官方网站上公开其中数款游戏原型,让感兴趣的玩家自行下载。
Super Tummy Bubble
之前偶然从 Gamasutra 的档案库里翻出这篇数年前的好文章,我觉得自己实在是非常非常地幸运!由这四位作者共同发起的 Experimental Gameplay Project,竟然能够在短短的一个学期内,完成超过 50 款游戏原型。不仅要在极为紧迫的週期内,完成游戏原型的开发工作,同时又要兼顾忙碌的研究所课业,一般人可能在制作出几个作品后就会产生放弃的念头,他们却能够保持纪律持之以恆地进行这项专案,绝对是一项相当难能可贵的成就。如果我是教授游戏开发课程的教师,我一定也会很乐意依循着这样的模式与原则,指导学生们进行如此具有乐趣与学习效果的游戏原型开发专案!
对于身处程式设计领域的人来说,即使你不知道如何制作精美的图片、不懂得如何谱出美妙的音乐,但只要你的脑袋里装满了「做出来应该会很有趣」的游戏点子,不妨大胆地放手一试吧!「左手只是辅助,工具也只是辅助。」不论你熟悉的开发工具是 OGRE、SDL、Torque 或者自己打造的引擎,条条大路通罗马,这些工具全都能够协助我们到达游戏开发疆土中的美丽境界。而对于美术、设计或具有其他专业的人来说,即使你所擅长的技能并不是程式设计,但只要能够学习使用 Flash 以及简单的 ActionScript 语法,同样能够以简单的工具创造出令人赞嘆的游戏原型。
以前的我,总认为如果想要制作一款游戏作品,必定要经过非常缜密的规划与周全的设计,才能够真正开始着手动工:「一定要有一个非常棒的游戏引擎,一定要有一个前无古人后无来者的游戏点子,一定要有一份超级详尽的游戏设计文件,一定要……」有许许多多的先决条件存在,一定要满足了这些条件以后,才能真正开始动手撰写游戏。但是过度的顾虑与计画,最后反而成为理想实践道路上的最大阻碍。所以与其戒慎恐惧而迟迟不敢跨出一步,不如豪迈地向前跨出步伐,大方拥抱包括失败在内的一切未知性与可能性吧!
阅读完这篇文章以后,给了我很大的鼓舞与激励,我也已经下定决心,准备要开始动手尝试游戏原型的实验开发计画。你呢?Happy Prototyping! :)

关于Flex端实时更新的一些方法总结

诚为大家所知,Flash之所以优秀,就是它可以带来良好的用户体验和交互特性。既然涉及到交互性,开发人员在开发过程中必然会遇到实时更新的问题,那么,当后台数据发现变化的时候,如何让Flash端实时刷新显示数据呢?以下是一些可资参考的方法,各种方案优缺点各异,开发系统之前请仔细考量:

第一种:Flex端采用轮询的方式访问后台,查看后台数据是否有更新,若有则获取数据,更新界面信息;这中方法一般适用于后台更新并不频繁,对实时性信息更新要求程度一般的实时更新。例如QQ上的好友个人头像更新。

第二种:Socket :这种方法的原理是后台携带数据并发出数据更新通知,前台监听到通知后得到数据发布到界面上。此方式适用于对信息的及时性特别强的业务。如聊天室,IM即时聊天!这方面flash已有成熟的方案:Red5或FMS

第三种:使用 BlazeDS 的 Romoting 消息服务,例如商城购物车监控。具体优劣待查。

第四种:RTMP方式:Adobe在2009年一月开始将RTMP进行开源。不过应用的时候还是需要向Adobe进行License申请,详情:http://www.adobe.com/aboutadobe/pressroom/pressreleases/200901/012009RTMP.html

深入理解Flash Player重绘

原文:http://flashteam.tencent.com/post/60/深入理解flash-player重绘/

Flash Player 会以SWF内容的帧频速度来刷新需要变化的内容,而这个刷新的过程,我们通常称为“重绘(redraw)”,相信即便是初级的菜鸟也知道,只要使用的是Debug版本的Flash Player, 右键菜单里就会有“Show Redraw Regions (显示重绘区域)” 这个选项,当此选项打开的时候,我们就能清楚地看到此刻场景内被重绘的区域。

那么什么情况下会发生重绘呢?
1、最常见的是情况就是舞台上的可视组件在形状、位置、状态(alpha, scale…)发生改变的时候会触发Flash Player 的重绘。
2、当一个DisplayObject的层级(ChildIndex)发生改变的时候也会导致重绘。
3、当你将一个Sprite / MovieClip 的buttonMode 设置为 true 的时候,即便是单帧动画,重绘会在MouseEvent.MOUSE_DOWN的时候触发。又或者你对DisplayObject设置层级的时候,即便DisplayObject的层级没有发生改变,也会使得 Flash Player对此显示对象进行重绘。
既然重绘是为了能够将显示内容进行更新,那么一个Flash应用程序就不可避免的要触发重绘。而重绘却是性能消耗的主要根源,一个有经验的Flash开发人员写出的Flash应用,其性能可能70% - 90%(甚至更高)是消耗在重绘上,那么提高Flash应用程序的运行效率和减少重绘有着莫大的关系。
要减少重绘,首先我们需要对单位每帧重绘大小这个概念进行量化:重绘的大小应该取决于数量和面积。数量取决(但不是完全取决)于可视范围内的需要更新的显示对象的数量,假设场景上有两个闪烁的小圆点并且宽和高都为20,那么重绘的数量为3,而重绘的总面积就为: 20 * 20 * 3 = 1200 (平方像素)。

简单的看看上面的公式是不是觉得重绘面积的计算很容易呢?那么继续估计下下面这个情况的重绘面积是多少:


如果你计算的结果是: 20 * 20 * 6 = 2400 (平方像素),那么恭喜你,答错了…
根据上面的介绍,重绘的大小理应就是重绘的数量 * 单个区域的面积,可是为什么说这个情况就错呢?让我们看看问题究竟出在什么地方:


让人觉得奇怪的地方出现了,重绘区域的数量依旧是3,而面积却增大了不少,按照图上给出的坐标信息,我们不难算出,总重绘面积的大小为:
20 * (70 – 20 + 20) * 3 = 4200 (平方像素),比起预先估算的 2400 (平方像素)整整大了 75%!
或许从这个地方开始,大家就开始觉得困惑了。的确,Flash Player的重绘面积并没有按照我们之前的设想那样来计算,但是依旧能找到一些规律,仔细来看以下几种况:


如果你够细心,应该不难看出每次 Flash Player 重绘的区域不会超过3个,即便舞台上有多于三个的显示对象需要被重绘,Flash Player 会将其中的两个或者多个集合(根据位置来判断)在一起,然后重绘在一个大区域里面,至此,我们暂时可以将上面两个重绘法则命名为三区域法则就近合并法则,通过总结出来的这两个法则,我们就能更加容易地理解Flash Player 重绘的机制,以及解释在日常调试中遇到的一些重绘现象了。比如QQ牧场里几个靠得比较近得小动物被放在一个区域里面重绘,而有些动物则不然,被单独重绘。
当我们了解了重绘机制后,那么接下来就应该进一步去了解如何避免多余的重绘,下面列举的方法可能大部分都是被大家所熟悉的。
1、当一个带有动画效果的DisplayObject在不显示的时候,不仅仅是将其 visible 属性设置为 false, 因为重绘依旧会进行,这里你可以选择暂停掉动画,又或者利用removeChild(displayObject) 直接将此对象移除出显示列表。
2、不出现在可视范围内外观变化的显示对象其实是不会发生重绘的,这点相信是Flash本身做了优化,也就是说我的Stage.stageWidth 和 Stage.stageHeight 都为200的情况下,一个处在舞台上的变化的显示物体,坐标为(200, 200) 宽高都为10,此时Flash Player重绘内容并不会包括此对象,新版本的Flash Player 甚至在浏览器窗口最小化的时候会关闭掉所有的重绘,这个时候你往往会发现CPU占用率骤降,但是应用程序依旧在运行。
3、在设置DisplayObject的层级的时候请先做一个判断:

if (myContainer.getChildIndex(myChild) != 0)
{
    myContainer.setChildIndex(myChild, 0);
}

运气好的话,这个判断最高能带来200%以上的效率提升。
4、当你的Sprite / MovieClip 设置 cacheAsBitmap = true 这个属性的时候,当此显示对象内很小的一个区域(甚至是被遮盖着的物体)发生变化,会导致整个Sprite / MovieClip重绘。
5、尽量确保活动的显示内容在非可见区域被暂停活动或者干脆直接移除出显示列表,这里提到的不可视区域不仅仅是舞台外不可见的,还包括舞台内被其他物体遮盖住的显示对象。

正如之前提到的,重绘是Flash Player性能消耗的主要大户,所以去优化减小重绘区域面积,减少不必要的重绘操作次数,往往能够带来比较大的性能优化回报。

Flex 优化技巧大全

说明:本人不能确认的翻译保留原文:

原文地址:http://www.insideria.com/2009/04/51-actionscript-30-and-flex-op.html

1、当创建一个数组的时候避免用new操作符用 var a:Array = [];而不用var a:Array = new Array();

2、传统的这样来简历数组的话代价是非常昂贵的:

var vanityCollection01 : Array = new Array();
var vanityCollection02 : Array = new Array();
var vanityCollection03 : Array = new Array();
var vanityCollection04 : Array = new Array();

3、快速的复制一个数组:

var copy : Array = sourceArray.concat();

4、设置一个数组的值是非常忙的:

employees.push( employee );
employees[2] = employee;
5、从一个数组中取得值的速度是设置一个数组值的两倍快:
var employee : Employee = employees[2];
6、当不需要一个类的实例的时候尽量用静态的属性或方法:
StringUtils.trim( "text with space at end " );
Class definition:
package
{
     public final class StringUtils
         {
          public static function trim( s : String ) : String
          {
               var trimmed : String;
               // implementation...
               return trimmed;
           }
      }
}
7、在整个程序的生命周期中都不会改变的变量用const定义常量:
public const APPLICATION_PUBLISHER : String = "Company, Inc.";
8、当一个类不需要有之类的时候应该讲该类声明为final类型的:
public final class StringUtils
9、变量和方法的长度在As3中并不影响什么性能,但在别的语言中可能就有影响:
someCrazyLongMethodNameDoesntReallyImpactPerformanceTooMuch();
10、将语句写在一行上面并不会影响AS3程序的性能,但在别的语言中却有影响:
var i=0; j=10; k=200;
11、在内存占用上面if语句和switch语句并没有什么区别:
语句:
if ( condition )
{
// handle condition
}
和语句:
switch ( condition )
{
case "A":
// logic to handle case A
break;
case "B":
// logic to handle case B
break;
}
占用的内存是一样的
12、当你的程序处理分支较多的时候,你应该适当的排列他们出现的顺序,可以参照以下的方式进行:
if ( conditionThatHappensAlot )
{
//处理经常发生的业务逻辑
}
else if ( conditionThatHappensSomtimes )
{
// 处理偶尔会发生的业务逻辑
}
else
{
// 处理几乎不会发生的情况
}
13、Actionscript虚拟机(Flash Player)推荐在循环内部用int而不是number,但是flash Player10在flash Player9的基础上做了很多
多的改进,int,uint和number之间的转换不在像以前那么慢了。
14、Resolve issues of promotion, unknown, or incorrect object types
(不太清楚怎么翻译,个人猜测是每个变量都应该声明一个确定的类型,解决那些没有指定类型的警告信息活错误信息)
15、尽量少用unint,它可能会非常慢,但是Flashplayer10做了改进,速度不像以前那么慢了:
var footerHex : uint = 0x00ccff;
16、循环遍历的时候用int类型:
(var i: int = 0; i < n; i++) NOT for (var i: Number = 0; i < n; i++)
17、在用decimal的时候用number而不用int:
var decimal : Number  = 14.654; 而不用:var decimal : int  = 14.654;
18、用乘法代替除法:
用100*0.01代替100/100
19. Locally store function values in for and while statements instead of repeatedly accessing them
for (..){ a * 180 / Math.PI; }
declare: toRadians = a*180/Math.PI; outside of the loop
20、避免在循环中调用方法或计算:
var len : int = myArray.lengh;
for (var i=0;i<len;i++){}
而不要用:
for (var i=0;i< myArray.lengh;i++){ }
21、用正则表达式进行字符串的校验,用String的方法进行字符串的查找:
// postal code validation example using regular expressions
private var regEx:RegExp = /^[A-Z][0-9][A-Z] [0-9][A-Z][0-9]$/i;
private function validatePostal( event : Event ) : void
{
if( regEx.test( zipTextInput.text ) )
{
// handle invalid input case
}
}
// search a string using String methods
var string : String = "Search me";
var searchIndex : int = string.indexOf( "me" );
var search : String = string.substring( searchIndex, searchIndex + 2 );
22. Reuse objects to maintain a “memory plateau” DisplayObjects, URLLoader objects
23. Follow the Flex component model:
createChildren();
commitProperties();
updateDisplayList();
24、尽量少用dataGrid这样的重量级的组件,除非你用一个常规的list无法实现你要的功能。
25. Avoid Repeaters for scrollable data
26、尽量避免使用setStyle()方法,这个方法在Flex框架里面是众多代价敖贵的方法之一。
27、当你用过多的容器嵌套的时候会较低应用程序的性能:
<mx:Panel>
<mx:VBox>
<mx:HBox>
<mx:Label text="Label 1" />
<mx:VBox>
<mx:Label text="Label 2" />
</mx:VBox>
<mx:HBox>
<mx:Label text="Label 3" />
<mx:VBox>
<mx:Label text="Label 4" />
</mx:VBox>
</mx:HBox>
</mx:HBox>
</mx:VBox>
</mx:Panel>
28、没有必要每次都用容器组件作为你自定义组件的父控件:
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml"
source="avatar.jpg" width="200" height="200" />
29、减少不必要的容器嵌套
30、不要在Panel中vBox和HBox,用Panel的Layout属性就可以了
31、不要在application标签下用HBox,和Vbox,道理和30一样
32. Set the recycleChildren property to true to improve a Repeater object's performance
(re-uses previously created children instead of creating new ones)
<mx:Script>
<![CDATA[
[Bindable]
public var repeaterData : Array = ["data 1", "data 2"];
]]>
</mx:Script>
<mx:Repeater id="repeater" dataProvider="{repeaterData}">
<mx:Label text="data item: {repeater.currentItem}"/>
</mx:Repeater>
33、将应用程序的帧率设置为60fps活着更低:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml
frameRate="45">
</mx:Application>
34. Avoid multiple display manipulations per frame
35. Code against ENTER_FRAME events instead of Timer events
public function onEnterFrame( event : Event ) : void
{
}
private function init() : void
{
addEventListener( Event.ENTER_FRAME, onEnterFrame );
}
NOT:
public function onTimerTick( event : Event ) : void
{
}
private function init() : void
{
var timer : Timer = new Timer();
timer.start();
timer.addEventListener( TimerEvent.TIMER, onTimerTick );
}
36. To defer object creation over multiple frames use:
<mx:Container creationPolicy="queued"/>
37. Alpha = 0 is not the same as visible = false (Objects marked invisible are passed over)
loginButton.visible = false;
NOT:
loginButton.alpha = 0;

7、在整个程序的生命周期中都不会改变的变量用const定义常量:
public const APPLICATION_PUBLISHER : String = "Company, Inc.";
8、当一个类不需要有之类的时候应该讲该类声明为final类型的:
public final class StringUtils
9、变量和方法的长度在As3中并不影响什么性能,但在别的语言中可能就有影响:
someCrazyLongMethodNameDoesntReallyImpactPerformanceTooMuch();
10、将语句写在一行上面并不会影响AS3程序的性能,但在别的语言中却有影响:
var i=0; j=10; k=200;
11、在内存占用上面if语句和switch语句并没有什么区别:
语句:
if ( condition ) {      // handle condition }
和语句:
switch ( condition ) {

case "A":          // logic to handle case A
break;

case "B":          // logic to handle case B       break; }

占用的内存是一样的
12、当你的程序处理分支较多的时候,你应该适当的排列他们出现的顺序,可以参照以下的方式进行:
if ( conditionThatHappensAlot ) {      //处理经常发生的业务逻辑
} else if ( conditionThatHappensSomtimes )  {      // 处理偶尔会发生的业务逻辑
} else  {      // 处理几乎不会发生的情况
}
13、Actionscript虚拟机(Flash Player)推荐在循环内部用int而不是number,但是flash Player10在flash Player9的基础上做了很多
多的改进,int,uint和number之间的转换不在像以前那么慢了。
14、Resolve issues of promotion, unknown, or incorrect object types

(不太清楚怎么翻译,个人猜测是每个变量都应该声明一个确定的类型,解决那些没有指定类型的警告信息活错误信息)
15、尽量少用unint,它可能会非常慢,但是Flashplayer10做了改进,速度不像以前那么慢了:
var footerHex : uint = 0x00ccff;
16、循环遍历的时候用int类型:
(var i: int = 0; i < n; i++) NOT for (var i: Number = 0; i < n; i++)  17、在用decimal的时候用number而不用int:
var decimal : Number  = 14.654; 而不用:var decimal : int  = 14.654;
18、用乘法代替除法:
用100*0.01代替100/100
19. Locally store function values in for and while statements instead of repeatedly accessing them
for (..){ a * 180 / Math.PI; }  declare: toRadians = a*180/Math.PI; outside of the loop
20、避免在循环中调用方法或计算:
var len : int = myArray.lengh;  for (var i=0;i<len;i++){}
而不要用:
for (var i=0;i< myArray.lengh;i++){ }
21、用正则表达式进行字符串的校验,用String的方法进行字符串的查找:
// postal code validation example using regular expressions

private var regEx:RegExp = /^[A-Z][0-9][A-Z] [0-9][A-Z][0-9]$/i;

private function validatePostal( event : Event ) : void {

if( regEx.test( zipTextInput.text ) )      {

// handle invalid input case       } }

// search a string using String methods

var string : String = "Search me"; var searchIndex : int = string.indexOf( "me" );

var search : String = string.substring( searchIndex, searchIndex + 2 );
22. Reuse objects to maintain a “memory plateau” DisplayObjects, URLLoader objects
23. Follow the Flex component model: createChildren(); commitProperties(); updateDisplayList();
24、尽量少用dataGrid这样的重量级的组件,除非你用一个常规的list无法实现你要的功能。
25. Avoid Repeaters for scrollable data
26、尽量避免使用setStyle()方法,这个方法在Flex框架里面是众多代价敖贵的方法之一。
27、当你用过多的容器嵌套的时候会较低应用程序的性能:
<mx:Panel>     <mx:VBox>         <mx:HBox>

<mx:Label text="Label 1" />

<mx:VBox>

<mx:Label text="Label 2" />

</mx:VBox>               <mx:HBox>

<mx:Label text="Label 3" />                   <mx:VBox>

<mx:Label text="Label 4" />                   </mx:VBox>

</mx:HBox>           </mx:HBox>

</mx:VBox> </mx:Panel>
28、没有必要每次都用容器组件作为你自定义组件的父控件:
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml"       source="avatar.jpg" width="200" height="200" />
29、减少不必要的容器嵌套
30、不要在Panel中vBox和HBox,用Panel的Layout属性就可以了
31、不要在application标签下用HBox,和Vbox,道理和30一样
32. Set the recycleChildren property to true to improve a Repeater object's performance

(re-uses previously created children instead of creating new ones) <mx:Script>     <![CDATA[

[Bindable]

public var repeaterData : Array = ["data 1", "data 2"];

]]> </mx:Script>

<mx:Repeater id="repeater" dataProvider="{repeaterData}">

<mx:Label text="data item: {repeater.currentItem}"/>

</mx:Repeater>
33、将应用程序的帧率设置为60fps活着更低:
<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml      frameRate="45">

</mx:Application>
34. Avoid multiple display manipulations per frame
35. Code against ENTER_FRAME events instead of Timer events public function onEnterFrame( event : Event ) : void { }

private function init() : void {      addEventListener( Event.ENTER_FRAME, onEnterFrame ); }
NOT:
public function onTimerTick( event : Event ) : void { } private function init() : void {

var timer : Timer = new Timer();      timer.start();      timer.addEventListener( TimerEvent.TIMER, onTimerTick ); }
36. To defer object creation over multiple frames use: <mx:Container creationPolicy="queued"/>
37. Alpha = 0 is not the same as visible = false

(Objects marked invisible are passed over)

loginButton.visible = false; NOT: loginButton.alpha = 0;

Java 面试:冒泡排序

面试无数,逢试必备——冒泡排序

public class TestBubbleUp { /* 冒泡排序算法 */
	public static int[] sort(int[] m) {
		int theLenth = m.length; /* 执行theLenth次 */
		for (int i = 0; i < theLenth; i++) { /* 每执行一次,将最小的数排在后面 */
			for (int j = 0; j < theLenth - i - 1; j++) {
				int a = m[j];
				int b = m[j + 1];
				if (a < b) {
					m[j] = b;
					m[j + 1] = a;
				}
			}
		}
		return m;
	}

	public static void main(String args[]) {
		int[] m = { 9, 1, 0, 13, 100, 39, 88, 32 };
		int[] n = sort(m);
		for (int i = 0; i < m.length; i++) {
			System.out.println(n[i]);
		}
	}
}

Flex 开发必备10武器(转载)

来自:http://www.ria999.com/a/menu2/2010/0419/381.html

01. Tour de Flex 02. Component Explorer 03. Style Explorer 04. Regular Expression Explorer By Ryan Swanson 05. Charts Explorer By Ely Greenfield 06. Efflex Effects Explorer By Stephen Downs 07. Filter Explorer 08. Primitive Objects Explorer

01. Tour de Flex

02. Component Explorer

03. Style Explorer

04. Regular Expression Explorer


By Ryan Swanson

05. Charts Explorer


By Ely Greenfield

06. Efflex Effects Explorer


By Stephen Downs

07. Filter Explorer

08. Primitive Objects Explorer

09. Data Visualization Explorer

10. Button Skin Explorer

Comment with your favorite Flex explore

笑看Adobe与Apple关于Flash之争

事件:

苹果修订应用开发协议 禁止使用Adobe技术

消息详情:

苹果当地时间周四公布了新版iPhone OS,同时修订了应用开发协议。根据协议,开发者在开发iPad和iPhone应用时不能使用Adobe的技术。
根据新版协议,苹果将不批准使用 非苹果专有软件开发的iPad和iPhone应用。苹果称,“应用只能使用或调用苹果应用开发手册中的公开API(应用编程接口),不得使用或调用任何非 公开的API。应用源代码必须采用Objective-C、C、 C++或JavaScript编程语言编写,只有采用C、C++和Objective-C的源代码才能编译并直接调用API(例如,通过中间转换代码、兼 容层或工具调用API的应用将不会被批准。)。”

这意味着,利用Adobe的最新版多媒体创作软件开发的iPad和iPhone应用违反了苹果的规则。 Adobe的最新版多媒体创作软件Creative Suite 5能够生成iPad和iPhone应用。

最新消息:

业内专家指出,苹果做出的限制将阻止开发者重用采用了Adobe Flash的应用。目前iPhone和iPad均不支持Flash。Adobe于4月12日发布了Creative Suite 5软件套装,帮助开发者将Flash代码转换为iPhone代码。(塔努·纳雷恩:你不让我放flash是吧,那我转成html5,嘿嘿

Flash程序在互联网上很常见,许多游戏和视频均采用Flash 来开发。然而根据苹果新的条款,开发者使用Creative Suite 5将导致应用被苹果拒绝。(乔布斯:小样,哥把你的开发工具也封了去!)

Adobe在一份声明中表示,苹 果修改授权条款不会阻止该公司发布这款软件。Adobe首席技术官凯文·林奇(Kevin Lynch)在博客中表示:“我们将继续在CS5中提供这项功能,是否允许应用采用该功能取决于苹果。”

局外人也来伸一脚:

第三方看准苹果与Adobe矛盾 推Flash解码包

美国RipCode公司日前推出一款Flash视频解码包,解决了苹果iPad平板电脑无法播放Flash视频的尴尬。
当前,由于iPad和 iPhone等产品始终不支持Flash,导致苹果和 Adobe两家公司的关系十分紧张。本周二甚至有消息称,Adobe将在未来书周内起诉苹果。

对此,RipCode公司日前看准时机,推出一款Flash视频解码包 “TransAct Transcoder V6”,它可以将基于Flash的文件或视频直播转提前转换为iPad可以支持的格式,甚至无需预解码或基于设备的客户端的支持。

该代码包支持从QVGA到1080i/p级分辨率,可以将Flash视频转换为 QuickTime、MP4、MPEG-TS和RTSP等多种媒体格式。

恩恩怨怨:

苹果暗示,采取这样的举措是由于技术原因,例如iPhone硬件限制,以及苹果CEO史蒂夫·乔布斯(Steve Jobs)对Flash这款产品的厌恶。此外有人猜测,这可能是由于大部分网络广告使用Flash,而苹果希望推出自己的广告解决方案iAd。

不过考虑到乔布斯的个人性格,苹果这样做可能另有原因。在过去近15年的时间中,Adobe一直将Windows作为主要平台。在苹果最困难的时期,Adobe没有给予苹果任何帮助。因此乔布斯无法原谅Adobe,并一直在寻找机会进行报复。

Adobe的产品主要面向从事创造性工作的专业人员,其产品包括Photoshop、Premiere。这也是对苹果来说最关键的用户群,尤其是在苹果复苏的初期。1996年,苹果看起来即将彻底失败,当时Adobe决定全面转向Windows平台。即使苹果随后开始复苏,Mac OS X系统成为一款具有吸引力的平台,Adobe仍然对苹果态度冷淡。

例如2001年时,Adobe针对Windows推出了全功能的视频编辑软件套装,但没有推出Mac版的计划。2002年,Adobe的一系列产品仍然不能原生地支持Mac OS X系统,其中包括Acrobat 4.x和5.0、After Effects 5.0、FrameMaker 6.0、FrameMaker+SGML 6.0、FrameViewer 6.0、GoLive、Premiere、Photoshop、Photoshop Elements和LiveMotion。

2006年,当苹果开始全面复苏,Mac电脑成为创造性工作者的第一选择后,Adobe仍然坚持将Windows放在首位,只是逐步将产品引入Mac平台。

业内人士认为,Adobe的软件契合苹果的核心用户群,因此乔布斯很可能将Adobe在1996年的做法视作一种背叛,并开始回击。

继续关注中,明显的是,苹果凭借平台优势对Adobe Flash不支持让Adobe极为难受,一方面html5的日益隆起,flash的地位正面临着前所未有的挑战;这边横生枝节,Apple落井下石。到底Flash将会走向何方,大家拭目以待吧。