2009-12-29 9 views
0

저는 Flex Canvas에서 셀룰러 오토매틱 시뮬레이션을 그립니다. 나는 Panel의 그래픽을 업데이트하여 오토 마톤의 상태를 계산하는 것을 번갈아한다. 그러나 Panel의 업데이트는 CA 상태의 업데이트와 "유지"되지 않는 것처럼 보입니다.플렉스 패널이 업데이트되지 않았습니다.

제가 그래픽 코드 처리에 문제가 있는지 궁금합니다. 코드는 다음과 같습니다. 미안하지만 시간이 너무 오래 걸리지는 않지만 문제가 더 간단해질 것이라고 생각하지 않습니다. (글쎄요, 아마도 그럴 것입니다. 그러나 시간을내어 그것을 찾고 싶지는 않습니다.) 무서운

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init();"> 
    <mx:Script> 
     <![CDATA[ 
     private static const universeRadius:uint = 8; 

     private var universes:Array = new Array(); 
     private var currentUniverse:uint = 0; 
     private var squareHeight:uint; 
     private var squareWidth:uint; 

     private function init():void { 
      squareHeight = myCanvas.height/universeRadius; 
      squareWidth = myCanvas.width/universeRadius; 
      initUniverses(); 

      while (true) { 
       trace("Calling draw()"); 
       draw(); 
       trace("Calling updateUniverse()"); 
       updateUniverse(); 
      } 
     } 

     private function initUniverses():void { 
      var universe0:Array = new Array(); 
      var universe1:Array = new Array(); 

      var i:int; 
      for (i = 0; i < universeRadius; i++) { 
       var universe0Row:Array = new Array(); 
       var universe1Row:Array = new Array(); 
       var j:int; 
       for (j = 0; j < universeRadius; j++) { 
        if (Math.random() < 0.5) { 
         universe0Row[j] = 0; 
        } else { 
         universe0Row[j] = 1; 
        } 
        universe1Row[j] = 0; 
       } 
       universe0[i] = universe0Row; 
       universe1[i] = universe1Row; 
      } 

      universes[0] = universe0; 
      universes[1] = universe1; 
     } 

     private function normalize(pos:int):int { 
      return (pos + universeRadius) % universeRadius; 
     } 

     private function updateUniverse():void { 
      var newUniverse:int = 1 - currentUniverse; 
      var i:int; 
      for (i = 0; i < universeRadius; i++) { 
       var j:int; 
       for (j = 0; j < universeRadius; j++) { 
        var dx:int; 
        var dy:int; 
        var count:int = 0; 
        for (dx = -1; dx <= 1; dx++) { 
         var neighborX:int = normalize(i + dx); 
         for (dy = -1; dy <= 1; dy++) { 
          var neighborY:int = normalize(j + dy); 
          if ((dx != 0 || dy != 0) && 
           universes[currentUniverse][neighborX][neighborY] == 1) { 
            count++; 
           } 
         } 
        } 
        var currentCell:int = universes[currentUniverse][i][j]; 
        if (currentCell == 1) { 
         // 1. Any live cell with fewer than two live neighbours 
         // dies, as if caused by underpopulation. 
         if (count < 2) { 
          universes[newUniverse][i][j] = 0; 
         } 
         // 2. Any live cell with more than three live neighbours 
         // dies, as if by overcrowding. 
         else if (count > 3) { 
          universes[newUniverse][i][j] = 0; 
         } 
         // 3. Any live cell with two or three live neighbours 
         // lives on to the next generation. 
         else { 
          universes[newUniverse][i][j] = 1; 
         } 
        } else { 
         // 4. Any dead cell with exactly three live neighbours 
         // becomes a live cell. 
         if (count == 3) { 
          universes[newUniverse][i][j] = 1; 
         } else { 
          universes[newUniverse][i][j] = 0; 
         } 
        } 
       } 
      } 

      currentUniverse = newUniverse; 
     } 

     private function draw():void { 
      myCanvas.graphics.clear(); 
      myCanvas.graphics.beginFill(0xFFFFFF, 1.0); 
      myCanvas.graphics.drawRect(0, 0, myCanvas.width, myCanvas.height); 
      var i:int; 
      for (i = 0; i < universeRadius; i++) { 
       var j:int; 
       for (j = 0; j < universeRadius; j++) { 
        if (universes[currentUniverse][i][j] == "1") { 
         myCanvas.graphics.beginFill(0x000000, 1.0); 
         myCanvas.graphics.drawRect(
          j * squareWidth, i * squareHeight, squareWidth, squareHeight) 
        } 
       } 
      } 
      myCanvas.graphics.endFill(); 
     } 
     ]]> 
    </mx:Script> 
    <mx:Panel title="Life" height="95%" width="95%" 
     paddingTop="5" paddingLeft="5" paddingRight="5" paddingBottom="5"> 

     <mx:Canvas id="myCanvas" borderStyle="solid" height="100%" width="100%"> 
     </mx:Canvas> 
    </mx:Panel> 
</mx:Application> 

답변

1

:

while (true) { 

플렉스는 단일 스레드, 그래서 나는 당신이 결코 UIComponents의를 완벽하게 업데이트 할 수있는 기회를 제공하지 않습니다 것 같아요.

타이머 대신 그리기 및 업데이트 메서드를 실행하거나 ENTER_FRAME 이벤트에서 실행하는 방법도 있습니다. 이들 중 하나는 표시 목록의 업데이트가

private function cycleUniverse(event:Event):void { 
    updateUniverse(); 
    draw(); 
} 

다음

private var t:Timer; 

private function init():void { 
    t = new Timer(500); // every 500 ms 
    t.addEventListener(TimerEvent.Timer, cycleUniverse); 
    t.start(); 
} 

또는

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" enterFrame="cycleUniverse(event)"> 
+0

중 하나 나는 타이머 이벤트를하고있는 업데이트를 넣어 결국 사이에서 발생 할 것 잘 작동합니다. "사실 (while) (사실)"은 무서운 것이지만 코드의 초기 버전이므로 나중에 변경하려고합니다. 감사합니다. –

+0

Flex의 단일 스레드로 인해서 만 무서워합니다. 다른 곳에, (사실) 동안. –

관련 문제