yui-frameworks でライフゲームつくったというかつくりなおしたというか。ソースの一部とコレ作ることで得られた知見などについてテキトーにメモ。
XXXAction
public class LifegameAction { public var helper:LifegameHelper; public var logic:LifegameLogic; public function onApplicationStartHandler( event:FrameworkEvent ):void{ trace("onApplicationStartHandler"); } public function onAssembleCompleteHandler( event:FrameworkEvent ):void{ trace("onAssembleCompleteHandler"); helper.startUp(); helper.init(); logic.init( helper.width, helper.height, helper.dotWidth, helper.dotHeight, helper.speedRate, helper.initRate, helper.drawLifegameCanvas); } public function lifegameCanvasMouseDownHandler(event:MouseEvent):void { var x:int = helper.mouseDownX; var y:int = helper.mouseDownY; logic.flipCell(x, y, helper.drawCell); } public function startButtonClickHandler(event:MouseEvent):void { logic.start(); helper.clickStartButton(); } public function stopButtonClickHandler(event:MouseEvent):void { logic.stop(); helper.clickStopButton(); } public function resetButtonClickHandler(event:MouseEvent):void { stopButtonClickHandler(event); helper.init(); logic.init( helper.width, helper.height, helper.dotWidth, helper.dotHeight, helper.speedRate, helper.initRate, helper.drawLifegameCanvas); } public function speedRateChangeHandler(event:SliderEvent):void { logic.changeSpeedRate(helper.speedRate); } }
イベントもらって XXXLogic のロジック呼び出すか、XXXHelper にビュー周りのお世話お願いするか、のどっちかですね。XXXAction はこんな感じに、誰かに何かを任せる、って構図になるかと思います。
XXXLogic
public class LifegameLogic { private var lifegame:Lifegame; private var gameSpeed:Timer; private var updateLifegame:Function; public function LifegameLogic() { } public function init( width:int, height:int, dotWidth:int, dotHeight:int, speedRate:Number, initRate:int, updateLifegame:Function):void { this.lifegame = new Lifegame(width, height, initRate); this.gameSpeed = new Timer(speedRate); this.gameSpeed.addEventListener(TimerEvent.TIMER,delayHandler); this.updateLifegame = updateLifegame; updateLifegame.call(updateLifegame, lifegame); } private function delayHandler(evt:TimerEvent):void{ lifegame.tick(); updateLifegame.call(updateLifegame, lifegame); } public function start():void { gameSpeed.start(); } public function stop():void { gameSpeed.stop(); } public function changeSpeedRate(value:Number):void { gameSpeed.delay = value; } public function flipCell(x:int, y:int, updateLifegameCell:Function):void { if (lifegame.isContain(x, y)) { lifegame.flipCell(x, y); updateLifegameCell.call(updateLifegameCell, lifegame.getCell(x, y), x, y); } } }
lifegame.tick() でライフゲームが次の状態に遷移、updateLifegame でビューに変更を通知して描画をやってもらう、ってのが大きな流れですかね。ライフゲームの核となるコードはめんどいんで載せてないけど、ロジックがここにくるんですよーってことは伝わるかな、と思います。
XXXHelper
public class LifegameHelper { private const INCLEMENT_VALUE:int = 10; public var view:LifegameView; private var drawer:LifegameDrawer; public function startUp():void { var data:Array = new Array(); var i:int = INCLEMENT_VALUE; for (i=INCLEMENT_VALUE; i<71; i+=INCLEMENT_VALUE) { data.push(i); } view.heightSelect.dataProvider = data; view.widthSelect.dataProvider = data; view.dotHeightSelect.dataProvider = [2, 3, 4, 5, 20]; view.dotWidthSelect.dataProvider = [2, 3, 4, 5, 20]; view.stopButton.enabled = false; view.dotHeightSelect.selectedIndex = 1; view.dotWidthSelect.selectedIndex = 1; view.heightSelect.selectedIndex = 2; view.widthSelect.selectedIndex = 2; } public function init():void { view.lifegameCanvas.graphics.clear(); drawer = new LifegameDrawer( view.lifegameCanvas.graphics, width, height, dotWidth, dotHeight); drawer.drawDrid(); } public function clickStartButton():void { view.startButton.enabled = false; view.stopButton.enabled = true; } public function clickStopButton():void { view.startButton.enabled = true; view.stopButton.enabled = false; } public function drawLifegameCanvas(lifegame:Lifegame):void { view.lifegameCanvas.graphics.clear(); drawer.drawDrid(); lifegame.traverse(drawCell); } public function drawCell(cell:Cell, x:int, y:int):void { drawer.drawCell(cell, x, y); } public function get mouseDownX():int { return drawer.convertLocalXToCoordinate(view.lifegameCanvas.contentMouseX); } public function get mouseDownY():int { return drawer.convertLocalYToCoordinate(view.lifegameCanvas.contentMouseY); } public function get width():int { return view.widthSelect.selectedItem as int; } public function get height():int { return view.heightSelect.selectedItem as int; } public function get dotWidth():int { return view.dotWidthSelect.selectedItem as int; } public function get dotHeight():int { return view.dotHeightSelect.selectedItem as int; } public function get speedRate():Number { return view.speedRate.value; } public function get initRate():int { return view.initRate.value as int; } }
見た目のお世話です。Canvas に対する描画のコードはココには載せないけど、まぁ雰囲気は伝わるかなーと。
XXXAction 側にどーやってデータ渡すのかは迷ったけど、とりあえず get ステートメントにしときました。実際にはデータ変換とか validation が絡むからもっとややこしくなりそう。