In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

MVC ってこういうこと?

解説は http://aquioux.blog48.fc2.com/blog-entry-640.html
Get Adobe Flash player
by Aquioux 03 Oct 2009
/**
 * Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/d9wo
 */

/**
 * 解説は http://aquioux.blog48.fc2.com/blog-entry-640.html
 */
package {
	import flash.display.Sprite;
	[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#FFCCCC")]
	
	public class Main extends Sprite {
		
		public function Main() {
			// Model を生成
			var model:Model = new Model();
			// View を生成
			var view:View = new View(model);
			view.x = stage.stageWidth / 2;
			view.y = stage.stageHeight / 2;
			addChild(view);
			// Controller を生成
			var controller:Controller = new Controller(model);


			// ユーザ入力用の View を生成
			const signs:Array = ["position", "scale", "rotation"];
			var n:uint = signs.length;
			for (var i:int = 0; i < n; i++) {
				var inputView:Button = new Button(signs[i]);
				inputView.controller = controller;
				inputView.x = inputView.width * i;
				inputView.y = 0;
				addChild(inputView);
			}
		}
	}
}


// Model
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	class Model extends EventDispatcher {
		// ----- View へ通知するメンバ変数 -----
		public function get value1():Number { return _value1; }
		private var _value1:Number;
		
		public function get value2():Number { return _value2; }
		private var _value2:Number;
		
		public function get value3():Number { return _value3; }
		private var _value3:Number;
		// ----- View へ通知するためのメンバ変数 -----

		// ----- View へ向けたイベント発効 (Model -> View)-----
		// イベント発効
		internal function notifyFromModelToListener():void {
			dispatchEvent(new Event(Event.CHANGE));
		}
		// ----- View へ向けたイベント発効 (Model -> View)-----
		
		
		// ----- Controller から呼び出される関数 (Controller -> Model)-----
		internal function update1():void {
			// value1 の変化と通知
			_value1 += RATE;
			notifyFromModelToListener();
		}
		internal function update2():void {
			// value2 の変化と通知
			_value2 += RATE;
			notifyFromModelToListener();
		}
		internal function update3():void {
			// value3 の変化と通知
			_value3 += RATE;
			notifyFromModelToListener();
		}
		// ----- Controller から呼び出される関数 (Controller -> Model)-----
		
		
		private const RATE:uint = 15;	// 変化量
		public function Model() {
			// 各データ初期化
			_value1 = 0;
			_value2 = 0;
			_value3 = 0;
			
			var timer:Timer = new Timer(25);
			timer.addEventListener(TimerEvent.TIMER, timerHandler);
			timer.start();
		}
		private function timerHandler(e:TimerEvent):void {
			_value1 += 0.5;
			_value2 += 0.5;
			_value3 += 0.5;
			notifyFromModelToListener();
		}
	}


// View
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;

	class View extends Sprite {
		// ----- Model への参照 -----
		private var _model:Model;

		// ----- Model からのイベントを捕捉 (Model -> View という流れ)-----
		private function changeHandler(event:Event):void {
			// 自分の各プロパティの値を Model のそれによって更新する
			x = Math.sin(_model.value1 * Math.PI / 180) * 200 + 465 / 2;
			scaleY = Math.cos(_model.value2 * Math.PI / 180);
			rotation = _model.value3;
		}
		// ----- Model からのイベントを捕捉 (Model -> View という流れ)-----


		public function View(model:Model) {
			_model = model;
			_model.addEventListener(Event.CHANGE, changeHandler);

			draw();
		}
		[Embed(systemFont = "sansserif", fontName = "myFont", mimeType = "application/x-font")]
		private static const myFont:Class;		
		private function draw():void {
			graphics.beginFill(0xFFFFFF);
			graphics.drawRect( -100, -100, 100, 200);
			graphics.beginFill(0x000000);
			graphics.drawRect(0, -100, 100, 200);
			graphics.endFill();
			
			var textFormat:TextFormat = new TextFormat("myFont", 40);
			textFormat.align = TextFormatAlign.CENTER;
			var textField:TextField = new TextField();
			textField.defaultTextFormat = textFormat;
			textField.text = "ABCDEFG\nHIJKLMN";
			textField.autoSize = TextFieldAutoSize.LEFT;
			textField.embedFonts = true;
			textField.selectable = false;
			textField.x = -textField.width / 2;
			textField.y = -textField.height / 2;
			textField.blendMode = BlendMode.INVERT;
			addChild(textField);
		}
	}


// Controller
	class Controller {
		// ----- Model への参照 -----
		private var _model:Model;
		
		// ----- Model の関数を呼び出す (Controller -> Model という流れ)-----
		internal function notifyFromControllerToModel(inputView:Button):void {
			// ユーザ入力に基づいて Model へ変更を要求する
			switch(inputView.sign) {
				case "position": {
					_model.update1();
					break;
				}
				case "scale": {
					_model.update2();
					break;
				}
				case "rotation": {
					_model.update3();
					break;
				}
			}
		}
		// ----- Model の関数を呼び出す (Controller -> Model という流れ)-----
		
		
		public function Controller(model:Model) {
			_model = model;
		}
	}


// Button (入力用 View)
	import flash.display.BlendMode;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	
	class Button extends Sprite {
		// ----- Controller への参照 -----
		public function set controller(value:Controller):void { _controller = value; }
		private var _controller:Controller;
		
		// ----- Controller へ通知するためのメンバ変数 -----
		public function get sign():String { return _sign; }
		private var _sign:String;
		// ----- Controller へ通知するためのメンバ変数 -----
		
		// ----- Controller の関数を呼び出す (入力用 View -> Controller という流れ)-----
		private function clickHandler(event:MouseEvent):void {
			_controller.notifyFromControllerToModel(this);
		}
		// ----- Controller の関数を呼び出す (入力用 View -> Controller という流れ)-----
		
		
		private const WIDTH:uint  = 100;
		private const HEIGHT:uint =  20;
		public function Button(sign:String) {
			// ボタンサインの保持
			_sign = sign;

			// ボタンシェイプ
			var up:Shape   = createButtonShape(0xCCCCCC);
			var over:Shape = createButtonShape(0xFFFFFF);
			var down:Shape = createButtonShape(0x000000);
			var button:SimpleButton = new SimpleButton(up, over, down, up);
			addChild(button);
			// ラベル
			var label:TextField = new TextField();
			label.text = sign + " boost";
			label.autoSize = TextFieldAutoSize.LEFT;
			label.selectable = false;
			label.x = (WIDTH - label.width) / 2;
			label.y = (HEIGHT - label.height) / 2;
			label.blendMode = BlendMode.INVERT;
			label.mouseEnabled = false;
			addChild(label);
			
			button.addEventListener(MouseEvent.CLICK, clickHandler);
		}
		private function createButtonShape(color:uint):Shape {
			var shape:Shape = new Shape();
			shape.graphics.lineStyle(0, 0x000000);
			shape.graphics.beginFill(color);
			shape.graphics.drawRect(0, 0, WIDTH, HEIGHT);
			shape.graphics.endFill();
			return shape;
		}
	}