2011-05-04 1 views
0

저는 AS3에서 여러 단어의 애니메이션을 만들고 있습니다. 모바일 장치에서이 코드를 사용하기 때문에 스프라이트가 아닌 비트 맵을 사용하고 싶습니다. 그래서 저는 액세스 할 수있는 .bitmap 속성을 가진 WordObject를 만들었습니다.enterframe의 루프?

다음 코드는 click 이벤트에서 발생하고 enterframe 이벤트 내에서 배열을 통해 반복됩니다. 이것은 아마 나쁜 생각이지만, 나는 그것을 더 잘하는 방법을 모르겠습니다. 놀랍게도 Flashbuilder에서는 정상적으로 실행되지만 Flash CS5에서는 크롤링 속도가 느려집니다.

더 좋은 방법이 있습니까? 난 단지 비트 맵 배열에 애니메이션을 적용하는 효율적인 방법이 필요하다.

private function clickhandler (e:MouseEvent){ 

     this.addEventListener(Event.ENTER_FRAME, blowemup); 
    } 
    private function blowemup(e:Event){ 
     var newPosition:Number; 
     for(var i:int=0; i<arrWordObjects.length; i++) 
     { 
      newPosition = updatePosition(arrWordObjects[i].bitmap); 
      arrWordObjects[i].bitmap.x += newPosition; 
      arrWordObjects[i].bitmap.y += getRandomNumber(); 

     } 
    } 

답변

1

뭔가 표준 for 루프보다는 for each(Object in Array)을 사용하고 있습니다.

private function blowemup(e:Event):void 
{ 
    var newPosition:Number; 

    var i:ArrWordsObjectClass; // <-- don't know what the class for this is, just replace 
    for each(i in arrWordObjects) 
    { 
     newPosition = updatePosition(i.bitmap); 
     i.bitmap.x += newPosition; 
     i.bitmap.y += getRandomNumber(); 
    } 
} 

for each 루프

arrWordObjects[i]마다 반복 무엇 해결하려고 노력 할 것입니다 경우 일반적으로 많은 시간이 저장됩니다 의미 입력됩니다.

또한 메모 : 하나의 ENTER_FRAME 구동 함수를 사용하고 응용 프로그램에서 각 프레임을 처리하려는 모든 항목을 반복하면서 개체에 대해 수백 개의 수신기를 적용하는 것보다 훨씬 효율적입니다.

나는 보통과 같이, 내 개체를 저장 ENTER_FRAME과 배열을 포함하는 핸들러 클래스를 만듭니다

package 
{ 
    import flash.events.Event; 
    import flash.display.Sprite; 

    public class Handler extends Sprite 
    { 
     // vars 
     public var elements:Array = []; 

     /** 
     * Constructor 
     */ 
     public function Handler() 
     { 
      addEventListener(Event.ENTER_FRAME, _handle); 
     } 

     /** 
     * Called on each dispatch of Event.ENTER_FRAME 
     */ 
     private function _handle(e:Event):void 
     { 
      var i:Element; 
      for each(i in elements) 
      { 
       i.step(); 
      } 
     } 
    } 
} 

그럼 내가 처리하는 모든 객체에 대한 기본 클래스를 만듭니다 step()를 포함 함수가 호출됩니다.

package 
{ 
    import flash.display.DisplayObject; 

    public class Element extends Object 
    { 
     // vars 
     public var skin:DisplayObject; 

     /** 
     * Called on each dispatch of Event.ENTER_FRAME at Handler 
     */ 
     public function step():void 
     { 
      // override me 
     } 
    } 
} 

이제 당신의 객체 요소를 확장 :

package 
{ 
    import flash.display.Sprite; 

    public class MyThing extends Element 
    { 
     /** 
     * Constructor 
     */ 
     public function MyThing() 
     { 
      skin = new Sprite(); 

      skin.graphics.beginFill(0); 
      skin.graphics.drawCircle(0,0,40); 
      skin.graphics.endFill(); 
     } 

     /** 
     * Override step 
     */ 
     override public function step():void 
     { 
      skin.x += 4; 
     } 
    } 
} 

을 그리고! :

var handler:Handler = new Handler(); 

var m:MyThing; 
var i:uint = 0; 
for(i; i<10; i++) 
{ 
    m = new MyThing(); 
    m.y = Math.random()*stage.stageHeight; 

    handler.elements.push(m); 
    addChild(m.skin); 
} 
+0

안녕 마티, 고마워 - 딘에게 내 위의 코멘트를 참조하십시오. 각 (Object in Array)로 전환했습니다. 한 가지 질문 - 객체로 객체를 가져온 경우 클래스로 변환하면 중요합니까? 어디에서 var i : ArrWordsObjectClass를 얻었습니까? 다음 코드에서는 ArrWordsObjectClass {}를 사용했습니다. 그보다 더 좋다고 생각할만한 이유가 있습니까? var i : Object; \t \t \t (각 i arrWordObjects) – David

+0

유형을 더 엄격하게 만들 때 각 루프의 속도가 증가합니다. 예를 들어, Array의 MovieClips로 구성된 Object를 사용하면 각 반복마다 루프가 작동해야합니다. 그렇지만이 항목은 객체이지만 실제로는 ** MovieClip ** -> Sprite -> DisplayObjectContainer -> InteractiveObject입니다. -> DisplayObject -> EventDispatcher -> ** ** 객체 **. 최대한 많이 상속 사슬을 사용하여 유형을 정의하면 훨씬 효율적입니다. – Marty

+0

상속 체인을 '위로'한다는 것은 실제로 MovieClip으로 '올라간다'는 것을 의미합니다. 이것은 항상 나를 뒤에서 공격했습니다. 나는 할아버지로부터 상속을 받는다. 내 할아버지는 내 가계도에서 나 위에있다. 그러나 나는 빗 나간다. :) 'class ArrWordsObjectClass {}'와 같은 임의의 클래스 유형을 지정하면 Sprite와 같은 내장 클래스를 직접 참조하는 것과 같은 효율성을 얻을 수 있습니까? – David

0

나는 ENTER_FRAME 이벤트에 대한 등록을 통해 Adobe 웹 사이트에서 사용자 정의 효과를 작성보고 제안했다. 프로그램에서 실행되는 동안이 코드가 영원히 계속 실행됨을 의미합니다. 효과를 멈추거나 10 프레임을 실행하고 멈추고 싶다면 더 많은 코드를 작성해야합니다. 이것을 여러 인스턴스에 적용하려는 경우 더욱 복잡해집니다. 사용자 정의 효과 프레임 워크가 해결하는 문제를 해결해야합니다.

내가 여기에 정의 효과를 작성하는 방법을 읽었다 :

http://livedocs.adobe.com/flex/3/html/help.html?content=createeffects_1.html

+0

감사가는 모든 것을 얻을 - 그러나 이것은 내가 원하는하지 않는 모든 액션 스크립트입니다 Flex 프레임 워크에 들어가십시오! – David

1

얼마나 많은 비트 맵을 한 번에 무대가 계획입니까?

공기 2.6을 사용하여 내 아이폰에서 최고 속도로 실행되는 스테이지에서 40 개의 900x16px 비트 맵을 애니메이션화했습니다.

나는 뮤스 큐리크에 추가 한 엔터 프레임 이벤트에서 foreach 루프를 사용하고 애니메이션이 끝나면 제거했습니다.

gpu 렌더링을 사용하는 모바일 용으로 컴파일해야합니다. (당신의 app.xml의 GPU는 공기 2.6을 사용하는 경우)

이 너무, 그것은 모바일 장치 http://help.adobe.com/en_US/as3/mobile/WS901d38e593cd1bac-3d719af412b2b394529-8000.html

의 성능에 대해 많은 설명 읽기는 여기에 내가 가진 무엇의 기본적인 예입니다 가치가있다. .. 큰 차이를 만들 것입니다

package 
{ 
    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.Sprite; 
    import flash.display.StageAlign; 
    import flash.display.StageScaleMode; 
    import flash.events.Event; 
    import flash.events.MouseEvent; 
    import flash.geom.Rectangle; 

    [SWF(frameRate="30", backgroundColor="#FF00FF")] 
    public class Test extends Sprite 
    { 
     private var fields:Vector.<Bitmap> = new Vector.<Bitmap>(); 

     public function Test() 
     { 
      this.stage.scaleMode = StageScaleMode.NO_SCALE; 
      this.stage.align = StageAlign.TOP_LEFT; 

      for(var i:int = 0; i< 37; i++){ 
       var bd:BitmapData = new BitmapData(960, 16, true, 0x000000); 

       bd.fillRect(new Rectangle(0, 0, 900, 16), Math.round(Math.random()*0xFFFFFFFF)); 

       var b:Bitmap = new Bitmap(bd); 

       b.x = 0; 
       b.y = i*16; 

       stage.addChild(b); 
       fields.push(b); 
      } 

      stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 
     } 

     private var inertia:Boolean = false; 
     private var yCurrent:Number; 
     private var ySpeed:Number; 
     private var startY:Number; 

     private var cy:Number = 0; 

     private function onEnterFrame(e:Event):void{ 
      if(!inertia){ 
       ySpeed = (startY - yCurrent) ; ///16; 
       startY = yCurrent 
      } else { 
       ySpeed *= 0.8; 

       if(ySpeed < 0.01 && ySpeed > -0.01){ 
        inertia = false; 
        stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
       } 
      } 

      cy += ySpeed; 
      if(cy > 640) 
       cy -= 640; 

      var ty:Number = cy; 
      for each(var tf:Bitmap in fields){ 
       tf.y = ty; 
       ty += 16; 

       if(ty > 640) 
        ty -= 640; 
      } 
     } 

     private function onMouseDown(e:MouseEvent):void{ 
      inertia = false; 
      startY = e.stageY; 
      yCurrent = e.stageY; 
      stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); 
      stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 
      stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); 
     } 

     private function onMouseMove(e:MouseEvent):void{ 
      yCurrent = e.stageY; 
     } 

     private function onMouseUp(e:Event):void{ 
      inertia = true; 
      stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 
      stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); 
     } 

    } 
} 
+0

안녕 딘, 감사합니다! 여기 내가 발견 한 것이있다. 나는이 미친 'Breakpoint가 설정되지 않았다. 줄 xx '에서 실행 코드가 없습니다. 오류가 많았습니다. 그것이 문제라고 판명되었습니다. 중단 점은 FB4에서는 설정되지 않았지만 CS5.5에서는 설정되지 않았습니다. 내가 지우고 정상적으로 달렸다. GPU에 대한 알림을 보내 주셔서 감사합니다. - David – David