2012-09-05 2 views
0

저는 모바일에서 "기본"응용 프로그램 및 데스크톱 웹 브라우저로 배포하기위한 게임을하고 있습니다.모바일 용 Flash/AIR 게임에서 높은 FPS를 얻으시겠습니까?

여러 플랫폼에서 작업 한 이후로 Flash 및 내장 AIR은 꽤 좋은 솔루션이었습니다. 하지만 어 - 오.

4 키 프레임 무비 클립의 경우 (무대에 추가하고 각 프레임에서 위치를 업데이트 한 다음 나중에 제거하면) 약 30 개가 데스크톱 화면에 표시 될 때 게임이 느려집니다. 내 Android (Samsung i9000 - 2.3.3)에서. 그리고 나는 더 필요할지도 모른다.

내 플래시 라이브러리에 저장된 내 비트 맵의 ​​영역을 다시 그리며 내 MovieClips를 bitmapDatas 스프라이트 시트로 변환하여 깜박 거리게했습니다. 데스크톱에서의 결과는 수 많은 객체가있는 경우에도 완벽하고 부드러운 애니메이션으로 훌륭합니다. 그러나 모바일에서의 결과는 끔찍합니다. FPS는 화면에 하나의 객체 만 표시되거나 CPU 또는 GPU가 렌더링되는 경우에도 15로 떨어집니다.

내 게임이 '오래된'장치에서 작동한다는 것이 분명 좋을 것이므로 50 개 또는 그 이상의 프레임 속도에 도달하려면 Flash 및 AIR로 작업하고 있습니다.

플래시가있는 모바일 게임을 개발할 때 필요한 팁이나 필수 사항이 있습니까? 이런 종류의 사건에서 우리가 피해야 할 공통적 인 실수가 있습니까?

답변

0

cacheAsBitmap 및 cacheAsBitmapMatrix를 GPU 렌더링과 함께 사용하면 약간의 개선 효과를 얻을 수 있지만, 원격으로 복잡한 작업을 수행 할 경우 60fps에 가깝지는 않습니다.

모바일 장치에서 실제 성능을 원한다면 Starling 프레임 워크 (http://gamua.com/starling/)를 확인하십시오. 객체 모델과 디스플레이 목록을 표준 플래시에 매우 가깝게 유지하면서 합성 및 렌더링을 GPU로 완전히 이동시킵니다. 생성 또는 2 개의 오래된 하드웨어에서도 성능이 빠르게 (60fps로 쉽게 달성 가능) 굉장합니다.

+0

나는 당신에게 약간의 대답을주기 전에 그것을 시도하고 싶었습니다. 그것은 매력처럼 부드럽게 작동합니다. 고맙습니다 ! –

1

Adobe Air에서 매우 복잡한 플래시 벡터 애니메이션으로 실제로 30fps ~ 50fps를 얻을 수 있습니다.

하지 말아야 할 것 :

  1. 애니메이션 아무것도 체크 박스 "비트 맵으로 캐시"사전 제작을 사용하지 마십시오. 이것은 정적 벡터 이미지로 적용 할 때 정적 비트 맵으로 변환 할 때 훌륭한 기능입니다. x 또는 y 축의 무비 클립을 변환하는 것 이외의 방법으로 애니메이션을 애니메이션하는 경우 비트 맵이 켜져있는 상태에서 애니메이션이 실제로 캐시와 함께 느려집니다.

  2. 블리 팅하지 마십시오. 블리 팅을 사용하면 Flash에서 게임을 빠르게 할 수 있지만 Adobe Air에서는 게임 속도가 느려집니다. 원하는 것은 무대에 배치 된 비트 맵 객체이며 스테이지에 블립되는 bitmapData 객체는 아닙니다.

그래서, 당신이 무엇을 할 수 있는지에 SWF 또는 무비 클립을 잡은하지만 개체의 모든 프레임을 실행하고 비트 맵으로 각 프레임을 변환합니다. 그런 다음 각 비트 맵을 배열에 저장하십시오. 그런 다음 애니메이션을 재생하려면 배열에서 비트 맵을 검색하여 스테이지에 순차적으로 배치합니다. 필자는 40fps 이상의 Android 태블릿에서 전체 화면, 24 프레임 애니메이션을 실행할 수있었습니다.

코드 샘플을 참조하십시오. 비트 맵을 천천히 캐시하고 완료 한 다음 즉시 더 높은 속도로 재생을 시작합니다. 원하는 경우 애니메이션이 캐시되는 동안 숨길 수 있습니다.애니메이션을 더 이상 필요로하지 않을 때 메모리를 비우기 위해 배열을 지우십시오.

package scripts.animation{ 
    import flash.display.MovieClip; 
    import flash.events.*; 
    import flash.display.Stage; 
    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.*; 
    import flash.events.Event; 


    public class spriteSheetMaker extends MovieClip { 
     private var pWidth:int=0; 
     private var pHeight:int=0; 
     private var regX:int=0; 
     private var regY:int=0; 
     private var swfObj:MovieClip = null; 
     private var pFrame:int=0; 
     private var pFrames:int=0; 
     private var pSheetArray:Array=[]; 
     private var pSheetInfo:Array=[]; 
     private var pAnimating:Boolean = false; 
     private var pAnimationCycle:int = 0; 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     //init 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     public function spriteSheetMaker():void { 
      startGrab(); 
     } 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     //swf is loaded, find out how many frames are in, dimentions etc, and start animation 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     public function startGrab():void { 
      swfObj=this.animation; 
      swfObj.x = 0; 
      //swfObj.y = 0; 
      pFrames=swfObj.totalFrames; 
      pFrame=0; 
      pSheetInfo=[this.name,pWidth,pHeight]; 
      pSheetArray.push (pSheetInfo); 
      pAnimating = false; 
      this.addEventListener (Event.ENTER_FRAME,cycleSwfAnim); 
     } 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     //load the next frame of the animation and convert it 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     private function cycleSwfAnim (event:Event):void { 
      pFrame++; 
      if (pFrame < pFrames + 2) { 
       swfObj.gotoAndStop (pFrame); 
       grabBitmap(); 
      } else { 
       stopGrab(); 
      } 
     } 
     // 
     private function stopGrab():void{ 
      this.removeEventListener (Event.ENTER_FRAME,cycleSwfAnim); 
      trace("Sheet = " + pSheetArray); 
      swfObj.parent.removeChild(swfObj); 
      swfObj=null; 
      startAnimationPlayback(); 
     } 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     //Convert fram (vector, bitmap, whatever is on the frame) into a bitmadata object 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     private function grabBitmap():void { 
      pWidth=this.width; 
      pHeight=this.height; 
      var bmd:BitmapData=new BitmapData(pWidth,pHeight,true,0x00FFFFFF); 
      bmd.draw (swfObj); 
      var bm:Bitmap = new Bitmap(); 
      bm.bitmapData = bmd; 
      pSheetArray.push (bm); 
     } 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     //Play animation 
     //------------------------------------------------------- 
     //------------------------------------------------------- 
     private function startAnimationPlayback():void{ 
      this.addEventListener (Event.ENTER_FRAME,animate); 
      pFrame =0; 
     } 
     // 
     private function animate(event:Event):void{ 
      pFrame++; 
      if (pFrame>pSheetArray.length){ 
       pFrame = 1; 
      } 
      var bm:Bitmap = pSheetArray[pFrame]; 
      if (bm != null){ 
       if (this.numChildren>0){ 
        this.removeChildAt(0); 
       } 
       this.addChild(bm); 
      } 
     } 
    } 
} 
관련 문제