动力男孩flash乐园

不抛弃、不放弃,梦想要迂回去实现~!
  • 首页
  • 我的座右铭
  • 我的作品
  • 留言聊天室
  • 动力男孩的诞生
933次浏览↓

[转]什么是 PureMVC 框架(提供下载)

2009年9月25日 powerboy 没有评论

  PureMVC是在基础的经典模型、视图和控制器上建立的一个轻量级的应用框架,这种开源框架是免费的,它最初是执行的ActionScript 3语言使用的Adobe Flex、Flash和AIR,现在已经移植到几乎所有主要的发展平台,目前支持两个版本框架:标准和多核,总之,标准版提供了一种简单的编码分离的方法,按照MVC设计概念。除此之外,多版本允许多个PureMVC应用运行在同一个虚拟机;模块化编程

AS3版 PureMVC 下载地址:
http://puremvc.org/pages/downloads/AS3/PureMVC_AS3.zip
PureMVC框架概述与UML视图
docx文档下载地址:http://as3libs.googlecode.com/files/PureMVC.rar

框架概述
本文讨论PureMVC框架的类和接口,通过简单的UML(统一建模语言)图表阐述他们的作用、职责和合作。
PureMVC有一个非常狭隘的主要目标:用于帮助程序员分离代码为三个离散的层:即模型,视图和控制器。
在该经典的MVC元模式实现框架中,应用层有三个单例(一个只创建一次的类)所表示。而第四个单例,Façade类通过一个单一的接口为应用程序之间提供通讯,从而简化了开发。
模型(Model)简单的指向Proxy的引用。Proxy代码负责操作数据模型,与远程服务通信存取数据。
视图指向Mediator的引用。Mediator管理视图组件,增加事件监听器,操作视图组件的状态。
控制器包括命令类及其映射。命令类是无状态的,只有需要时才被创建。
Façade单例初始化Model, View, Controller,并且能访问各层类的Public方法。

Façade与核心类

Façade类令roxies, Mediators和Commands之间以松耦合的方式允许互相通信,而不需要导入或知道框架核心的存在。当我们创建一个Façade类具体的应用时,就可以“即开即用”的使用它了。附带的,与Façade类的交互将会最大化的降低开发者对API知识的了解程度。
核心成员类Model, View和Controller分别实现了IModel, IView 以及 IController 接口,Façade类实现了由核心接口组成的IFacade接口。

View, Mediators和View组件

View类被实现为一个用来缓存指向一个IMediator实例引用的单例。
Mediators类帮助我们创建或者重用已经存在的用户接口组件,而不用让他们通讯的PureMVC程序的知识去影响他们。具体的Mediators实例必须实现IMediator接口,通常是作为Mediator类的子类来实现的。
View视图用来显示数据和处理用户交互。在一个基于flash的应用程序中,他们通常通过使用事件和传递一些属性给其Mediators类去检查或者控制,以便与View的Mediators类交互。一个Mediator类通过View组件的数据与之建立联系。当一个Mediator 类的实例被view注册时,他会被假设为他需要获取通知。因此必须返回一个包含所有他感兴趣数据的通知名数组。
因为Mediator类必须实现IMediator接口,所以一个Mediator实例拥有handleNotification方法。当该实例被View组件注册,一个Observer实例就被创建并且被注册给每一个Notification的数组中。这样Mediator的handleNotification方法就被触发,而不论注册Notification的Mediator是否感兴趣。
Mediator类由于实现了INotifier接口而具备了sendNotification方法,sendNotification方法的参数是一个新的Notification通知,而后使用一个IFacade接口的单例去广播。

Mediator类的protected属性被初始化用于注册IFacade实例,并且因此Mediator必须在主程序初始化Façade实例后被注册。

Model, Proxies与数据对象

Model类被实现为一个简单的指向IProxy引用的单例。
Proxy类帮助我们暴露数据模型和实体类(当域逻辑和服务支持时)给应用程序,使得程序可以被其它地方被复用或重构。
我们可能通过使用一个Proxy实例来简化指向本地数据对象的管理,在这种情况下交互可能引起一些数据的同步操作。一个Proxy实例也可能被用来进行程序的原创服务操作,加载或者保持数据。这时,我们可能需要出发一个方法或者基于Proxy去设置数据,并且等待该Proxy从服务器成功加载到数据后广播一个Notification通知。
Proxy类由于实现了INotifier接口而具备了sendNotification方法,sendNotification方法的参数是一个新的Notification通知,而后使用一个IFacade接口的单例去广播。
Proxy类的protected属性被初始化用于注册IFacade实例,并且因此Mediator必须在主程序初始化Façade实例后被注册。

Controller与Commands

MacroCommand类从它的构造函数中触发initializeMacroCommand方法。使用者必须在其子类中重写initializeMacroCommand方法,一般addSubCommand方法添加所有Command。可以使用SimpleCommands 或者 MacroCommands中的任何一种。

View, Observer与Notification

Proxies,Mediators与Commands类之间的通讯是通过广播Notifications来实现松耦合和跨平台特性的:
Proxies可以发送,但不能接收Notification
Mediator声明感兴趣的Notification和接收Notification
Commands被触发或广播Notifications
PureMVC应用程序可能运行在不能访问Flash Event和EventDispatcher类的环境中,所以框架使用观察者模式以一种松耦合的方式在Model, View, Controller之间通信。
PureMVC使用观察者模式就是为了该目的。IObserver携带一个希望被关注(即“被关注的内容”)的对象引用,该对象的一个方法将会在INotification实例被广播(即“被关注方法”)时被触发。
View组件的职责是管理Notification的名称给Observer列表,以及当有Notification被发送时通知所有的Observers。

转自:http://www.b4en.com/home/space.php?uid=117&do=blog&id=93

分类: 我收集的文章 标签: as3, flash, flex
495次浏览↓

[转] 我们为什么要工作

2009年9月12日 powerboy 没有评论

强烈推荐——HP大中华区总裁孙振耀退休感言
如果这篇文章没有分享给你,那是我的错。
如果这篇文章分享给你了,你却没有读,继续走弯路的你不要怪我。
如果你看了这篇文章,只读了一半你就说没时间了,说明你已经是个“茫”人了。
如果你看完了,你觉得这篇文章只是讲讲大道理,说明你的人生阅历还不够,需要你把这篇文章珍藏,走出去碰几年壁,头破血流后再回来,再读,你就会感叹自己的年少无知。
如果你看完了,觉得很有道理,然后束之高阁,继续走进拥挤的地铁,依然用着自己昨日的观念来思考自己的未来,你的人生也将继续重复着昨日的状况。
如果你看完了,觉得那是一个过来人,对你的人生忠告,并你也愿意用他告诉你的思想去指导自己今后的生活,对你来讲成功不是很难,难的是你是否可以用这篇文章里的思想一直鞭策自己。
如果你看完了,觉得那是一个长辈用他的一生的时间来写的一篇对你忠告的文章,说明你已经有了和他相似的人生阅历,只要你继续努力,成就伟业并不难,难的是你是否可以把自己的人生经验和他人分享呢?
体验决定深度,知识决定广度。你的人生是什么呢?

一、关于工作与生活   
  我有个有趣的观察,外企公司多的是25-35岁的白领,40岁以上的员工很少,二三十岁的外企员工是意气风发的,但外企公司40岁附近的经理人是很尴尬的。我见过的40岁附近的外企经理人大多在一直跳槽,最后大多跳到民企,比方说,唐骏。外企员工的成功很大程度上是公司的成功,并非个人的成功,西门子的确比国美大,但并不代表西门子中国经理比国美的老板强,甚至可以说差得很远。而进外企的人往往并不能很早理解这一点,把自己的成功90%归功于自己的能力,实际上,外企公司随便换个中国区总经理并不会给业绩带来什么了不起的影响。好了问题来了,当这些经理人40多岁了,他们的薪资要求变得很高,而他们的才能其实又不是那么出众,作为外企公司的老板,你会怎么选择?有的是只要不高薪水的,要出位的精明强干精力充沛的年轻人,有的是,为什么还要用你?
  从上面这个例子,其实可以看到我们的工作轨迹,二三十岁的时候,生活的压力还比较小,身体还比较好,上面的父母身体还好,下面又没有孩子,不用还房贷,也没有孩子要上大学,当个外企小白领还是很光鲜的,挣得不多也够花了。但是人终归要结婚生子,终归会老,到了40岁,父母老了,要看病要吃药,要有人看护,自己要还房贷,要过基本体面的生活,要养小孩……那个时候需要挣多少钱才够花才重要。所以,看待工作,眼光要放远一点,一时的谁高谁低并不能说明什么。   
  从这个角度上来说,我不太赞成过于关注第一份工作的薪水,更没有必要攀比第一份工作的薪水,这在刚刚出校园的学生中间是很常见的。正常人大概要工作 35年,这好比是一场马拉松比赛,和真正的马拉松比赛不同的是,这次比赛没有职业选手,每个人都只有一次机会。要知到,有很多人甚至坚持不到终点,大多数人最后是走到终点的,只有少数人是跑过终点的,因此在刚开始的时候,去抢领先的位置并没有太大的意义。刚进社会的时候如果进500强公司,大概能拿到3k -6k/月的工资,有些特别技术的人才可能可以到8k/月,可问题是,5年以后拿多少?估计5k-10k了不起了。起点虽然高,但增幅有限,而且,后面的年轻人追赶的压力越来越大。   
  我前两天问我的一个销售,你会的这些东西一个新人2年就都学会了,但新人所要求的薪水却只是你的一半,到时候,你怎么办?
  职业生涯就像一场体育比赛,有初赛、复赛、决赛。初赛的时候大家都刚刚进社会,大多数都是实力一般的人,这时候努力一点认真一点很快就能让人脱颖而出,于是有的人二十多岁做了经理,有的人迟些也终于赢得了初赛,三十多岁成了经理。然后是复赛,能参加复赛的都是赢得初赛的,每个人都有些能耐,在聪明才智上都不成问题,这个时候再想要胜出就不那么容易了,单靠一点点努力和认真还不够,要有很强的坚忍精神,要懂得靠团队的力量,要懂得收服人心,要有长远的眼光……   
  看上去赢得复赛并不容易,但,还不是那么难。因为这个世界的规律就是给人一点成功的同时让人骄傲自满,刚刚赢得初赛的人往往不知道自己赢得的仅仅是初赛,有了一点小小的成绩大多数人都会骄傲自满起来,认为自己已经懂得了全部,不需要再努力再学习了,他们会认为之所以不能再进一步已经不是自己的原因了。虽然他们仍然不好对付,但是他们没有耐性,没有容人的度量,更没有清晰长远的目光。就像一只愤怒的斗牛,虽然猛烈,最终是会败的,而赢得复赛的人则象斗牛士一样,不急不躁,跟随着自己的节拍,慢慢耗尽对手的耐心和体力。赢得了复赛以后,大约已经是一位很了不起的职业经理人了,当上了中小公司的总经理,大公司的副总经理,主管着每年几千万乃至几亿的生意。
  最终的决赛来了,说实话我自己都还没有赢得决赛,因此对于决赛的决胜因素也只能凭自己的猜测而已,这个时候的输赢或许就像武侠小说里写得那样,大家都是高手,只能等待对方犯错了,要想轻易击败对手是不可能的,除了使上浑身解数,还需要一点运气和时间。世界的规律依然发挥着作用,赢得复赛的人已经不只是骄傲自满了,他们往往刚愎自用,听不进去别人的话,有些人的脾气变得暴躁,心情变得浮躁,身体变得糟糕,他们最大的敌人就是他们自己,在决赛中要做的只是不被自己击败,等着别人被自己击败。这和体育比赛是一样的,最后高手之间的比赛,就看谁失误少谁就赢得了决赛。

 
二、 根源   
  你工作快乐么?你的工作好么?  
  有没有觉得干了一段时间以后工作很不开心?有没有觉得自己入错了行?有没有觉得自己没有得到应有的待遇?有没有觉得工作像一团乱麻每天上班都是一种痛苦?有没有很想换个工作?有没有觉得其实现在的公司并没有当初想象得那么好?有没有觉得这份工作是当初因为生存压力而找的,实在不适合自己?你从工作中得到你想要得到的了么?你每天开心么?   
  天涯上愤怒的人很多,你有没有想过,你为什么不快乐?你为什么愤怒?  
  其实,你不快乐的根源,是因为你不知道要什么!你不知道要什么,所以你不知道去追求什么,你不知道追求什么,所以你什么也得不到。   
  我总觉得,职业生涯首先要关注的是自己,自己想要什么?大多数人大概没想过这个问题,唯一的想法只是——我想要一份工作,我想要一份不错的薪水,我知道所有人对于薪水的渴望,可是,你想每隔几年重来一次找工作的过程么?你想每年都在这种对于工作和薪水的焦急不安中度过么?不想的话,就好好想清楚。饮鸩止渴,不能因为口渴就拼命喝毒药。越是焦急,越是觉得自己需要一份工作,越饥不择食,越想不清楚,越容易失败,你的经历越来越差,下一份工作的人看着你的简历就皱眉头。于是你越喝越渴,越渴越喝,陷入恶性循环。最终只能哀叹世事不公或者生不逢时,只能到天涯上来发泄一把,在失败者的共鸣当中寻求一点心理平衡罢了。大多数人都有生存压力,我也是,有生存压力就会有很多焦虑,积极的人会从焦虑中得到动力,而消极的人则会因为焦虑而迷失方向。所有人都必须在压力下做出选择,这就是世道,你喜欢也罢不喜欢也罢。  
  一般我们处理的事情分为重要的事情和紧急的事情,如果不做重要的事情就会常常去做紧急的事情。比如锻炼身体保持健康是重要的事情,而看病则是紧急的事情。如果不锻炼身体保持健康,就会常常为了病痛烦恼。又比如防火是重要的事情,而救火是紧急的事情,如果不注意防火,就要常常救火。找工作也是如此,想好自己究竟要什么是重要的事情,找工作是紧急的事情,如果不想好,就会常常要找工作。往往紧急的事情给人的压力比较大,迫使人们去赶紧做,相对来说重要的事情反而没有那么大的压力,大多数人做事情都是以压力为导向的,压力之下,总觉得非要先做紧急的事情,结果就是永远到处救火,永远没有停歇的时候。(很多人的工作也像是救火队一样忙碌痛苦,也是因为工作中没有做好重要的事情。)那些说自己活在水深火热为了生存顾不上那么多的朋友,今天找工作困难是当初你们没有做重要的事情,是结果不是原因。如果今天你们还是因为急于要找一份工作而不去思考,那么或许将来要继续承受痛苦找工作的结果。   
  我始终觉得我要说的话题,沉重了点,需要很多思考,远比唐笑打武警的话题来的枯燥乏味,但是,天下没有轻松的成功,成功,要付代价。请先忘记一切的生存压力,想想这辈子你最想要的是什么?所以,最要紧的事情,先想好自己想要什么。   

三、什么是好工作   
  当初微软有个唐骏,很多大学里的年轻人觉得这才是他们向往的职业生涯,我在清华bbs里发的帖子被这些学子们所不屑,那个时候学生们只想出国或者去外企,不过如今看来,我还是对的,唐骏去了盛大,陈天桥创立的盛大,一家民营公司。一个高学历的海归在500强的公司里拿高薪水,这大约是很多年轻人的梦想,问题是,每年毕业的大学生都在做这个梦,好的职位却只有500个。   
  人都是要面子的,也是喜欢攀比的,即使在工作上也喜欢攀比,不管那是不是自己想要的。大家认为外企公司很好,可是好在哪里呢?好吧,他们在比较好的写字楼,这是你想要的么?他们出差住比较好的酒店,这是你想要的么?别人会羡慕一份外企公司的工作,这是你想要的么?那一切都是给别人看的,你干吗要活得那么辛苦给别人看?另一方面,他们薪水福利一般,并没有特别了不起,他们的晋升机会比较少,很难做到很高阶的主管,他们虽然厌恶常常加班,却不敢不加班,因为“你不干有得是人干”,大部分情况下会找个台湾人香港人新加坡人来管你,而这些人又往往有些莫名其妙的优越感。你想清楚了么?500强一定好么?找工作究竟是考虑你想要什么,还是考虑别人想看什么?   
  我的大学同学们大多数都到美国了,甚至毕业这么多年了,还有人最近到国外去了。出国真的有那么好么?我的大学同学们,大多数还是在博士、博士后、访问学者地挣扎着,至今只有一个正经在一个美国大学里拿到个正式的教职。国内的教授很难当么?我有几个表亲也去了国外了,他们的父母独自在国内,没有人照顾,有好几次人在家里昏倒都没人知道,出国,真的这么光彩么?就像有人说的“很多事情就像看A片,看的人觉得很爽,做的人未必。”  
  人总想找到那个最好的,可是,什么是最好的?你觉得是最好的那个,是因为你的确了解,还是因为别人说他是最好的?即使他对于别人是最好的,对于你也一定是最好的么?  
  对于自己想要什么,自己要最清楚,别人的意见并不是那么重要。很多人总是常常被别人的意见所影响,亲戚的意见,朋友的意见,同事的意见……问题是,你究竟是要过谁的一生?人的一生不是父母一生的续集,也不是儿女一生的前传,更不是朋友一生的外篇,只有你自己对自己的一生负责,别人无法也负不起这个责任。自己做的决定,至少到最后,自己没什么可后悔。对于大多数正常智力的人来说,所做的决定没有大的对错,无论怎么样的选择,都是可以尝试的。比如你没有考自己上的那个学校,没有入现在这个行业,这辈子就过不下去了?就会很失败?不见得。   
  我想,好工作,应该是适合你的工作,具体点说,应该是能给你带来你想要的东西的工作,你或许应该以此来衡量你的工作究竟好不好,而不是拿公司的大小,规模,外企还是国企,是不是有名,是不是上市公司来衡量。小公司,未必不是好公司,赚钱多的工作,也未必是好工作。你还是要先弄清楚你想要什么,如果你不清楚你想要什么,你就永远也不会找到好工作,因为你永远只看到你得不到的东西,你得到的,都是你不想要的。
  可能,最好的,已经在你的身边,只是,你还没有学会珍惜。人们总是盯着得不到的东西,而忽视了那些已经得到的东西。   

四、普通人   
  我发现中国人的励志和国外的励志存在非常大的不同,中国的励志比较鼓励人立下大志愿,卧薪尝胆,有朝一日成富成贵。而国外的励志比较鼓励人勇敢面对现实生活,面对普通人的困境,虽然结果也是成富成贵,但起点不一样,相对来说,我觉得后者在操作上更现实,而前者则需要用999个失败者来堆砌一个成功者的故事。   
  我们都是普通人,普通人的意思就是,概率这件事是很准的。因此,我们不会买彩票中500万,我们不会成为比尔盖茨或者李嘉诚,我们不会坐飞机掉下来,我们当中很少的人会创业成功,我们之中有30%的人会离婚,我们之中大部分人会活过65岁……   
  所以请你在想自己要什么的时候,要得“现实”一点,你说我想要做李嘉诚,抱歉,我帮不上你。成为比尔盖茨或者李嘉诚这种人,是靠命的,看我写的这篇文章绝对不会让你成为他们,即使你成为了他们,也绝对不是我这篇文章的功劳。“王侯将相宁有种乎”但真正当皇帝的只有一个人,王侯将相,人也不多。目标定得高些对于喜欢挑战的人来说有好处,但对于大多数普通人来说,反而比较容易灰心沮丧,很容易就放弃了。
  回过头来说,李嘉诚比你有钱大致50万倍,他比你更快乐么?或许。有没有比你快乐50万倍,一定没有。他比你最多也就快乐一两倍,甚至有可能还不如你快乐。寻找自己想要的东西不是和别人比赛,比谁要得更多更高,比谁的目标更远大。虽然成为李嘉诚这个目标很宏大,但你并不见得会从这个目标以及追求目标的过程当中获得快乐,而且基本上你也做不到。你必须听听你内心的声音,寻找真正能够使你获得快乐的东西,那才是你想要的东西。
  你想要的东西,或者我们把它称之为目标,目标其实并没有高低之分,你不需要因为自己的目标没有别人远大而不好意思,达到自己的目标其实就是成功,成功有大有小,快乐却是一样的。我们追逐成功,其实追逐的是成功带来的快乐,而非成功本身。职业生涯的道路上,我们常常会被攀比的心态蒙住眼睛,忘记了追求的究竟是什么,忘记了是什么能使我们更快乐。   社会上一夜暴富的新闻很多,这些消息,总会在我们的心里面掀起很多涟漪,涟漪多了就变成惊涛骇浪,心里的惊涛骇浪除了打翻承载你目标的小船,并不会使得你也一夜暴富。“只见贼吃肉,不见贼挨揍。”我们这些普通人既没有当贼的勇气,又缺乏当贼的狠辣绝决,虽然羡慕吃肉,却更害怕挨揍,偶尔看到几个没挨揍的贼就按奈不住,或者心思活动,或者大感不公,真要叫去做贼,却也不敢。  
我还是过普通人的日子,要普通人的快乐,至少,晚上睡得着觉。

转自:http://blog.hellodsp.com/space.php?uid=19336&do=blog&id=342

分类: 我收集的文章 标签: 人生感悟, 哲理
748次浏览↓

RIA技术深度解析Flex4和Flash安全沙箱

2009年8月9日 powerboy 1 条评论

  昨天参加了InfoQ中文站主办的活动,由马鉴讲解了Flex4新体系、李文磊讲解了安全沙箱机制,这次活动总体感觉还不错,不过互动环节还有一些需要改进的地方,很多学习者想交流问题,但由于会议时间有限,所以不得不停止提问。
  Flash Catalyst无疑成为我这次最关心的话题。我们传统开发项目的模式,都是美术设计师先出一个设计稿,交互设计师拿过来再按照设计稿样式制作出交互模型,但是很多情况下他们沟通都会陷入尴尬局面,交互设计师说这个设计稿某某地方实现不了,美术设计师说你做的东西不是我想要的,诸如此类事情频繁发生,于是就出现了Flash Catalyst,它诞生的初衷就是为了保证交互设计师做出来的东西就是美术设计师想要的。不过由于目前只是1.0beta版,所以还不可能十分完美,但是不管怎么说,它的出现已经颠覆了传统的开发方式,这无疑是个进步。
  在这次活动中,我有幸获得了官方赠送的adobe开发工具光盘和书籍,在此表示感谢,希望活动越办越好!



分类: 我的新闻 标签: RIAMeeting, 新闻
370次浏览↓

Good” Lessons on How To Fail a RIA Project——RIA项目失败的教训

2009年8月8日 powerboy 没有评论

作者 Abel Avram 译者 崔康 发布于 2009年7月22日 上午11时6分

In a presentation called Ten Ways to Ensure RIA Failure, Anthony Franco, president of EffectiveUI, gives 10 pieces of advice to those who want their RIA project to fail. Gerd Waloszek, SAP AG, wrote 18 Golden Rules for Bad User Interfaces.

EffectiveUI公司主席Anthony Franco最近做了一次名为“RIA项目失败的十种方式”的演讲,为想要RIA项目失败的人提供了十条建议。SAP AG的Gerd Waloszek则总结了“糟糕用户界面的18黄金法则”。

 These are the 10 pieces of anti-advice given by Franco explaining why they should be avoided and what should be done instead:

以下是Franco提供的十条逆向建议,并解释了为何要避免它们,而应该如何去做: 

  1. If You Want to Fail, Do Not Understand the End User – 70% of all IT projects fail because of user acceptance.
  2. If You Want to Fail, Trust Developers to Make Good Design Decisions. Developers are encouraged to make bad design decision by tracking their work using the number of features completed. When a project is going to miss the deadline, the developers focus on removing features instead of thinking at the end user
  3. If You Want to Fail, Hope for a Silver Bullet Design. Great ideas are welcome, but a great feature idea should not replace good, healthy UI design
  4. If You Want to Fail, Build for Everyone. “If a company tries to build a product for everybody, it will end up building it for nobody”
  5. If You Want to Fail, Launch & Forget. After the launch, the product needs more iterations to be polished and completed.
  6. If You Want to Fail, Do Not Define Success. Not defining success means not knowing where one is heading to.
  7. If You Want to Fail, Avoid Conflict. Conflict is not necessarily bad, because “there is no progress without conflict.” A red flag should be raised when everyone in the room agrees with an idea.
  8. If You Want to Fail, Believe You Should Not Have to Sell Your Ideas. Stakeholders should be looking to sell their idea inside their organization, and do not expect it to be accepted simply because it comes from them. This involves being ready to answer questions like: what is the ROI, what is success for this, why now, what if we do not do it now?
  9. If You Want to Fail, Plan for Perfection. One should not be planning all from the beginning and expect it to happen as planned because chances are it won’t.
  10. If You Want to Fail, Value Process Over Product. This advice can be rephrased: “If You Want to Fail, Take No Risk.” We may highly value the development process we are using, but “it means nothing to deliver a crappy product in time”, and it is easier to build the desired product with an iterative approach.

 

  1. 如果你想失败,那就不要理解最终用户——70%的IT项目失败都是由于用户可接受性出了问题。
  2. 如果你想失败,那就相信开发人员能够正确的做出设计决定。开发人员被逼迫着做出糟糕的设计,因为他们的工作量是由其所完成的功能数量决定的。当一个项目将要接近截止日期时,开发人员就会关注于删除功能而不是从最终用户的角度思考。
  3. 如果你想失败,那就期望一个银弹式的设计。好主意是值得肯定的,但一个伟大的功能建议不应该取代优秀健康的UI设计。
  4. 如果你想失败,那就满足所有人的需求。“如果一个公司试图为所有人创造一个产品,那么最后不会适用于任何人”。
  5. 如果你想失败,那就启动项目然后忘却。在项目启动之后,产品需要更多的迭代以不断完善。
  6. 如果你想失败,那就不要定义成功。不定义成功意味着不知道目标是什么。
  7. 如果你想失败,那就避免冲突。冲突未必是坏事,因为“没有冲突就没有进步”。当屋子里的所有人都赞同某种看法时,那么就要提高警惕了。
  8. 如果你想失败,那就相信不需要推销自己的想法。利益相关者应该努力在组织内部推销自己的想法,但不要期望仅仅因为来源于你就会被接受。这需要准备回答类似下面的问题:投资回报率如何?优点是什么?为什么要现在做?如果不做会怎么样?
  9. 如果你想失败,那就追求完美。不应该一开始就把所有都计划好,并期望现实会按照计划行事,因为变化无处不在。
  10. 如果你想失败,那就重视过程甚于产品。这条建议可以改写为:“如果你想失败,那就不要冒险”。我们可以非常重视开发过程,但是“按时生产一个糟糕的产品毫无意义”,通过迭代的方法构建满意的产品更轻松一些。

Following are Waloszek’s 18 golden rules along with some negative examples that should not be followed:

以下是Waloszek总结的糟糕用户界面18黄金法则,提供了负面的例子:

  1. Keep The Users Busy Doing Unnecessary Work – Let users enter data into fields only to tell them afterwards that they cannot enter data there (e.g. an application lets you enter data on holidays or weekends and tells you afterwards that you cannot work on those days).
  2. DO NOT OBEY Standards – Do not place menu items into the categories and locations they typically belong to (e.g. place “Save” in the “Edit Menu”).
  3. Make It Slow – There are nearly unlimited possibilities of making software slow. For example, you can include long lasting checks or roundtrips after each user input. Or you can force users through long chains of dialog boxes.
  4. Use Abbreviations Wherever Possible, Particularly Where There Would Be Space Enough For The Complete Term – Use “dat.” instead of “date,” “TolKy” instead of “Tolerance Key,” “NxOb” instead of “Next Object,” and many more…
  5. Educate Users In Technical Language – Always send URLs as UTF-8 (requires restart) (advanced settings in MS Internet Explorer)
  6. Hide Important And Often-Used Functionality From The Users’ View – Hide important functions in menus where users would never expect them.
  7. Make Your Application Mouse-Only – Do Not Offer Any Keyboard Shortcuts
  8. Make Using Your Application A Real Challenge – Do not warn users if actions can have severe consequences.
  9. Keep Away From End Users – Many end users have many opinions, you have one. That’s far easier and faster to implement.
  10. Spread The Message Of Bad Examples And Live It – Just follow any of the other golden rules on this page, that’s a perfect start.
  11. Take Great Care In Setting Bad Defaults: Contrary To The Users’ Expectations, Disastrous, Annoying, Useless – It’s Up To You - Set default options in Web forms so that users get unwanted newsletters or offers, have their addresses distributed, etc.
  12. Destroy The Work Context After Each System Reaction – Deselect selected screen elements after a system reaction (e.g. a round trip).
  13. Leave Out Functionality That Would Make The Users’ Life Easier – Let Them Do It The Hard (Cumbersome) Way - When users want to add items to a list, allow them to add items at the end of the list only and let them then move the items to the correct position. That is, do not offer additional functionality for inserting items at their target locations. To add some spice, introduce spurious errors that return items to the bottom when users have already moved them half-way up.
  14. Do Not Let Users Interrupt Time-Consuming And/Or Resource-Hungry Processes – Start a backup or indexing process while users are not aware of it. Make this process hard to cancel, that is, let it ignore the users’ mouse clicks and key presses.
  15. Make It Illogical – Label a button that will only prepare an operation so that users believe that it will already do the operation. Here is a real-word example: In many e-mail applications, the Forward button does not actually forward an e-mail but prepares it only for forwarding (because, for example, the recipient has still to be provided).
  16. Add A System Crash From Time To Time Or Let Applications Simply Freeze – Let editors or edit fields freeze at unforeseeable intervals so that users will not fall into the habit of saving their work frequently, which would unnecessarily waste valuable system resources.
  17. Block User Input As Often And Long As Possible – Page loading is also an appropriate event for blocking user input. Users may chat with their room mates, read the newspaper, or simply stare at the empty screen during that time.
  18. Block User Input Even If It’s Not Necessary – Blocking user input in an image browser while it updates the thumbnail images is a good example of this –there is absolutely no reason why users should not be able to scroll, select images, or initiate an action.
  1. 让客户忙于那些不必要的工作——让用户在某些控件填写数据,随后又提示他们不能在那里输入数据(比如,一个应用让你在假期或周末填写数据,随后又提示说你不能在那些天工作)。
  2. 不遵守标准——不把菜单条目放置在通常的类别和位置上(比如,在“编辑”菜单中放置“保存”按钮)。
  3. 让软件运行缓慢——有无数的可能性导致软件运行缓慢。比如,你可以在每个用户输入之后包含长时间的验证或者切换。或者你可以强制用户浏览一连串的对话框。
  4. 尽可能地使用缩写,特别是在有足够空间显示完整单词的情况下——使用“dat.”而不是“date”,“Tolky”而不是“Tolerance Key”,“NxOb”而不是“Next Object”,等等还有很多……
  5. 使用技术型语言指导用户——使用UTF-8格式发送URL(需要重启,在MS IE的高级设置里)
  6. 隐藏在用户看来重要和常用的功能——把其藏在用户永远找不到的菜单里。
  7. 让你的应用只支持鼠标——绝不提供任何键盘快捷键。
  8. 使用你的应用成为一项挑战——即使用户操作会导致严重的后果也不加以提示。
  9. 脱离最终用户——许多用户有许多的选择,你只提供一个。这倒是可以更快更简单的实现。
  10. 宣扬糟糕的示例——只需要听从本页的其他黄金法则就可以实现。
  11. 花费大量精力设置糟糕的缺省参数:与用户的期望背道而驰,缺省配置极其糟糕、令人厌恶、无用——反正由你决定——在web表单上做缺省设置使用户收到不想要的新闻或者广告,散布他们的地址等等。
  12. 在每次系统重新恢复之后都破坏工作上下文——在系统重启之后取消之前选择的屏幕元素。
  13. 忽略让用户更方便的功能——让他们很辛苦——当用户需要在列表中添加条目时,只允许他们在列表末端插入条目,然后再让用户把条目移动到正确的位置。换句话说,没有提供额外的功能用于直接将条目插入到目标位置。为了增加点情趣,当用户直接把条目移动到目标位置时,应用提示一些伪造的错误,然后把条目插入到末尾。
  14. 不让用户中断消耗时间和/或消耗资源的进程——偷偷启动一个备份或者索引进程,让用户难以取消,也就是说,无视用户的鼠标点击和键盘操作。
  15. 应用不合逻辑——添加一个准备某操作的按钮使用户确认可以做该操作了。这里有一个真实例子:在许多电子邮件应用中,“转发”按钮实际上没有真正执行转发操作,而是做转发之前的准备工作(因为,我们不得不提供收件人地址)。
  16. 时不时的来一次系统崩溃或者让应用僵死——让编辑器或者编辑域在用户事先未预料的情况下僵死,以至于用户还没有来得及保存他们的工作成果,而频繁保存的习惯会浪费宝贵的系统资源。
  17. 尽可能的阻碍用户输入——页面加载也是阻碍用户输入的好机会。在等待的时候,用户可能会与室友聊天、读报或者盯着空屏幕发呆。
  18. 阻碍用户输入,即使没有必要——阻碍用户在图片浏览器更新缩略图的时候输入就是一个很好的例子——没有任何理由阻止用户滚动、选择图片或者发起操作。 

本文来自:http://www.infoq.com/news/2009/07/Lessons-to-Fail-RIA-Project

分类: 我收集的文章 标签: flash资料
406次浏览↓

一个简单的问题——怎样使代码优化的更好呢?

2009年7月28日 powerboy 没有评论

  今天在公司,一同事问了我一个问题,我想写一个方法,当接收到任意长度整型数值的时候,我如何只保留首位,其他位全部置为0呢。我思考了几秒钟:你可以先把整型参数用String强类型转换,看看字符串的长度,这样你就能根据长度得到首位的数字,后面再根据长度补零就行了。这时他问道,可不可以不通过字符串转换,直接用整型来处理呢?于是我们开始研究:
第一种做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function encoder(num:int):int{
	var sNum:int = num;
	var count:int = 0;
	while(true){
		count++;
		sNum /= 10;
		if (sNum < 10){
			sNum = Math.floor(sNum);
			break;
		}
	}
	return decoder(sNum,count);
}
 
function decoder(num:int,step:int):int{
	var _num:int = num;
	for (var i:int = 0;i<step;i++){
		_num *= 10;
	}
	return _num;
}

经过测试,这种做法是没有问题的,但是这是不是最好的方法呢,当然不是,因为Math.floor()的原因肯定会导致效率下降一部分,有办法替换么,其实很简单,直接用int()转换一下就行了。这样是最优做法么,当然还不是,看看下面这段代码:

第二种做法:

1
2
3
4
5
6
7
8
9
10
function encoder(num:int):int{
	var i:int=num;
	var j:int=1;
	while(i>10)
	{
		j*=10;
		i=num/j;
	}
	return i*j;
}

这段代码相信大家都能看懂,它的优化在哪呢?比之前少了一个循环,当然效率会大幅提升了。我们只需再添加一个变量作为被乘数,这样就减少了一个循环。这段代码基本已经是效率很高了,但其实如果你够细心的话,仍然可以再进行优化,就是这句:i=num/j;我们把它替换成i *= .1;为什么呢?因为在计算机内部,乘运算比除运算要快。让我们看一下测试结果吧:

1
2
3
4
5
6
7
8
9
(左边是乘运算,右边是除运算,单位:毫秒)
当循环100万次时:
1028  1070
1049  1065
1045  1063
1024  1074
当循环1000万次时:
10319  10784
10467  10625
分类: actionscript3.0学习笔记, 心情驿站 标签: as3
544次浏览↓

Alternativa3D教程之三——Materials材质

2009年7月26日 powerboy 2 条评论

声明:以下文章是本人在学习过程中翻译的,如果需要复制,请务必注明出处:http://www.p-boy.cn

In this tutorial we will learn how to texture polygonal objects with Alternativa3D methods. We’ll allpy textures to a house built in previous tutorial, so if you didn’t complete it before, it is recommended to do that.

在这一节的向导中,我们将要学习如何利用Alternativa3D的方法建立多边形材质对象。我们要给上一节中的房子合成材质。因此,如果你之前还没有做完的话,建议你先将它完成。

Create new project named TexturingTutorial and place source code of lesson in it. Don’t forget to connect SWC-libraries from Alternativa3D package.

创建新项目,命名为TexturingTutorial并将源代码加入其中。不要忘记连接Alternativa3D包中的SWC库文件。

Project consists of three classes and two graphic files containing textures of bricks and roof tiling. We will use rectangular textures to reduce calculating a lil’bit. Main class, as usual, contains scene creation code and necessary event handlers. The only difference is in type of object being added, this time it is TexturedHouse class object. TexturedHouse class is a descendant of House class (created in a previous tutorial), and it redefine setMaterials() method.

项目中包含了3个类、两个包含砖和瓦盖材质的绘图文件,我们使用矩形材质来减少一些计算。通常,主类包含了建立场景的代码和必要的事件处理机制。这里唯一的区别是加入了对象类型,现在用到的是TexturedHouse类对象。TexturedHouse类是House的子类(在之前的教程中建立过),并且重新定义了setMaterials方法。

Materials and UV-coordinates——材质和UV坐标

Basic thing to get polygonal object draw in Alternativa3D is material. You can set material to every object’s surface, and one surface may contain only one material. In previous lessons we used alternativa.engine3d.materials.WireMaterial, which draws polygons’ edges. This time we’ll use with fill and texture materials.

在Alternativa3D中获得多边形对象绘制的基本对象是材质,你可以给任何对象表面设置材质,一个表面只能包含唯一的材质。在之前的教程中我们使用了alternativa.engine3d.materials.WireMaterial,它用来绘制多边形的边缘,这一次我们将填充纹理材质。

To be able for material to put texture on a face of 3D-object, it is necessary to set a way to find texture point corresponding given face point. It is achieved by setting texture coordinates for first three vertices, forming the face. Depending on given values, transformation matrix between texture plane and face plane is being formed.

为了能够把材质与3D对象纹理对应上,必须建立一种方式寻找纹理的点来符合面上的点,实现给前三个顶点设置纹理坐标来形成面。通过传值,当纹理平面和所建立的平面被创建之后,在两者之间使用matrix变形。

Coordinates in texture space are marked as U and V symbols, as a convention. Lower left texture corner has U = 0, V = 0 coordinates, upper right – U = 1, V = 1. You can see rectangular texture piece and triangle face projection to texture coordinates space, set by vertices a, b and c.

在纹理空间的坐标被U、V记号所标记,作为协议。左下角的坐标U = 0, V = 0,右上角U = 1, V = 1。你能看到给纹理坐标空间的矩形纹理和三角面投影,设为a、b、c顶点。

Texturing object——纹理对象

Let’s see how to set UV-coordinates for walls. Every wall is formed by one face. We have to set UV-coordinates for first three face’s vertices in order to apply texture. In our case they are lower-left, lower-right and upper-right wall points. Let’s agree that texture size is equal to wall size. Then, if we set wall height as H and it’s length as L, and take into account that corners’ coordinates vary from 0 to 1, and textures are rectangular, UV-coordinates of first three vertices will be (0, 0), (L/H, 0) and (L/H, 1) accordingly. Let’s take into account that walls standing along different axes will have different right side coordinates. As a result, we can prepare needed values:

我们看看如何给墙面设置UV坐标。每个墙由一个面所构建,我们必须设置UV坐标给前三个顶点来应用纹理。在我们的例子中他们是墙面的左下、右下和右上的点。我们需要纹理尺寸和墙面尺寸保持一致,然后,如果我们把墙的高度设为H、长度设为L,考虑角的坐标从0到1的改变,纹理是矩形的,前三个点的UV坐标则相应是(0, 0), (L/H, 0) 和(L/H, 1)。我们考虑墙沿着不同坐标矗立着,将会有不同的右侧坐标。因此,我们可以准备所需要的值:

1
2
3
4
5
// Texture fills the wall by the height once——纹理填充墙的高度
var wallsReferenceHeight:Number = wallsHeight;
// U-coordinates of right walls' sides. First coordinate is for northern and southern walls, second is for western and eastern ones
//墙右侧的U坐标,第一个坐标是北墙和南墙,第二个是西墙和东墙。
var wallU:Array = [houseWidth / wallsReferenceHeight, houseLength / wallsReferenceHeight];

Next step is calculating UV-coordinates for roof faces. This will be slightly more difficult because of their trapezium shape. Let’s agree that texture heigth is equal to a roof slope height. So, defining slope height as H, lower slope length as bL and upper slope length as tL, UV coordinates of slope first three vertices will be (0, 0), (bL/H, 0) and ((bL + tL)/2H, 1) accordingly. It is necessary to adjust V-coordinate of the upper edge for western and eastern sides of the roof, by dividing eastern slope height by northern one.

下一步计算屋顶面的UV坐标。这会有点不同,因为他们是梯形。我们设定纹理高度等于屋顶斜坡高度,因此,定义斜坡高度为H,底部斜坡为bL,顶部斜坡为tL,前三个顶点的UV坐标点顺序就会是 (0, 0), (bL/H, 0) 和((bL + tL)/2H,1)。 有必要用东侧和西侧斜坡来划分西侧、东侧屋顶的上部边缘,调整他们的V坐标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Northern and southern roof slopes' height——北侧和南侧屋顶高度
var snSlopeHeight:Number = getHypotenuse(roofHeight, (roofBottomLength - roofTopLength) / 2);
// Western and eastern roof slopes' height——西侧和东侧屋顶高度
var weSlopeHeight:Number = getHypotenuse(roofHeight, (roofBottomWidth - roofTopWidth) / 2);
// Texture fills whole nortern or southern slope by height——纹理填充整个北侧和南侧的高度
var roofReferenceHeight:Number = snSlopeHeight;
// U-coordinates of lower-right vertices of the roof slope. First coordinate is for northern and southern slope, second is for eastern and western one
//屋顶斜坡的右下角的U坐标。第一个坐标是北侧和南侧的斜坡,第二个坐标是东侧和西侧的斜坡。
var roofBottomU:Array = [roofBottomWidth / roofReferenceHeight, roofBottomLength / roofReferenceHeight];
// U-coordinates for upper-right vertices of the roof slope. First coordinate is for northern and southern slope, second is for eastern and western one
//屋顶斜坡的右上角的U坐标。第一个坐标是北侧和南侧的斜坡,第二个坐标是东侧和西侧的斜坡。
var roofTopU:Array = [0.5 * (roofBottomWidth + roofTopWidth) / roofReferenceHeight, 0.5 * (roofBottomLength + roofTopLength) / roofReferenceHeight];
// V-coordinates for upper vertices of the roof slope. First coordinate is for northern and southern slope, second is for eastern and western one
//屋顶斜坡的上部的V坐标。第一个坐标是北侧和南侧的斜坡,第二个坐标是东侧和西侧的斜坡。
var roofTopV:Array = [1, weSlopeHeight / roofReferenceHeight];

Now, having all necessary coordinates calculated, we can set them to faces.

现在,所有必要的坐标都计算过了,我们可以设置他们的面了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Running over plane XY quadrants, beginning from zero
//运行XY象限,从0开始
for (var i:int = 0; i < 4; i++) {
	// wall mapping——墙面映射
	// U-coordinate of wall right side——墙面右侧U坐标
	var u:Number = wallU[i & 1];
	setUVsToFace(new Point(0, 0), new Point(u, 0), new Point(u, 1), "wall_" + i);
	// roof slope mapping——屋顶斜坡映射
	setUVsToFace(new Point(0, 0), new Point(roofBottomU[i & 1], 0), new Point(roofTopU[i & 1], roofTopV[i & 1]), "roof_slope_" + i);
}
 
// upper roof side mapping——屋顶上部映射
setUVsToFace(new Point(0, 0),
	new Point(roofTopLength / roofReferenceHeight, 0),
	new Point(roofTopLength / roofReferenceHeight, roofTopWidth / roofReferenceHeight),
	"roof_top");

After setting texture coordinates we have to set texture materials to according surfaces. While creating texture material, it is necessary to define alternativa.types.Texture class instance, which is used for filling. Texture has to have graphics set, which is being get from project files in our case:

设置完纹理坐标之后我们必须根据表面设置纹理材质,在创建纹理材质时,必须定义alternativa.types.Texture类,用于填充。纹理必须拥有图形设置,可以从我们例子的项目文件中获得:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Embed(source="resources/wall.jpg")] private static const bmpWall:Class;
[Embed(source="resources/roof.jpg")] private static const bmpRoof:Class;
private static const wallTexture:Texture = new Texture(new bmpWall().bitmapData, "wall");
private static const roofTexture:Texture = new Texture(new bmpRoof().bitmapData, "roof");
 
//...
 
// Set solid fill for lower roof parts and house box
//为屋顶底部和房子体设置固定填充
setMaterialToSurface(new FillMaterial(0x666666), "roof_bottom");
setMaterialToSurface(new FillMaterial(0x666666), "box_bottom");
 
// Set texture materials for roof and walls
//为屋顶和墙面设置纹理材质
setMaterialToSurface(new TextureMaterial(wallTexture), "walls");
setMaterialToSurface(new TextureMaterial(roofTexture), "roof");

We get this house as a result.

我们得到了这所房子了。

本文出自动力男孩博客:http://www.p-boy.cn/?p=416

分类: alternativa3D, 我翻译的英文资料 标签: as3, 翻译
503次浏览↓

Alternativa3D教程之二——Building geometry建筑几何

2009年7月26日 powerboy 1 条评论

声明:以下文章是本人在学习过程中翻译的,如果需要复制,请务必注明出处:http://www.p-boy.cn

In this tutorial we will build a house using Alternativa3D methods to create objects’ geometry. Our house will be pretty simple – four walls and a roof, but we’ll get to know how to create vertices and faces, and how to form surfaces from faces’ groups.

在这个向导中我们将使用Alternativa3D方法来建立一个房子的几何对象。我们的房子非常简单——四面墙、一个房顶,但是我们将学会如何建立多个顶点和多个面,并且从多个面的组里面构建表面。

Create new project with GeometryTutorial name in your programming software, and put classes source code of this tutorial in it. Connect SWC-libraries from Alternativa3D package.

在你的程序里面创建一个新项目,命名为GeometryTutorial,然后把源文件放进去。连接Alternativa3D包中的SWC库。

We already know main class structure from previous tutorial. We set scene, put camera, and set necessary event handlers. The difference is that we put an instance of House class instead of cube primitive.

从上一节向导中我们已经知道了主类的构建,设置场景、加入摄像机和设置必要的事件处理机制。这里不同的是,我们加入一个House类来代替那个原始立方体。

House class——House类

House class is a descendant of alternativa.engine3d.core.Mesh class, which provide polygonal objects creation methods.

House类是alternativa.engine3d.core.Mesh的子类,它提供了多边形对象的构建方法。

You should create vertices in order to construct an object. To understand which vertices our object will have, lets draw house projections on a planes XY and YZ:

你应该通过建立多个顶点来构建对象。理解我们对象里存在的顶点,让我们先在XY、YZ平面画一下房子的预测:

It is easy to understand that our house has 16 vertices. Eight of them are in corners of walls, another eight are in corners of roof. Let’s create vertex identification system: vertex identyfier will consist of plane name and quadrant XY number. Quadrant names are marked on the first pic, house planes – on a second pic. So, eastern wall (east equal X axis direction here) is formed by following vertices: box_bottom_3, box_bottom_0, box_top_0, box_top_3.

很容易理解,我们的房子拥有16个顶点。8个点位于墙角,其他的8个点在房顶的角上。让我们建立顶点识别系统:顶点系统由平面名称和XY象限数字组成。象限命名标记在第一张图上,房子平面在第二张图。所以,东面的墙(东等于X轴方向)由下面的顶点来构建:box_bottom_3, box_bottom_0, box_top_0, box_top_3。

Let’s create a method to form vertices in a given house plane:

我们创建一个方法来构建房子平面的顶点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Rectangle width is along X, length along Y
//矩形的宽度沿x轴,长度沿Y轴
private function addRectangleVertices(rectWidth:Number, rectLength:Number, rectZ:Number, idPrefix:String):void {
	var hw:Number = rectWidth / 2;
	var hl:Number = rectLength / 2;
	// Add first quadrant vertex——添加第一个顶点
	createVertex(hw, hl, rectZ, idPrefix + "_0");
	// Add second quadrant vertex——添加第二个顶点
	createVertex(-hw, hl, rectZ, idPrefix + "_1");
	// Add third quadrant vertex——添加第三个顶点
	createVertex(-hw, -hl, rectZ, idPrefix + "_2");
	// Add fourth quadrant vertex——添加第四个顶点
	createVertex(hw, -hl, rectZ, idPrefix + "_3");
}

Now using this function we can easily form all necessary vertices for our house:

现在使用这个方法,我们能够很方便的构建房子所有需要的顶点:

1
2
3
4
5
6
7
8
// Create lower rectangle of the house box——构建房子体的底部矩形
addRectangleVertices(houseWidth, houseLength, 0, "box_bottom");
// Create upper rectangle of the house box——构建房子体的顶部矩形
addRectangleVertices(houseWidth, houseLength, wallsHeight, "box_top");
// Create lower rectangle of the house roof——构建房顶的底部矩形
addRectangleVertices(roofBottomWidth, roofBottomLength, wallsHeight, "roof_bottom");
// Create upper rectangle of the house roof——构建房顶的顶部矩形
addRectangleVertices(roofTopWidth, roofTopLength, wallsHeight + roofHeight, "roof_top");

Next step – faces forming. Face is defined by vertex sequence, set in counter-clockwise order (looking at face from it’s normal).

下一步——构建面。面是由顶点序列定义的,通过逆时针顺序来设置(看一下正常的面)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Walls forming faces array——构建墙面的数组
var wallsFaces:Array = [];
// Roof forming faces array——构建房顶面的数组
var roofFaces:Array = [];
// Roof bottom forming faces array——构建房顶底部的数组
var roofBottomFaces:Array = [];
 
// Create faces for every XY plane quadrant——为XY象限平面创建面
for (var i:int = 0; i < 4; i++) {
	var j:int = (i + 1) & 3;
	// Create wall face and save it in array for further surface forming
	// 创建墙面并保存在数组中以便将来构建表面
	wallsFaces.push(createFace(["box_bottom_" + i, "box_bottom_" + j, "box_top_" + j, "box_top_" + i], "wall_" + i));
	// Create roof slope face and save it in array for further surface forming
	// 创建房顶坡面并保存在数组中以便将来构建表面
	roofFaces.push(createFace(["roof_bottom_" + i, "roof_bottom_" + j, "roof_top_" + j, "roof_top_" + i], "roof_slope_" + i));
	// Create roof lower face and save it in array for further surface forming
	// 创建房顶底部并保存在数组中以便将来构建表面
	roofBottomFaces.push(createFace(["roof_bottom_" + j, "roof_bottom_" + i, "box_top_" + i, "box_top_" + j], "roof_bottom_" + i));
}
// Create upper face of the upper roof part
//创建屋顶上部的面
roofFaces.push(createFace(["roof_top_3", "roof_top_0", "roof_top_1", "roof_top_2"], "roof_top"));
// Create bottom face of the house box
//创建房子底部的面
createFace(["box_bottom_3", "box_bottom_2", "box_bottom_1", "box_bottom_0"], "box_bottom");

So, our house geometrical representation is ready. We have to set materials to different parts of the house in order to get it on screen. In Alternativa3D you set materials to surfaces, which are the sets of faces. So we have to create surfaces for our house and set them materials. Let’s do it:

我们房子的几何表现已经准备完毕,还要必须设置房子不同部分的材质以便显示在屏幕上。在Alternativa3D中给表面设置材质,需要对面进行设置。因此我们必须给房子建立表面并设置他们的材质。开始吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Create surfaces. We use early created arrays as a set of vertices.
//创建表面。我们用之前建立好的数组作为顶点的设置。
// Create wall surface——创建墙的表面
createSurface(wallsFaces, "walls");
// Create upper roof part surface——创建房顶的上表面
createSurface(roofFaces, "roof");
// Create lower roof part surface——创建房顶的下表面
createSurface(roofBottomFaces, "roof_bottom");
// Creale loweb house box surface——创建房子的下表面
createSurface(["box_bottom"], "box_bottom");
 
//Set surface materials. We use wire materials to keep it simple.
//设置表面材质。我们使用线性材质来保持它的简单性。
// Set white to the walls——设置白色的墙
setMaterialToSurface(new WireMaterial(1, 0xFFFFFF), "walls");
// Set yellow to the roof——设置黄色的房顶
setMaterialToSurface(new WireMaterial(1, 0xFFFF00), "roof");
// Set red to roof bottom——设置红色的房顶底部
setMaterialToSurface(new WireMaterial(1, 0xFF0000), "roof_bottom");
// Set green to house box bottom——设置绿色的房子底部
setMaterialToSurface(new WireMaterial(1, 0x00FF00), "box_bottom");

By combining all the code into House class and compiling it we’ll get this:

集合所有代码放入House类并且编译,我们会得到:

Conclusion——总结

Using this house example, we understood how to create polygonal geometry from the code. We’ll review materials and texturing in next tutorials.

使用这个房子的例子,我们懂得了怎样用代码创建多边形的几何图形,在下一节向导中,我们再检查一下材质和纹理。

本文出自动力男孩博客:http://www.p-boy.cn/?p=409

分类: alternativa3D, 我翻译的英文资料 标签: as3, 翻译
784次浏览↓

Alternativa3D教程之一——Hello, Alternativa3D

2009年7月26日 powerboy 2 条评论

声明:以下文章是本人在学习过程中翻译的,如果需要复制,请务必注明出处:http://www.p-boy.cn

In this tutorial we will create simple 3d-scene to understand scene building basics in Alternativa3D, step by step.

在这个向导中,我们通过建立简单的3D立方体来一步步了解基于Alternativa3D的场景构建。

So, let’s create new ActionScript Project in Flex Builder (or in other software you’re using), and name it, say, HelloAlternativa3D. Then connect all SWC-libraries from Alternativa3D package.

那么,我们在Flex Builder中新建一个ActionScript项目(或者你正在使用的其他软件),命名为HelloAlternativa3D,然后把Alternativa3D包中所有的SWC库都建立连接。

Our project will have only one file with following code inside:

我们的项目只包含一个文件,里面的代码如下:

HelloAlternativa3D.as

package {
	import alternativa.engine3d.controllers.CameraController;
	import alternativa.engine3d.core.Camera3D;
	import alternativa.engine3d.core.Object3D;
	import alternativa.engine3d.core.Scene3D;
	import alternativa.engine3d.display.View;
	import alternativa.engine3d.materials.WireMaterial;
	import alternativa.engine3d.primitives.Box;
	import alternativa.utils.FPS;
 
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
 
	[SWF(backgroundColor="#000000", frameRate="100")]
 
	public class HelloAlternativa3D extends Sprite	{
 
		private var scene:Scene3D;
		private var view:View;
		private var camera:Camera3D;
		private var cameraController:CameraController;
		private var box:Box;
 
		public function HelloAlternativa3D()	{
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		public function init(e:Event): void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
 
			// Creating scene——建立场景
			scene = new Scene3D();
			scene.root = new Object3D();
			box = new Box(100, 100, 100, 3, 3, 3);
			box.cloneMaterialToAllSurfaces(new WireMaterial(1, 0xFFFFFF));
			scene.root.addChild(box);
 
			// Adding camera and view——添加摄像机和视窗
			camera = new Camera3D();
			camera.x = 100;
			camera.y = -150;
			camera.z = 100;
			scene.root.addChild(camera);
 
			view = new View();
			addChild(view);
			view.camera = camera;
 
			// Connecting camera controller——与“摄像机控制器”建立连接
			cameraController = new CameraController(stage);
			cameraController.camera = camera;
			cameraController.setDefaultBindings();
			cameraController.checkCollisions = true;
			cameraController.collisionRadius = 20;
			cameraController.lookAt(box.coords);
			cameraController.controlsEnabled = true;
 
			// FPS display launch——FPS 运转显示
			FPS.init(stage);
 
			stage.addEventListener(Event.RESIZE, onResize);
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
			onResize(null);
		}
 
		private function onResize(e:Event):void {
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
		}
 
		private function onEnterFrame(e:Event):void {
			// User input processing——控制器的输入过程
			cameraController.processInput();
			// Scene calculating——场景计算
			scene.calculate();
		}
	}
}

We’ll look through the code later, now just try to copy it to your project, compile and run it.

稍后我们浏览一下代码,现在试着拷贝代码到你的项目中,编译、运行它。

You’ll see this (it is a link to SWF here):

你会看到这个(它是一个SWF链接地址):

You can control camera using “arrows” and WASD, Space and Shift. Mousewheel controls camera field of view (FOV).

你可以通过鼠标和按键“WASD、Space和Shift”来控制摄像机,鼠标滚轮控制摄像机的视野。

Creating scene——创建场景

Let’s review code line by line. At first we create scene and put cube primitive to it:

我们一行行的温习一下代码。首先我们建立了场景并且把一个原始的立方体加入其中:

// Create scene object. Scene is a container which have everything else inside.
//建立场景对象,它是里面一切对象的容器。
scene = new Scene3D();
// Set root object for scene hierarchy. Root object coordinate system becomes scene global coordinate system.
//为阶层式场景设置根对象,根对象的坐标系会成为场景全局坐标系。
scene.root = new Object3D();
// Create cube primitive——建立原始立方体。
box = new Box(100, 100, 100, 3, 3, 3);
// Set material which draws primitive edges——利用原始的边缘绘制材质。
box.cloneMaterialToAllSurfaces(new WireMaterial(1, 0xFFFFFF));
// Add primitive to a scene——为场景添加这个原始对象。
scene.root.addChild(box);

Adding camera——添加摄像机

Scene is ready, so we want to see result. We have to put camera on the scene and connect it to view:

场景已经准备好了,我们想看一下结果。我们必须把摄像机放入场景中并且与视窗建立连接:

// Create camera instance and set it's coordinates
//建立摄像机实例并设置坐标系。
camera = new Camera3D();
camera.x = 100;
camera.y = -150;
camera.z = 100;
// Add camera to the scene——向场景中添加摄像机
scene.root.addChild(camera);
// Create a view and connect it to the camera
//建立视窗并与摄像机建立连接
view = new View();
addChild(view);
view.camera = camera;

Camera revival——摄像机运动(不知道这样翻译是否恰当)

Let’s use controller from library. It implements basic movement and rotation camera controls, with basic collision detection:

我们使用引擎库里面的控制器,它是一个基于碰撞检测的控制摄像机基本移动、旋转的工具:

// Create controller and connect camera——建立控制器并连接摄像机
cameraController = new CameraController(stage);
cameraController.camera = camera;
// Set default control keys——设置默认控制键
cameraController.setDefaultBindings();
// Turn on camera collision detection——打开摄像机碰撞检测
cameraController.checkCollisions = true;
// Set collision detection radius for camera——设置摄像机碰撞检测弧度
cameraController.collisionRadius = 20;
// Aim camera at the cube primitive——把摄像机定位到原始立方体上
cameraController.lookAt(box.coords);
// Activate camera controls——摄像机激活控制
cameraController.controlsEnabled = true;

Latest touch——最新的接触

So, scene is ready, camera is set, we just have to “push the button”.

那么,场景已经就绪了,摄像机也设置好了,我们必须“按下按钮”。

public function HelloAlternativa3D() {
 
	//...
 
	// Initialize FPS display
	FPS.init(stage);
	// This function is for view size changes during player window changes
	addEventListener(Event.RESIZE, onResize);
	// This function enables user input processing and scene calculation every frame
	stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
	// Initial view size
	onResize(null);
}
 
private function onResize(e:Event):void {
	// Set view size equal to player window size
	view.width = stage.stageWidth;
	view.height = stage.stageHeight;
}
 
private function onEnterFrame(e:Event):void {
	// User input processing
	cameraController.processInput();
	// Scene calculating. Scene will be recalculated and all changes will be redrawed in camera.
	scene.calculate();
}

Conclusion——结论

So, we just got basic understanding about scene creation process, and showing it on screen. We’ll learn different aspects of Alternativa3D workflow in next tutorials.

我们刚才基本了解了场景的建立过程,而且显示在了屏幕上。在下一节向导中,我们会学习到Alternativa3D工作流中其他方面的知识。

本文出自动力男孩博客:http://www.p-boy.cn/?p=402

分类: alternativa3D, 我翻译的英文资料 标签: as3, 翻译
437次浏览↓

天气预报

2009年5月29日 powerboy 没有评论

弄了一个天气预报的小程序,由于安全沙箱的原因,请下载到本地打开使用。
weather.swf

分类: 我的AS3实验室 标签: as3, flex, 实验室
435次浏览↓

哈理工学子合唱《我的骄傲》

2009年5月18日 powerboy 没有评论

今天无意之间看到这个视频,突然觉得很有感触。学生们的合唱很振奋人心,让我对未来充满了希望,在此留个脚印,希望能通过我的博客和大家一起分享这份激情!!

青春,最美!哈理工学子合唱《我的骄傲》

分类: 心情驿站 标签: 心情
上一页 下一页
RSS 订阅
  • Google
  • 有道
  • 鲜果
  • 抓虾
  • My Yahoo!
  • newsgator
  • Bloglines
  • 哪吒

分类列表

  • actionscript3.0学习笔记 (16)
  • air学习笔记 (6)
  • alternativa3D (3)
  • AS2疑难杂症 (1)
  • Box2D (3)
  • flash教程 (5)
  • flex学习笔记 (3)
  • 心情驿站 (24)
  • 我收集的flash 8.0资料 (3)
  • 我收集的flash 9.0资料 (3)
  • 我收集的文章 (21)
  • 我的AS2实验室 (4)
  • 我的AS3实验室 (9)
  • 我的新闻 (17)
  • 我的相册 (6)
  • 我翻译的英文资料 (7)
  • 日语学习 (2)
  • 英语学习 (2)

最近发表

  • 浅谈工具的意义
  • “小小便利店”终于上线啦
  • 禁止按tab时焦点从flash切换到地址栏
  • 隐藏Flex滚动条的箭头和滑竿
  • 为asdoc设定example
  • 一个测试睡眠的例子
  • Box2D——入门教程
  • Box2D——shoot Demo
  • 一个由单例模式引发的问题
  • 给图像加水印

最近评论

  • 空谷的回响 发表于 一个测试睡眠的例子
    我的QQ:373131285,希... »
  • manyu 发表于 一个测试睡眠的例子
    请给我发一份吧~我也在学习~谢谢... »
  • Brooks 发表于 mp3播放器 beta2.0(开源)
    好像不能下啊,楼主给我发一份吧,... »
  • velika 发表于 Box2D——shoot Demo
    刚开始学Box2d。发一份源码来... »
  • velika 发表于 一个测试睡眠的例子
    我也想要一份源码,谢谢15337... »
  • velika 发表于 一个测试睡眠的例子
    正在学BOX2D,楼主帮了我大忙... »
  • sky 发表于 一个测试睡眠的例子
    房主,你太强了,非常值得我学习,... »
  • GGGG 发表于 Box2D——shoot Demo
    zswrhua@163.com ... »
  • kirahua 发表于 Box2D——shoot Demo
    我也正在学习用BOX2D 做游戏... »
  • sans 发表于 Box2D——shoot Demo
    楼主很厉害哦,正在学box2d呢... »
  • 下一页 »

标签云

人生感悟 吸血姬美夕 哲理 地震 奥运 学习 实验室 小樱 帕尔玛 开源API 心情 手绘 摩豆 教程 新闻 日语 明日赞歌 游戏 相册 翻译 英语 贝塞尔曲线 资料 阿兰 音乐 项目 3D adobe air as2 as3 D2 flash flash资料 flex loading RIAMeeting

存档

  • 2010年五月 (2)
  • 2010年二月 (1)
  • 2009年十二月 (2)
  • 2009年十一月 (4)
  • 2009年十月 (1)
  • 2009年九月 (2)
  • 2009年八月 (2)
  • 2009年七月 (4)
  • 2009年五月 (3)
  • 2009年三月 (3)
  • 2009年二月 (2)
  • 2009年一月 (8)
  • 2008年十二月 (10)
  • 2008年十一月 (7)
  • 2008年十月 (4)
  • 2008年九月 (7)
  • 2008年八月 (8)
  • 2008年七月 (4)
  • 2008年六月 (5)
  • 2008年五月 (11)
  • 2008年四月 (14)
  • 2008年三月 (8)
  • 2008年二月 (12)

友情链接

  • alan新浪博客
  • sunbright
  • 云风Blog
  • 嘎嘎在东京
  • 张毅君/工长君
  • 永明则名
  • 海峡IT网
  • 闪界
  • 雷晟的新浪博客
  • 鼠标炸弹

我读过的书

clicki

管理

  • 登录
置顶 WordPress
版权所有 © 2008-2010 动力男孩flash乐园 京ICP备09048608号
主题由 NeoEase 提供, 通过 XHTML 1.1 和 CSS 3 验证.Powered by WordPress