2009-11-17 4 views
3

나는 프리 로더 쓰고 있어요 : 메인 클래스로이 함께프리 로더 -에 getDefinition (에 참조 오류)

package { 
    import flash.display.DisplayObject; 
    import flash.display.Sprite; 
    import flash.text.TextField; 
    import flash.display.LoaderInfo; 
    import flash.events.MouseEvent; 
    import flash.events.Event; 
    import flash.events.ProgressEvent; 
    import flash.system.System; 

    public class Preloader extends Sprite { 
      private var t:TextField = new TextField(); 
      private var ver:String = "1000"; 
      public function Preloader() { 
        t.y = 570; 
        addChild(t); 
        t.text = ver; 

        addEventListener(Event.ADDED_TO_STAGE, init); 
      } 

      private function init(e:Event):void { 
        this.root.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadingProgress); 
        this.root.loaderInfo.addEventListener(Event.COMPLETE, onLoadingCompleted); 

        // See if it's already completed 
        var percent:int = int(root.loaderInfo.bytesLoaded/root.loaderInfo.bytesTotal); 
        if (percent == 1) 
          onLoadingCompleted(); 
      } 

      private function onLoadingProgress(event:Event):void { 
        var percent:int = int(root.loaderInfo.bytesLoaded/root.loaderInfo.bytesTotal * 100); 
        t.text = "Loading.. " + percent + "%"; 
      } 

      private function onLoadingCompleted(event:Event = null):void { 
        root.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoadingProgress); 
        root.loaderInfo.removeEventListener(Event.COMPLETE, onLoadingCompleted); 

        var mainClass:Class = loaderInfo.applicationDomain.getDefinition("Main") as Class; 
        var main:DisplayObject = new mainClass() as DisplayObject; 

        parent.addChild(main); 
        parent.removeChild(this); 
      } 
    } 
} 

을 :

package { 
    import flash.display.Sprite; 

    public class Main extends Sprite { 

      public function Main() { 
      } 
    } 
} 

은 그래서 이것은 한 베어 본에 가까운 나는 그것을 만들 수 있었다.

그러나, 그것은 나에게 인사 :

ReferenceError: Error #1065: Variable Main is not defined. 
at flash.system::ApplicationDomain/getDefinition() 
at ... 

은 이미 홈페이지를 삽입 frames.frame를 사용합니다. 개미와 리눅스 SDK를 직접 (mxmlc) 사용하여 컴파일하고 있습니다. 나는 명백한 것을 놓치고 있습니까?

답변

4

"스타일"에서 프리 로더를 만들 때 프리 로더는 응용 프로그램의 첫 번째 프레임에 배치되고 나머지는 두 번째 프레임에 배치됩니다. 여기서 누락 된 부분은 컴파일러에게 Main 클래스가 컴파일되기를 원한다는 것입니다. 그래서 지금은 swf에도 존재하지 않습니다. 그것이 getDefinition이 작동하지 않는 이유입니다.

프리 로더를 표시하기 전에 첫 번째 프레임에서로드하게하기 때문에 프리 로더에서 참조 할 수 없습니다. 따라서, 약간의 사용자 정의 인수 마법이 필요합니다.

컴파일러 옵션이 줄을 추가하고 당신이 가서 잘되어야합니다 :

-frame start Main 

자신의 메인 클래스가 패키지에있는 경우 당신은 거기에서 전체 참조 얻을 필요가 있음을 기억

-frame start com.grapefrukt.examples.Main 

getDefinition 호출과 동일합니다.

는 편집 : 나는 당신이 무슨 짓을했는지와는 다른 접근 방법을 사용하는 것이 볼이 작업을 수행 내 코드를 통해

을 찾고, 어쩌면이 잘 작동 :

var mainClass:Class = getDefinitionByName("com.grapefrukt.examples.Main") as Class; 
addChild(new mainClass() as DisplayObject); 

편집 다시 : 를 작동하는 경우 버튼을 사용하면 완전한 이벤트가 너무 일찍 해고되었다고 추측 할 수 있습니다. 모든 바이트가로드 되어도 모든 것이 제대로 이벤트에 삽입되지 않도록 할 수 있습니다. 대신 완료를 확인하기 위해이 코드를 사용해보십시오 :

if (currentFrame == totalFrames) onLoadingCompleted() 

또한 당신의 onLoadingCompleted에 정지() 명령을 추가하는 것이 좋습니다 수 있습니다() 메소드를 바로 재생 헤드가 일을 망쳐되지 않습니다 만들기 위해, 하지만 그건 나중에 문제입니다.

+0

멋지다! 나는 이것을 몰랐다. 나는 이것이 티미의 질문을 해결하기를 희망한다. –

+0

나는 이미 이것을하고있다. 불행히도, "메인을 삽입하기 위해 frames.frame을 사용했다"고했을 때 명확하지 않았습니다. – Timmy

+0

괜찮 았어, 또 다른 제안을 추가했는데 도움이 되었습니까? – grapefrukt

1

기본 패키지 ("game.Game"대신 "Game")에 Game 클래스가있는 경우에는 어떤 차이가 있습니까?

새로운 mainClass (this.root)와 같은 것을 사용 해본 적이 없으며 새로운 mainClass()가 괜찮을 것입니다.

또한 Event.COMPLETE 대신 Event.INIT를 사용하면 어떤 차이가 있습니까?

+0

패키지 이동 = 동일한 결과. 클래스에 변수로 루트를 전달 중입니다 (플래시 바를 읽을 수 있도록) Event.INIT는 아무 것도 변경하지 않았습니다. 감사합니다. – Timmy

+0

은 Game public class입니까? 또한 편리한가요? http://www.kirupa.com/forum/showthread.php?t=274871? –

+0

예. 공개입니다. 단추 나 타이머를 추가하면 찾은 것 같습니다. 그것은 실제로 그것이 준비가되기 전에 이벤트를 발생시키는 것입니다. – Timmy

1

nextFrame()이 누락되었습니다.
함수에서 : onLoadingComplete add nextFrame(); 정말 grapefrukt의 대답에 확장 비록

public class Preloader extends MovieClip 
    { 
    public function Preloader() 
    { 
     stop(); 
     addEventListener(Event.ENTER_FRAME, onEnterFrame); 
     this.loaderInfo.addEventListener(Event.COMPLETE, startup); 
     // Set up progress bar/graphics 
    } 

    private function onEnterFrame(e:Event):void 
    { 
     // Display progress bar, loadedbytes, animation, etc... 
    } 

    private function startup(e:Event):void 
    { 
     nextFrame(); 
     removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
     loaderInfo.removeEventListener(Event.COMPLETE, startup); 
     var gameClass:Class = getDefinitionByName("Main") as Class; 
     if (gameClass) addChild(new gameClass() as Sprite); 
    } 
    } 

1

이 댓글에 대한 조금 긴 :

여기 베어 뼈 버전입니다. 오히려 늦은 대답이기도합니다. 하지만 어도비 나 다른 누구도이 문서를 보지 못했습니다.

Event.COMPLETE이 런타임 공유 라이브러리를 사용할 때 "다음"프레임이 실제로 준비되기 전에 "초기"로 트리거되는 것처럼 보이는 한 가지 이유가 있습니다. Event.COMPLETE은 현재 swf가로드 될 때 트리거됩니다. RSL로드가 완료되기 전에 발생할 수 있습니다.

일반적인 프리 로더 구현에서 - 재생 헤드가 입력을 시도 할 때를 의미하는 ("Flash Pro에서 런타임 공유를 위해 가져 오기"를 사용하여) "자동으로"로드 된 RSL이로드됩니다 프레임 2.

로드가 끝날 때까지 프레임 2로 넘어갈 수 없으며 진행할 수없는 한 해당 프레임의 클래스 나 인스턴스에는 액세스 할 수 없습니다. gotoAndStop(2) 또는 nextFrame()에 대한 전화는 즉각적인 영향을주지 않습니다 (즉, eLouai의 응답은이 경우 작동하지 않습니다). 그 외에도 통화가 대기 상태가되지 않습니다. 재생 헤드는 단순히 프레임 1에 머물러 있습니다. 내부적으로 FlashPlayer에서 어딘가에 삼켜지는 참조 오류가 발생할 수 있습니다. 적어도 내 테스트에서는 오류가보고되지 않습니다. 그냥 조용히 실패합니다. play() 그러나, 이 될 때 다음 프레임으로 이동합니다.

즉, grapefrukt는 swf가 재생중인 경우 ENTER_FRAME 청취자에서 currentFrame == 2 (또는 프레임 번호)을 기다릴 수 있음을 알립니다. 또는 currentFrame == 2을 감지 할 때까지 ENTER_FRAME 청취자에서 nextFrame() 또는 gotoAndStop(2) (또는 어떤 프레임 번호)이라도 호출 할 수 있습니다. 후자는 플레이어가 아무 것도 출력하지 않더라도 오류가 실제로 내부에서 발생하고 있기 때문에 미래에 잠재적으로 손상 될 수있는 것처럼 보입니다. 한마디로

: 프레임 2가 준비 될 때까지

play() 기다립니다. gotoAndStop(2) 또는 nextFrame()은이라고 할 때 프레임 2가 준비되지 않은 경우 아무런 효과가 없습니다 (나타납니다) . Event.COMPLETE은 모든 프레임을 표시 할 준비가되었음을 보증하지 않습니다. 특히 RSL을 사용하지 않는 경우에는 다른 이유가있을 수 있습니다.

관련 문제