“小小便利店”终于上线啦
自从新换了工作之后,就一直没怎么再更新博客了,每天的时间都安排的满满的,今天借着推出这款小游戏的机会,赶紧踩个脚印。本来计划这款游戏半个月完成,但由于平时的工作太忙,导致我一周只有一天的开发时间,这款游戏在经历了2个多月之后才浮出水面,现在还仍然在完善中。
目前正在跟人人网合作,在此感谢跟我一起奋斗的兄弟们,没有大家的共同努力,这款游戏是永远也不会有成功的基因的。
游戏地址:http://page.renren.com/littlecvs/index
自从新换了工作之后,就一直没怎么再更新博客了,每天的时间都安排的满满的,今天借着推出这款小游戏的机会,赶紧踩个脚印。本来计划这款游戏半个月完成,但由于平时的工作太忙,导致我一周只有一天的开发时间,这款游戏在经历了2个多月之后才浮出水面,现在还仍然在完善中。
目前正在跟人人网合作,在此感谢跟我一起奋斗的兄弟们,没有大家的共同努力,这款游戏是永远也不会有成功的基因的。
游戏地址:http://page.renren.com/littlecvs/index
这里给出一个小例子,方便大家看到是否设置睡眠的区别。右上角的5个按钮代表重力方向,他们都是用向量模拟的,中间的按钮“无”代表失重状态。关于睡眠设置,默认是禁止睡眠,点击右侧按钮可以切换状态。通过观察你可以发现,当所有小球停止运动的时候,如果是禁止睡眠,当你改变重力方向的时候它们仍然可以运动,如果是允许睡眠的话,你会发现他们确实睡的跟死猪一样,一动不动。
需要看源码的朋友,请在下方留言,留下你的邮箱地址,我会尽快回复你的。
PureMVC是在基础的经典模型、视图和控制器上建立的一个轻量级的应用框架,这种开源框架是免费的,它最初是执行的ActionScript 3语言使用的Adobe Flex、Flash和AIR,现在已经移植到几乎所有主要的发展平台,目前支持两个版本框架:标准和多核,总之,标准版提供了一种简单的编码分离的方法,按照MVC设计概念。除此之外,多版本允许多个PureMVC应用运行在同一个虚拟机;模块化编程
框架概述
本文讨论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。
下面这些资料是我以前在网上收集的,具体出处已经忘了。它这里主要是针对as2说明的,发上来留作手边资料以备随时查看。不知道as3里面这些参数有没有什么变化,知道的朋友还望提醒一下。
[DOCUMENT]
size:
-width: 1 to 2880
-height: 1 to 2880
drawing extents within:
-width: -720 to document width + 720
-height: -720 to document height + 720
-grid spacing: 7.2 to 288
-frame rate: .01 to 120
-frames: 16000
-layers: 16000
-movieclip instances: 16000
-loaded movies (in levels): 16000
[MOVIECLIP]
drawing extents within:
-width: -720 to 720
-height: -720 to 720 (1440×1440)
-_xscale/_yscale values: ~ 3276800
-_alpha values: 256
-_alpha steps: ~ .4 (don’t increment _alpha below that value)
-_x/_y steps: .05 (don’t increment _x/_y below that value)
-_rotation: -180 to 180 (you can set it to values beyond these but will revert to a value in that range)
-_rotation steps: .1 (_rotation wont be seen in increments below that value)
-attached clips before drastic attachMovie speed drop: ~ 800-1000 (common in grid creation; creating new clips to attach groups of clips, like each row, to will reduce the slowdown)
[TEXT]
-characters in a textfield: ~63000 (?)
-rotation of dynamic or input textfields w/o embedded fonts or static w/ device fonts: 0 (no rotation)
-max size of POST data (loadVars and XML Objects etc): around 64k
-characters for URLs set in Character panel: 127
[SCRIPTING]
depths:
-depths of existence: -16384 to 2130690045
(createEmptyMovieClip can surpass these values in creation but not always accurate
max reliable: 2147483647, min reliable: -2147483648)
-removable depths: 0 to 1048575
-recursive function call levels: 256
-loop calls: processor dependant, 15 or 20 seconds until timeout
[MISC]
-Flash Player zoom: 2000%
-line thickness (Flash authoring): .1 to 10
-line thickness (AS): 0 to 256 (increments of 1; 0 is hairline)
-size of imported bitmap: 5×5 minimum
-shape hints: 0 to 26
之前从国外网站找的一些相关资料,给大家分享一下,这里都是针对的flash8之前版本,不知道flashCS3的这些限制有没有相关变化,知道的麻烦告诉一下,相互学习。
[DOCUMENT]
size:
-width: 1 to 2880
-height: 1 to 2880
drawing extents within:
-width: -720 to document width + 720
-height: -720 to document height + 720
-grid spacing: 7.2 to 288
-frame rate: .01 to 120
-frames: 16000
-layers: 16000
-movieclip instances: 16000
-loaded movies (in levels): 16000
[MOVIECLIP]
drawing extents within:
-width: -720 to 720
-height: -720 to 720 (1440×1440)
-_xscale/_yscale values: ~ 3276800
-_alpha values: 256
-_alpha steps: ~ .4 (don’t increment _alpha below that value)
-_x/_y steps: .05 (don’t increment _x/_y below that value)
-_rotation: -180 to 180 (you can set it to values beyond these but will revert to a value in that range)
-_rotation steps: .1 (_rotation wont be seen in increments below that value)
-attached clips before drastic attachMovie speed drop: ~ 800-1000 (common in grid creation; creating new clips to attach groups of clips, like each row, to will reduce the slowdown)
[TEXT]
-characters in a textfield: ~63000 (?)
-rotation of dynamic or input textfields w/o embedded fonts or static w/ device fonts: 0 (no rotation)
-max size of POST data (loadVars and XML Objects etc): around 64k
-characters for URLs set in Character panel: 127
[SCRIPTING]
depths:
-depths of existence: -16384 to 2130690045
(createEmptyMovieClip can surpass these values in creation but not always accurate
max reliable: 2147483647, min reliable: -2147483648)
-removable depths: 0 to 1048575
-recursive function call levels: 256
-loop calls: processor dependant, 15 or 20 seconds until timeout
[MISC]
-Flash Player zoom: 2000%
-line thickness (Flash authoring): .1 to 10
-line thickness (AS): 0 to 256 (increments of 1; 0 is hairline)
-size of imported bitmap: 5×5 minimum
-shape hints: 0 to 26
最近正在学习用flashDevelop开发flash程序,其中遇到一个问题,我们在flashIDE中测试程序的时候,可以直接通过trace输出结果,然而在flashDevelop中却没有任何提示,幸好得到好心人指点,这里分享给大家:
1、建立一个xtrace类:
2、将上面这个类文件复制到<盘符:>FlashDevelop\FirstRun\Library\AS3\classes\org\flashdevelop\utils下;
3、在程序中import org.flashdevelop.utils.xtrace;
4、在想要输出数据的地方写xtrace()就可以了,括号中可以写你想要输出的变量的值。
Mime-Typ Dateiendung(en) Bedeutung
application/acad *.dwg AutoCAD-Dateien (nach NCSA)
application/applefile AppleFile-Dateien
application/astound *.asd *.asn Astound-Dateien
application/dsptype *.tsp TSP-Dateien
application/dxf *.dxf AutoCAD-Dateien (nach CERN)
application/futuresplash *.spl Flash Futuresplash-Dateien
application/gzip *.gz GNU Zip-Dateien
application/listenup *.ptlk Listenup-Dateien
application/mac-binhex40 *.hqx Macintosh Binär-Dateien
application/mbedlet *.mbd Mbedlet-Dateien
application/mif *.mif FrameMaker Interchange Format Dateien
application/msexcel *.xls *.xla Microsoft Excel Dateien
application/mshelp *.hlp *.chm Microsoft Windows Hilfe Dateien
application/mspowerpoint *.ppt *.ppz *.pps *.pot Microsoft Powerpoint Dateien
application/msword *.doc *.dot Microsoft Word Dateien
application/octet-stream *.bin *.exe *.com *.dll *.class Ausführbare Dateien
application/oda *.oda Oda-Dateien
application/pdf *.pdf Adobe PDF-Dateien
application/postscript *.ai *.eps *.ps Adobe Postscript-Dateien
application/rtc *.rtc RTC-Dateien
application/rtf *.rtf Microsoft RTF-Dateien
application/studiom *.smp Studiom-Dateien
application/toolbook *.tbk Toolbook-Dateien
application/vocaltec-media-desc *.vmd Vocaltec Mediadesc-Dateien
application/vocaltec-media-file *.vmf Vocaltec Media-Dateien
application/x-bcpio *.bcpio BCPIO-Dateien
application/x-compress *.z -Dateien
application/x-cpio *.cpio CPIO-Dateien
application/x-csh *.csh C-Shellscript-Dateien
application/x-director *.dcr *.dir *.dxr -Dateien
application/x-dvi *.dvi DVI-Dateien
application/x-envoy *.evy Envoy-Dateien
application/x-gtar *.gtar GNU tar-Archiv-Dateien
application/x-hdf *.hdf HDF-Dateien
application/x-httpd-php *.php *.phtml PHP-Dateien
application/x-javascript *.js serverseitige JavaScript-Dateien
application/x-latex *.latex Latex-Quelldateien
application/x-macbinary *.bin Macintosh Binärdateien
application/x-mif *.mif FrameMaker Interchange Format Dateien
application/x-netcdf *.nc *.cdf Unidata CDF-Dateien
application/x-nschat *.nsc NS Chat-Dateien
application/x-sh *.sh Bourne Shellscript-Dateien
application/x-shar *.shar Shell-Archiv-Dateien
application/x-shockwave-flash *.swf *.cab Flash Shockwave-Dateien
application/x-sprite *.spr *.sprite Sprite-Dateien
application/x-stuffit *.sit Stuffit-Dateien
application/x-supercard *.sca Supercard-Dateien
application/x-sv4cpio *.sv4cpio CPIO-Dateien
application/x-sv4crc *.sv4crc CPIO-Dateien mit CRC
application/x-tar *.tar tar-Archivdateien
application/x-tcl *.tcl TCL Scriptdateien
application/x-tex *.tex TEX-Dateien
application/x-texinfo *.texinfo *.texi TEXinfo-Dateien
application/x-troff *.t *.tr *.roff TROFF-Dateien (Unix)
application/x-troff-man *.man *.troff TROFF-Dateien mit MAN-Makros (Unix)
application/x-troff-me *.me *.troff TROFF-Dateien mit ME-Makros (Unix)
application/x-troff-ms *.me *.troff TROFF-Dateien mit MS-Makros (Unix)
application/x-ustar *.ustar tar-Archivdateien (Posix)
application/x-wais-source *.src WAIS Quelldateien
application/x-www-form-urlencoded HTML-Formulardaten an CGI
application/zip *.zip ZIP-Archivdateien
audio/basic *.au *.snd Sound-Dateien
audio/echospeech *.es Echospeed-Dateien
audio/tsplayer *.tsi TS-Player-Dateien
audio/voxware *.vox Vox-Dateien
audio/x-aiff *.aif *.aiff *.aifc AIFF-Sound-Dateien
audio/x-dspeeh *.dus *.cht Sprachdateien
audio/x-midi *.mid *.midi MIDI-Dateien
audio/x-mpeg *.mp2 MPEG-Dateien
audio/x-pn-realaudio *.ram *.ra RealAudio-Dateien
audio/x-pn-realaudio-plugin *.rpm RealAudio-Plugin-Dateien
audio/x-qt-stream *.stream -Dateien
audio/x-wav *.wav Wav-Dateien
drawing/x-dwf *.dwf Drawing-Dateien
image/cis-cod *.cod CIS-Cod-Dateien
image/cmu-raster *.ras CMU-Raster-Dateien
image/fif *.fif FIF-Dateien
image/gif *.gif GIF-Dateien
image/ief *.ief IEF-Dateien
image/jpeg *.jpeg *.jpg *.jpe JPEG-Dateien
image/tiff *.tiff *.tif TIFF-Dateien
image/vasa *.mcf Vasa-Dateien
image/vnd.wap.wbmp *.wbmp Bitmap-Dateien (WAP)
image/x-freehand *.fh4 *.fh5 *.fhc Freehand-Dateien
image/x-portable-anymap *.pnm PBM Anymap Dateien
image/x-portable-bitmap *.pbm PBM Bitmap Dateien
image/x-portable-graymap *.pgm PBM Graymap Dateien
image/x-portable-pixmap *.ppm PBM Pixmap Dateien
image/x-rgb *.rgb RGB-Dateien
image/x-windowdump *.xwd X-Windows Dump
image/x-xbitmap *.xbm XBM-Dateien
image/x-xpixmap *.xpm XPM-Dateien
message/external-body Nachricht mit externem Inhalt
message/http HTTP-Headernachricht
message/news Newsgroup-Nachricht
message/partial Nachricht mit Teilinhalt
message/rfc822 Nachricht nach RFC 1822
model/vrml *.wrl Visualisierung virtueller Welten
multipart/alternative mehrteilige Daten gemischt
multipart/byteranges mehrteilige Daten mit Byte-Angaben
multipart/digest mehrteilige Daten / Auswahl
multipart/encrypted mehrteilige Daten verschlüsselt
multipart/form-data mehrteilige Daten aus HTML-Formular (z.B. File-Upload)
multipart/mixed mehrteilige Daten gemischt
multipart/parallel mehrteilige Daten parallel
multipart/related mehrteilige Daten / verbunden
multipart/report mehrteilige Daten / Bericht
multipart/signed mehrteilige Daten / bezeichnet
multipart/voice-message mehrteilige Daten / Sprachnachricht
text/comma-separated-values *.csv komma-separierte Datendateien
text/css *.css CSS Stylesheet-Dateien
text/html *.htm *.html *.shtml -Dateien
text/javascript *.js JavaScript-Dateien
text/plain *.txt reine Textdateien
text/richtext *.rtx Richtext-Dateien
text/rtf *.rtf Microsoft RTF-Dateien
text/tab-separated-values *.tsv tabulator-separierte Datendateien
text/vnd.wap.wml *.wml WML-Dateien (WAP)
application/vnd.wap.wmlc *.wmlc WMLC-Dateien (WAP)
text/vnd.wap.wmlscript *.wmls WML-Scriptdateien (WAP)
application/vnd.wap.wmlscriptc *.wmlsc WML-Script-C-dateien (WAP)
text/xml-external-parsed-entity extern geparste XML-Dateien
text/x-setext *.etx SeText-Dateien
text/x-sgml *.sgm *.sgml SGML-Dateien
text/x-speech *.talk *.spc Speech-Dateien
video/mpeg *.mpeg *.mpg *.mpe MPEG-Dateien
video/quicktime *.qt *.mov Quicktime-Dateien
video/vnd.vivo *viv *.vivo Vivo-Dateien
video/x-msvideo *.avi Microsoft AVI-Dateien
video/x-sgi-movie *.movie Movie-Dateien
workbook/formulaone *.vts *.vtts FormulaOne-Dateien
x-world/x-3dmf *.3dmf *.3dm *.qd3d *.qd3 3DMF-Dateien
x-world/x-vrml *.wrl VRML-Dateien
一、需求决定功能
下面是最终演示效果:
这里我之所以先把演示效果放到第一位,目的是为了让大家看过之后先有个印象,这样当我后面叙述到某些东西的时候,大家就不会那么陌生,不知所云了。
其实设计这个效果的初衷,是想实现一种类似Ajax的效果,像大家经常在视频网站中见到的那样,当你看完一部片子之后,可以实时对其进行评分、留言等等,所见即所得。这些flash当然也做得到,我们完全可以通flash+js来实现。但是我没有把它和js交互的部分放上来,这里我只讲解flash展现的效果部分。可是如果单纯把信息罗列出来,就和普通页面没什么分别了,没有把flash的特点发挥出来,所以我想要在效果上显出她的与众不同。这个程序里面所设计到的功能在题目当中已经给出,但其实还有很多,我们完全可以把这个小程序的功能做的很强大,不过这要看一个人的思维方式和创意了,而我就作为抛砖引玉吧。
这里面的元素可以完全用AS来写,我这里为了方便,所以偷了个小懒,有的元件是用图形画的。
二、设计思路
这个程序虽然不大,但是涉及到的知识点还是挺多的,那么在设计前期我们应该做些什么呢?Lee Brimelow说过一句话,你是第一个能够“看到”这个作品的人,因为在你设计之前,这个实体的最终形态已经呈现在你的脑海中了。从这一点上我们可以看出,编程其实是次要的,关键是前期的策划与设计,如果失误的话,会影响到整个程序进度,你可能会频繁的去修改甚至是重写代码。另一方面,我们的程序要能给用户带来良好的体验,不能只单单自己感觉好用就行,毕竟你是设计者。
对于此程序来说,我希望能够尽自己所能来给用户提供便利,所以首先一点,自动滚屏和手动滚屏是必须的,因为这是两种不同的需求。其次是投票窗口的设计,最初我想到的是像传统的制作方法一样,点击查看之后弹出一个窗口来显示投票结果,你可以关闭,也可以选择查看其他项目的投票结果来更新这个窗口。但是,我想到了一点,这样做缺乏对比性,因为一次只能显示一个窗口,能不能改善一下这种状况呢,其实也不难办到,我们可以把显示结果做成MINI型,就是很小巧的那种,让他们在不同的选项上可以自由弹出,互不干扰,这样用户可以自由选择查看投票结果。这样做,其实就是给用户提供了方便,我们要在细节上多下一些功夫。
不过这个程序目前有一点不太完善的地方,如果只有20多个图像展示区域,效果是可以接受的,但是如果太多了,稍微滑动滚动条,一下就会过去好几张图片,这样带来的用户体验就不是很好,他们可能会因此频繁的调整而失去耐心。解决的方法不是没有,我首先想到了两种。第一种,就是加入分页,我们可以设定一次最多显示20张,然后通过点击分页来进行切换,这样用户是可以接受的;第二种,就是加入快捷键,可以让用户通过键盘切换到不同的显示区,也可以通过方向键来调整滚动的距离。其实解决方案有很多种,我想大家也有自己不同的解决途径,这部分扩展程序我没有写,大家最好能够自由发挥。但是不管怎样,我们都要始终把握住一点
———— 尽最大可能给用户提供方便,以用户体验为中心!
三、双击剖析
对于一般的老手来说,“双击”的实现已经不再陌生,我在这里简单的提一下思路,给更多的学习者以参考,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //双击判断事件; if (!click) { timer = getTimer()/1000; click = true; } else { timer2 = getTimer()/1000; _root.test2 = timer2-timer; if (timer2-timer<0.25) { if (the_scroll == true) { delete scroll.bar.onEnterFrame; the_scroll = false; scroll.news.gotoAndStop(2); } else { the_scroll = true; scroll.news.gotoAndStop(1); Scroll(); } } else { timer = getTimer()/1000; } } |
双击的实现主要就是判断连续两次单击时间的间隔,在程序刚开始执行的时候,当鼠标第一次单击时,会进入第一个分支语句,目的就是给timer赋初值,这样,后面再次按下鼠标的时候,就可以用第二次的时间timer2减去timer来计算二者时间间隔,当小于我们设定的值时,则双击成立,再判断滚动是否暂停,否则将第二次单击的值作为timer保存起来,以便于侦听下一次的鼠标操作。
四、色彩变换与滚动的实现
其实这个效果非常的简单,你只需要记住两点就能搞定:
1、通过Transform类来收集颜色转换的相关数据;
2、用ColorTransform类对颜色进行处理。
这样当鼠标移入或者移出图像的时候,才能看到色彩转化的效果。其实当我讲到这里的时候,你已经完全可以编写出此效果,因为它的原理非常简单。不过毕竟教程是以“教”为主,这里我给出了具体实现的方法,不过我仍然希望在你看过之后,能够仔细思考一下这段代码,你会很惊奇的发现,原来很多类似的效果都是触类旁通的。
这里我只以鼠标移入为例,因为其他地方都是一样的,多说无益。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | //把亮度偏移加载到当前对象上 var trans:Transform = new Transform(this); //偏移步长为15 var step:Number = 15; //偏移量 var offset:Number = 0; var GT:Number = null; this.onEnterFrame = function() { offset += step; if (offset>=150||offset<0) { step *= -1; } picColor(trans,offset); }; // 亮度偏移 function picColor(t:Transform, v:Number) { var bt:ColorTransform = new ColorTransform(1, 1, 1, 1, v, v, v, v); t.colorTransform = bt; } |
通过上面的if语句,判断色彩偏移量的状态,如果超过了预设范围之后,就使其步长值取相反数,这样它的值就会在这个区间内不停的变换。然后把每次变化的偏移量传给picColor,让它通过这个值来对色彩进行改变, new ColorTransform(1, 1, 1, 1, v, v, v, v)是指在初始化颜色不改变的情况下,调整红、绿、蓝、alpha四个颜色通道的偏移量,这里面我统一用一个变量v来代替,表明当这些数值同时改变的话,会产生暗淡或者高光的效果。
对于滚动效果,egoldy的教程已经讲的很详细了,一个是滚动公式的应用,另一个是鼠标中键onMouseWheel的应用。不过这里我想强调一点,就是对于细节的处理问题。如果当前状态为自动滚动的时候,滚动条也是随之移动的,此时如果按下鼠标拖拽滚动条,虽然图像也能随之移动,但此时如果不释放鼠标(即触发release事件),滚动条就会移动到鼠标外,而不是停留在鼠标的位置,这样用户在使用的时候,就会有一种“失灵”的感觉。其实这是个很小的问题,解决也很容易,只要移除onEnterFrame事件就可以了,但是从另外一个角度也说明了细节决定成败的道理。
五、整合
这部分整合的功能就是投票显示,主要就是通过xml来获取服务器端的数据,当然如果你对js比较熟悉的话,也可以通过js来实现。我把算法简化了很多,这里我把思路简单的介绍一下。假设我们把总共所有投票的人数进度条设为100%的话,那么“当前投票”和“投票约占百分比”的进度条长度其实是一样的,所以只要进度条随着百分比(当前投票数/总共投票数)的增加而增加就可以了。但是显示总共投票数的时候进度条有个问题,因为不管总共投票人数有多少,进度条都应该保持100%长度以显示总投票数,可是我想要在进度条增长的时候,后面的数字也随之变化,当人数太多的时候,进度条不断增长所需要的时间就会延长,这样效果就不是很好了。所以我的解决方法就是,让显示的总投票数从高位到地位数字依次变化。比如投票总数是5678,我设一个变量votenumtotal_i,让它从0开始累加,再设一个votenumtotal来记录投票总数,然后判断votenumtotal-votenumtotal_i的值,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //显示总共投票数 if (votenumtotal_i<=view.votenumtotal){ this._parent.board.C_votenumtotal.text=votenumtotal_i; if (view.votenumtotal-votenumtotal_i>10000){ thearea=4; }else if (view.votenumtotal-votenumtotal_i>1000){ thearea=3; }else if (view.votenumtotal-votenumtotal_i>100){ thearea=2; }else if (view.votenumtotal-votenumtotal_i>10){ thearea=1; }else if (view.votenumtotal-votenumtotal_i>0){ thearea=0; } switch (thearea){ case 0:votenumtotal_i+=1;break; case 1:votenumtotal_i+=10;break; case 2:votenumtotal_i+=100;break; case 3:votenumtotal_i+=1000;break; case 4:votenumtotal_i+=10000;break; } } |
当差值大于10000的时候votenumtotal_i每次加10000,大于1000的时候votenumtotal_i每次加1000以此类推,这样就可以实现从高位到地位数字不断变化的效果。唯一的缺点就是,数字变化的效果瞬间显示完毕,而不能随着进度条的增加而增加。当然,如果谁有更好的解决方法,欢迎提供思路。
六、总结
在编程的整个过程中,我个人的感觉是:最枯燥的事情就是写代码,最有趣的事情仍然是写代码。这句话看似很矛盾,其实则不然。俗话说的好,万事开头难,但是一个好的开始就是成功的一半,所以我们多花一些时间在前期的策划和准备上是很值得的。当你把一些事情都考虑好了之后,剩下的事情就水到渠成了,写起代码思路清晰,而且效率也高,等待着你的就是品尝胜利的果实。
人往往是很守旧的,一但某种思想形成一种习惯,就很难再去改变、再去接受新的东西,这会在某种程度上住一个人的潜力。改变一个人的习惯真的很难吗?根据美国科学家对人类的调查结果表明,两个星期完全可以给人重塑一个新的习惯。这能说明什么呢?其实主要原因还是来自于人类的本性——惰性。
一个有惰性的人我们通常叫做他懒人,但是有一句很经典的话:世界是由懒人创造的,由于懒的走路,所以有了汽车;由于懒得上楼,所以有了电梯……正是由于懒人的思想,才推动了社会的发展。很奇怪吗?可事实确实如此,看来懒人往往又是很勤奋的人。其实,这里的”懒人”都是聪明人的代名词,他们的想法能够帮助提高人们的生活效率,他们能够把生活中常见的现象和事物进行总结和归纳,然后产生新的事物,一些常人想都不敢想的事物。所以说,我们不要做真正意义上的懒人,只要你经常善于总结和思考,一样能够创造出更好的东西。
此次总结没有讲解技术方面的东西,而是思想上的总结。
写完程序之余,突然有此一念,因此随笔而写,作为总结以记之。
———————–PowerBoy
2007年12月20日 凌晨
一、建立分页从何下手?
在得到ego老大的支持和其他朋友的鼓励下,通过一段时间的准备,写了这篇继“关于图片切换的制作方法”之后的第二篇教程,之前我在网上看过一些人写的例子,但总感觉像是一个模子刻出来的,这其中不难发现肯定存在着copy,当然我不反对这样。不过在这里我想先岔开个话题,现在网上公开的源代码很多,你完全可以把别人的东西拿来修改然后使用,但是要记住一点,如果代码里面,你编写的东西没有超过50%以上的话,千万别说这个代码是你写的,因为这是做人最基本的道德问题,而且对于学习者来说这也是自欺欺人,水平永远都停留在这个阶段,要知道自己写一遍代码,学到的东西可能不光是代码本身,更重要的是学会了思考,很多人问我同样一个问题,想做一个效果该从哪做起呢?我的回答是“思考+实践”。我通过自己学习,总结出来的经验就是,学习编程其实就是学的一种思想,代码只是一种实现的手段,千万不要为了学代码而学代码。就拿这个贴子的话题来说吧,当你想写一个分页程序的时候,你首先考虑到的是什么呢?我的建议是:
1、先将外部数据调入数组(为什么要使用数组,后面会讲到);
2、设定每页需要显示多少,至少需要这些自定义参数:行、列、(数组)元素总数;
3、将数组中的数据有选择性的输出;
4、增加显示特效。
(注:本教程以算法为主,代码不作为主要内容,因为方法不唯一)
下面我们就从第一步做起,有些人可能不习惯使用数组,但是它的优点真的很多,管理方便,而且能帮助我们提高效率,寻找它们就像寻找数据库的记录一样,想要什么数据一目了然。下面这段代码就是把xml节点数据读入数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Load = function () { var intro = myXML.firstChild; var len:Number = intro.childNodes.length; for (i=0; i<len; i++) { box[i] = new Array(); box[i][0] = intro.childNodes[i].attributes.spath; box[i][1] = intro.childNodes[i].attributes.path; box[i][2] = intro.childNodes[i].attributes.url; box[i][3] = intro.childNodes[i].attributes.title; box[i][4] = intro.childNodes[i].attributes.description; } record = len; pages = Math.ceil(len/total); if (i == len) { refreshmenu(page); } }; |
读取结束以后,下面才是核心问题,如何将图片输出呢,我们可以根据自己预设的行、列参数来让它自动输出,但是单纯这样输出的话是不会分页的,所以我们要从中针对行、列分别进行一下判断,代码如下:
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 27 28 29 30 31 32 33 | refreshmenu = function (page) { var i:Number = 0; var j:Number = 0; var num:Number = 0; copy = function () { if (i<hang) { if (j<lie) { if (total1<=total) { CreateClip(i, j, num, box[num+(page-1)*total][0], box[num+(page-1)*total][1], box[num+(page-1)*total][2], box[num+(page-1)*total][3], box[num+(page-1)*total][4]); thecount = ((page-1)*total)+count; count++; j++; num++; total1++; } if (total1>total) { total1 = 1; count = 0; i = 0; j = 0; nb.gotoAndStop(1); pb.gotoAndStop(1); clearInterval(control); ListMenu(); } } else { j = 0; i++; } } }; var control = setInterval(copy, 50); }; |
上面这段代码没有什么难点,都是一些计数器之类的,关键是上面CreateClip自定义函数,通过它把数组里面的数据和图片的计数器变量读取出来,然后对其进行有选择性的输出。
这里是自定义函数的内部结构:
1 2 3 4 5 6 7 8 9 10 | CreateClip = function (i:Number, j:Number, num:Number, thespath:String, thepath:String, theurl:String, thetitle:String, thedescription:String) { var movie = mc.createEmptyMovieClip("mc"+i+j, num); dx = movie.attachMovie("tu", "tu1", 1); dx._x += (dx._width+feng_x)*j+x; dx._y += (dx._height+feng_y)*i+y; dx.msg.selectable = false; dx.msg.text = thetitle; dx.imgs = thespath; dx.link = theurl; }; |
上面有两个变量没有用到(thepath、 thedescription),这是为了以后扩展用的,比如做个图片放大读取或者相关信息描述之类的都可以,这里相当于个接口,但是因为他们所涉及到的内容和本教程无关,所以这里不作为研究对象(这里可以当他们不存在)。其中每个图片(dx)里面的第一帧也有一些代码,不过只是限制图片大小和加载图片的简短代码,老声常谈的东西这里就不赘述了。
之后我们再继续添加关于翻页按钮输出:
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 27 28 29 30 31 32 33 34 35 | ListMenu = function () { var menupath = mc.menu.menu1; menu._x = x+30; menu_y = y+hang*(dx._height+feng_y); menu._y = menu_y; menupath.up.onRelease = function() { if (page == 1) { } else { page--; refreshmenu(page); } gotoAndStop(1); }; menupath.down.onRelease = function() { if (page == pages) { } else { page++; refreshmenu(page); } gotoAndStop(1); }; menupath.makesure.onRelease = function() { if ((menupath.jump.text>pages) || (menupath.jump.text<1)) { menupath.jump.text = page; makesure = true; } else { page = menupath.jump.text; refreshmenu(page); } }; mc.menu.menu1.totaltxt.selectable = false; mc.menu.menu1.pagetxt.selectable = false; mc.menu.menu1.totaltxt.text = "--共"+pages+"页--"; mc.menu.menu1.pagetxt.text = "--第"+page+"页--"; }; |
这样,一个分页展示的雏形基本就已经出来了,下面给出了源文件fenye.rar,但是这样程序是不健全的,我们可以从中看到很多的不完善:
1、最后一页图片出现undefined;
2、狂点翻页按钮,显示会出现问题,因为图片是循环输出的,有时间间隔,当还没完全输出的时候,又点击了另外一组图片,所以显示就会错误了;
在下面我们就继续来分析如何解决上述bug。
fenye.rar
二、如何完善你的程序?
什么样的程序才能算是完善呢,首先你的程序的bug要全部得到解决,所以你可以让别人来帮你一起测试,做到万无一失;第二点是你的程序功能是否可以扩展,如果我们需要做很多程序,而其中有些东西是可以再利用的,如果前期工作没有做好的话,那么很可能你要把代码再重新写一遍,做重复性的工作,所以我们在写程序的时候,要多想想后面你会碰到什么样的问题以方便将来程序的扩展;还有一点,你的想法是否“另类”,能够让你的效果看上去与众不同。
下面我们就来一步步解决这些问题。针对第一点,程序中出现的undefined是因为他们是多余的,没有数据传输过去,所以我们应该想办法把他们屏蔽掉。
我做了如下修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 | if (total1<=total) { if (total1<=flag) { CreateClip(i, j, num, box[num+(page-1)*total][0], box[num+(page-1)*total][1], box[num+(page-1)*total][2], box[num+(page-1)*total][3], box[num+(page-1)*total][4]); thecount = ((page-1)*total)+count; count++; j++; } else { var movie = mc.createEmptyMovieClip("mc"+i+j, num); movie.removeMovieClip(); } num++; total1++; } |
我新引入了一个变量flag,是用来判断本页应该显示几张图片的,var movie = mc.createEmptyMovieClip(”mc”+i+j, num);movie.removeMovieClip();
这两句是用来屏蔽undefined用的。
关于防止用户狂点按钮,我们可以采取当图片正在显示过程中,让按钮失效的做法,再引入一个变量makesure,把按钮代码做如下修改:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | menupath.up.onRelease = function() { if (makesure == true) { makesure = false; if (page == 2) { menupath.up._visible = false; } else { menupath.up._visible = true; menupath.down._visible = true; } page--; refreshmenu(page); } gotoAndStop(1); }; menupath.down.onRelease = function() { if (makesure == true) { makesure = false; if (page == pages-1) { menupath.down._visible = false; } else { menupath.up._visible = true; menupath.down._visible = true; } page++; refreshmenu(page); gotoAndStop(1); } }; menupath.makesure.onRelease = function() { if (makesure == true) { makesure = false; if ((menupath.jump.text>pages) || (menupath.jump.text<1)) { menupath.jump.text = page; makesure = true; } else { page = menupath.jump.text; refreshmenu(page); } if (page == 1) { menupath.up._visible = false; menupath.down._visible = true; } else if (page == pages) { menupath.up._visible = true; menupath.down._visible = false; } else { menupath.up._visible = true; menupath.down._visible = true; } } }; |
现在来讲,一个分页展示就已经完成了,测试一下吧~~!见(fenye1.rar)
******************************************************************
(进阶教程——-图片飞入)
现在网站上流行的主要是一些比较动感的特效,在这里,我做的是让每张图片按先后次序连续飞入场景的特效,代码如下:
1 2 3 4 5 6 7 | PicIn = function () { for (i=0; i<hang; i++) { for (j=0; j<lie; j++) { mc["mc"+i+j]._y += (InTarget-mc["mc"+i+j]._y)*0.2; } } }; |
因为之前我们已经将每个图片在场景中实例化了,所以我们可以利用他们来做出一些效果出来。
这里我突然又有了一个想法,如果能让翻页按钮随着行高的不同而跟随的变化的话,感觉也蛮不错的,但是怎样让他知道当前的高度是多少呢?经过思考,我的算法是这样的:
1 2 3 4 5 | if (page == pages) { menu_y = y+Math.ceil(flag/lie)*(dx._height+feng_y); } else { menu_y = y+hang*(dx._height+feng_y); } |
经过判断,如果没有到达最后一页的话,高度直接按照规定的行高就可以,否则把当前的行高重新计算再赋值。这样,图片飞入的效果就实现了。代码不算难,关键还是一个思路的问题。
(见fenye2.rar)
fenye1.rar
fenye2.rar
三、我的创意我作主
下面是我加的一些效果,供大家参考。我个人认为,一个好的设计者,最重要的因素就是创造力。
这个程序的扩展性很好,只需很少改动甚至只修改1~2处地方,就可以应用在其他方面,比方说新闻列表,mp3、视频播放器列表等等,因为我已经有成功案例了,节省了大量的时间开发重复性工作,所以这里拿出来和大家一起分享。记住:因为你们快乐,所以我很快乐~!
方法总结:
1、利用数组保存临时数据;
2、通过判断语句的嵌套,达到限制每页图片输出的目的;
3、CreateClip传值方法;
4、缓冲移动效果的运用。
附加小程序:
“动态文本框的调用”:也许大家已经注意到了,范例中的题目是通过调用TextField类来实现的,如果不了解这方面使用方法的话,上面的源文件已经给出了范例的应用,作为你学习本教程的额外收获吧~!