1

我刚开始用 AS3 编码,能从专家那里得到一些反馈真的很棒;关于我的编码风格,我做错的事情,我可以改进的事情,最佳实践等等......另外,如果你有一些额外的提示或技巧,那就太好了。

这是我的第一个 AS3 代码,花了我 5 个小时,噗:

package {

    import flash.display.Sprite;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.*;
    import flash.errors.*;
    import flash.display.MovieClip;
    import gs.*;
    import flash.display.Loader;
    import net.stevensacks.preloaders.CircleSlicePreloader;

    public class FlatSelector extends MovieClip {

        var preloader:CircleSlicePreloader = new CircleSlicePreloader();
        var imageLoader:Loader = new Loader();
        var globalXML:XML;

        public function FlatSelector() {
            stage.addEventListener(Event.ENTER_FRAME, init);
            building.alpha = 0;
        }

        public function init(event:Event):void {
            stage.removeEventListener(Event.ENTER_FRAME, init);
            var loader:URLLoader = new URLLoader(); 
            loader.addEventListener(Event.COMPLETE, handleXML);
            loader.load(new URLRequest('http://localhost/boligvelger/flats.xml'));
            TweenLite.to(building, 2, {alpha:1});
            TweenLite.to(building.flat, 2, {alpha:0.5, tint:0x00FF23});
            //var myTween:TweenLite = TweenLite.to(mc, 1, {x:200});
            //var myTween:TweenLite = new TweenLite(mc, 1, {x:200});
        }

        public function handleXML(e:Event):void {
            var xml:XML = new XML(e.target.data);
            globalXML = xml;
            for (var i:Number = 0; i < xml.leiligheter.leilighet.length(); i++) {
                var flatName = xml.leiligheter.leilighet[i].navn;
                if(movieClipExists(building[flatName])) {
                    building[flatName].addEventListener(MouseEvent.MOUSE_UP, flatMouseClick);
                    building[flatName].addEventListener(MouseEvent.MOUSE_OVER, flatMouseOver);
                    building[flatName].addEventListener(MouseEvent.MOUSE_OUT, flatMouseOut);
                    building[flatName].alpha = 0;
                    TweenLite.to(building[flatName], 2, {alpha:0.5, tint:0x00FF23});
                }
            }
        }

        public function showInfoBox():void {

        }

        public function showFlat(flatName:String):void {
            trace('flatName: '+flatName);
            trace('flat shown');
            var imageURL;
            for (var i:Number = 0; i < globalXML.leiligheter.leilighet.length(); i++) {
                if(globalXML.leiligheter.leilighet[i].navn == flatName) {
                    imageURL = globalXML.leiligheter.leilighet[i].plantegning;
                }
            }
            trace(imageURL);
            loadImage(imageURL);
        }

        public function showBuilding():void {
            TweenLite.to(imageLoader, 0.5, {alpha:0, onComplete:function(){
                removeChild(imageLoader);           
            }});
        }

        public function flatMouseClick(e:MouseEvent):void {
            trace('clicked');
            TweenLite.to(building, 0.7, {alpha:0, onComplete:showFlat(e.target.name)});
            TweenLite.to(building, 2, {y:stage.stageHeight, overwrite:0});
        }

        public function flatMouseOver(e:MouseEvent):void {
            TweenLite.to(building[e.target.name], 0.5, {tint:0x62ABFF});
            building[e.target.name].buttonMode = true;
        }

        public function flatMouseOut(e:MouseEvent):void {
            TweenLite.to(building[e.target.name], 0.5, {tint:0x00FF23});
        }

        public function showPreloader():void {
            preloader.x = (stage.stageWidth-preloader.width)/2;
            preloader.y = (stage.stageHeight-preloader.height)/2;
            preloader.alpha = 0;
            addChild(preloader);
            TweenLite.to(preloader, 0.5, {alpha:1});
        }

        public function hidePreloader():void {
            TweenLite.to(preloader, 0.5, {alpha:0, onComplete:function(){
                removeChild(preloader);         
            }});
        }

        public function loadImage(url):void {
            imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loaderProgressStatus);
            imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderComplete);
            var imageURL:URLRequest = new URLRequest(url);
            imageLoader.load(imageURL);
            showPreloader(); 
            function loaderProgressStatus(e:ProgressEvent) {  
                //trace(e.bytesLoaded, e.bytesTotal); 
            }
            function loaderComplete(e:Event) {
                hidePreloader();
                imageLoader.alpha = 0;
                imageLoader.y = (stage.stageHeight-imageLoader.height)/2;
                addChild(imageLoader);
                TweenLite.to(imageLoader, 2, {alpha:1});
            }
        }

        public function movieClipExists(mc:MovieClip):Boolean {
            return mc != null && contains(mc);
        }




    }

}
4

4 回答 4

9

完全披露:我是一个肛门和迂腐的评论家,所以不要把它当作个人。一般来说,您的代码很好。

  • 为什么ENTER_FRAME之前的延迟init?也许你有一个很好的理由,但我不知道。您应该能够init直接从您的构造函数调用。
  • 我知道 Adob​​e 建议在类属性定义中静态地实例化,但我认为它的风格不好。我在构造函数中或在我确定将首先使用它的任何地方执行此操作(通常情况下,我知道它应该在哪里初始化)。
  • 将 lib 函数 ( TweenLite) 用于动画。+1
  • 删除未使用的注释掉的代码。如果您认为有一天需要回到旧版本,请使用源代码管理。永远不要在实时源代码中留下注释掉的代码 - 这是代码腐烂
  • for (var i:Number<-- 应该使用int一个整数计数器。
  • xml.leiligheter.leilighet.length()<-- 考虑将其缓存在var len:int = ...
  • var flatName =<-- 不要偷懒忘记你的类型。
  • xml.leiligheter.leilighet[i].navn<--在那里挖得很深。你可能宁愿这样做:
    var children:XMLList = xml.leiligheter.leilighet;
    对于每个(var 节点:儿童中的 XML)
    {
        var flatName:String = String(node.navn);
        if(movieClipExists(建筑[flatName]))
        {
            building[flatName].addEventListener(MouseEvent.MOUSE_UP, flatMouseClick);
            building[flatName].addEventListener(MouseEvent.MOUSE_OVER, flatMouseOver);
            building[flatName].addEventListener(MouseEvent.MOUSE_OUT, flatMouseOut);
            建筑[flatName].alpha = 0;
            TweenLite.to(building[flatName], 2, {alpha:0.5, tint:0x00FF23});
        }
    }
  • public function showInfoBox<-- 空函数?代码腐烂,摆脱它。
  • trace('flatName: '+flatName);<-- 我养成了去除痕迹的习惯。您的代码中有几个。只要您绝对需要它们,就将它们放在那里,然后摆脱它们。
  • 在功能上showFlat更多的痕迹和糟糕的 XML 处理。
  • TweenLite.to(imageLoader, 0.5, {alpha:0, onComplete:function(){<-- 我知道在这里写一个匿名函数很容易,但最好是恕我直言,创建一个成员函数。当我想要一个闭包时,我倾向于只使用匿名函数。
  • TweenLite.to(building, 0.7, {alpha:0, onComplete:showFlat(e.target.name)}); <-- 这个调用立即显示...它不会像你想象的那样等待 onComplete 。
  • building[e.target.name].buttonMode = true;您应该只在建造建筑物时(期间handleXML)设置一次,而不是每次将鼠标悬停在上面时
  • 在命名和loadImage内部定义了两个命名函数。这些应该在类级别定义,因为它是空的——不要定义它,也不要将它分配为监听器(code-cruft)loaderProgressStatusloaderCompleteloaderProgressStatus
  • *在导入语句中避免使用通配符 ( )。显式声明每个导入可能需要做更多的工作,但它可以最大限度地减少可能的名称冲突的可能性。

就像我说的——我挑剔。你的代码风格是一致的,显示出良好的潜力。只有几种主要类型的错误:

  1. 未使用的代码永远不应保留在活动文件中。
  2. traces 应该只在调试期间存在并且应该尽快消失。
  3. 除非您需要闭包,否则请避免使用匿名函数和内部函数。
  4. 更好地熟悉 XML 的 E4X 样式处理,这样您就不必不必要地深入研究 XML 结构。
  5. 确保您始终使用类型和最合适的类型(intover Number
  6. 注意分配回调——你在错误的时间执行了一个函数。
于 2009-09-06T02:02:49.123 回答
3

导入类时,尽量不要使用通配符“*”。例如

import flash.events.*;

请准确说明您要使用的类。

原因:

  1. 当您的项目变得更大时,您可能需要导入其他类,它可能与使用通配符导入的类之一发生冲突,而导致冲突的类根本没有被使用。
  2. 更容易调试。当出现问题时,您知道需要查找哪个包。
于 2009-09-06T02:22:58.053 回答
2

需要注意的一件事:为避免内存泄漏,请使用带有事件侦听器的弱引用。建议这样做,因为即使从对象中删除了所有引用,但它具有注册到其他对象事件的函数,该对象也不会被垃圾收集(因为仍然存在某种引用),除非您使用了弱参考。

更多信息:http ://www.gskinner.com/blog/archives/2006/07/as3_weakly_refe.html

这篇文章还指出了匿名函数和弱引用的问题,这会让粗心的人头疼。

另外,我必须补充一点,如果您过度创建和“破坏”对象,这只是一个问题。

于 2009-09-06T01:25:43.583 回答
-2

今年夏天,我编写了一个图形类,用于在 AS3 中创建折线图。基于那个经验,我可以说你的代码很好,但我更喜欢在类变量和函数之前显式地写这个关键字。所以如果你声明一些类似的局部变量,你就不会迷失在它们之间。

于 2009-09-06T00:58:12.480 回答