2009-09-06 2 views
1

Я только что начал кодирование в AS3, и было бы здорово получить некоторые отзывы от экспертов; на мой стиль кодирования, что я делаю неправильно, что я могу улучшить, лучшие практики и т. д. Кроме того, если у вас есть дополнительные советы или приемы, это было бы здорово.AS3 code feedback

Вот мой первый бит AS3 кода, мне потребовалось 5 часов, PUH:

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); 
     } 




    } 

} 

ответ

9

Полное раскрытие информации: Я анальный и педантичный рецензент, поэтому не принимайте это лично. В общем, ваш код хорош.

  • Почему ENTER_FRAME Задержка до init? Возможно, у вас есть веская причина, но я не знаю об этом. Вы должны иметь возможность позвонить init непосредственно со своего конструктора.
  • Я знаю, что Adobe рекомендует создание экземпляра в определении свойств классов, но я считаю его плохим. Я делаю это в конструкторе или везде, где я уверен, что он будет сначала использоваться (чаще всего я знаю, где он предназначен для инициализации).
  • Хорошее использование функций lib (TweenLite) для анимаций. +1
  • Удалите прокомментированный код, который не используется. Используйте источник управления, если вы считаете, что вам нужно вернуться к старой версии в один прекрасный день. Никогда не оставляйте прокомментированный код в прямом эфире - это code rot.
  • 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; 
    for each(var node:XML in children) 
    { 
     var flatName:String = String(node.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 < - пустая функция? Код гниения, избавиться от него.
  • trace('flatName: '+flatName); < - У меня есть привычка удалять следы. В вашем коде несколько. Держите их там только до тех пор, пока вы в них абсолютно нуждаетесь, тогда избавитесь от них.
  • в функции showFlat больше следов и плохой обработки XML.
  • TweenLite.to(imageLoader, 0.5, {alpha:0, onComplete:function(){ < - Я знаю, что здесь легко написать анонимную функцию, но лучше использовать IMHO для создания функции-члена. Я предпочитаю использовать анонимные функции, когда хочу закрыть.
  • TweenLite.to (building, 0.7, {alpha: 0, onComplete: showFlat (e.target.name)}); < - это звонит прямо сейчас ... он не дожидается до конца, как вы думаете.
  • building[e.target.name].buttonMode = true; вы должны установить это только один раз, когда вы возводят здания (при handleXML), а не каждый раз, когда он наведении мышки на
  • В loadImage у вас есть две названные функции, определенные внутри имени loaderProgressStatus и loaderComplete. Они должны быть определены на уровне класса и поскольку loaderProgressStatus пуст - не определяйте его и не назначайте его в качестве слушателя (code-cruft)
  • Избегайте символа подстановки (*) в ваших операциях импорта. Может быть немного больше работы, чтобы явно объявить каждый импорт, но это минимизирует шансы на возможное столкновение имен.

Как я уже говорил - я очень picky. Ваш стиль кода согласован, что показывает хороший потенциал. Существует только несколько основных типов ошибок:

  1. Неиспользованный код никогда не должен оставаться в активном файле.
  2. trace s должен существовать только во время отладки и должен исчезать как можно скорее.
  3. Избегайте анонимных функций и внутренних функций, если вы не нуждаетесь в закрытии.
  4. Станьте лучше знакомы с обработкой XML в стиле E4X, поэтому вам не придется излишне копаться в структурах XML.
  5. Убедитесь, что вы всегда использовать типы и наиболее подходящий тип (int над Number)
  6. Берегись назначения функции обратного вызова - вы выполняете функцию в неправильное время.
+1

Я согласен со всем ... Я бы добавил, что я нашел хорошую практику, чтобы отключить «автообъявление экземпляров сцены» в настройках ActionScript ... тогда вы можете явно объявить их в своем классе с соответствующим типом, поэтому класс в целом будет явно объявлять все свои зависимости (т.е. public var building: MovieClip). – Cay

+0

СПАСИБО, Джеймс! Именно то, что я искал: D –

+0

@ Cay: Я просмотрел код, пытаясь найти определение здания, а затем должен был предположить, что это был экземпляр сцены. Я бы предпочел, чтобы это было объявлено внутри класса. Я использую Flex Builder в эти дни, а не Flash IDE, поэтому я этого не понимал - и полностью согласен с вашей рекомендацией. –

-2

Этим летом я написал класс графов для создания линейных диаграмм в AS3. Основываясь на этом опыте, могу сказать, что код довольно неплохой, но я предпочитаю явно писать это ключевое слово перед переменными класса и функциями. Поэтому, если вы объявите некоторые аналогичные локальные переменные, вы не потеряетесь между ними.

+2

Я думаю, что это довольно субъективно ... Мое мнение состоит в том, что большинство бесполезных утверждений следует избегать, а не только избегать многословия, но также и потому, что они добавляют сложность коду. В случае «этого», используя его только тогда, когда это необходимо, оба удержат вас от именования аналогичных локальных переменных (что запутывает в любом случае) и явно сообщают, когда это происходит ... – Cay

2

Одна вещь, которой нужно следить: чтобы избежать утечек памяти, используйте слабые ссылки с прослушивателями событий. Это предлагается, потому что даже если все ссылки удалены из объекта, но у него есть функция, которая зарегистрирована на событие другого объекта, объект не будет собираться с мусором (потому что есть еще какая-то ссылка), если только вы использовал слабую ссылку.

Подробнее: http://www.gskinner.com/blog/archives/2006/07/as3_weakly_refe.html

Эта статья также указывает на проблему с анонимными функциями и слабой ссылки, которые могут вызвать LOF головной боли для неосторожных.

Кроме того, я должен добавить, что это только проблема, если вы чрезмерно создаете и уничтожаете объекты.

+2

Я бы рекомендовал использовать сильные ссылки, в то время как обучения AS3, так как это даст вам лучшее представление о том, как работает язык. Слабые ссылки велики (я их много использую), но они довольно ленивый способ избежать утечек памяти (и они ничего не гарантируют), поэтому я бы использовал «почти всегда использовать слабые ссылки» в качестве хорошего совета для но не для обучения. Удаление слушателей, когда вы закончите с ними, является довольно хорошей практикой, особенно при обучении AS3 – Cay

+0

Я согласен с Кей здесь - слабые ссылки имеют свое место, но хорошо учиться развиваться без них. Я очень осторожен, чтобы всегда удалять слушателей, и это хорошая привычка делать это. –

3

При импорте класса старайтесь не использовать подстановочный знак «*». , например.

import flash.events.*; 

Укажите, какой именно класс вы собираетесь использовать.

причины:

  1. Когда ваш проект становится все больше, вы , возможно, придется импортировать другой класс, он может вступать в противоречие с одним из классов , который импортируется с помощью джокера, и класс, который вызывает конфликт не используется вообще.
  2. Проще для отладки. Вы знаете, какой пакет нужно искать, когда что-то пошло не так.
+0

Абсолютно. Я добавил это к моему ответу, так как я полностью согласен. –