我正在Flex Canvas上绘制元胞自动机模拟。我通过更新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>
答案 0 :(得分:1)
可怕:
while (true) {
Flex是单线程的,所以我认为你永远不会给UIComponents一个完全更新的机会。
替代方法是在Timer上运行draw和update方法,或者在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)">