状態遷移についてGoogle検索で調べたところ、 http://flash-scope.com/scene_change_with_function_call.html のソースコードが単純でわかりやすかった。
少し変更したのが以下。SceneではなくてPageと呼んでいるが、2つのページをクリックするたびに切り替える。(シーンというのは映画用語だと思うが、私は本派なのでページで)
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author itouhiro
*/
[SWF (backgroundColor="0xEEEEEE",frameRate="30",width="465",height="465")]
public class Main extends Sprite {
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
sceneTop();
}
private function sceneTop():void {
addChild(new Page(sceneRound1, 0x808080 + 0x808080 * Math.random() * 0.5));
}
private function sceneRound1():void {
addChild(new Page2(sceneTop, 0x808080 * Math.random() * 0.5));
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
class Page extends Sprite {
private var nextPage:Function;
public function Page(f:Function, c:uint):void {
nextPage = f;
graphics.beginFill(c);
//365 .. stage.stageWidth - 100。 stage.stageWidth だとerror
graphics.drawRect(365 * Math.random(), 365 * Math.random(), 100, 100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, onClick);
parent.removeChild(this);
nextPage();
nextPage = null;
}
}
class Page2 extends Sprite {
private var nextPage:Function;
public function Page2(f:Function, c:uint):void {
nextPage = f;
graphics.beginFill(c);
graphics.drawCircle(365 * Math.random(), 365 * Math.random(), 50);
graphics.endFill();
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, onClick);
parent.removeChild(this);
nextPage();
nextPage = null;
}
}https://sites.google.com/site/itouhiro/2013/20130602funccall.swf
この原始的て単純なコードを、以下で磨いていく。
http://www.project-nya.jp/modules/weblog/details.php?blog_id=1333 ではSceneは interface IScene で共通methodを持たせている。
同じようにやってみたけど、上のソースにinterfaceつけても特に意味はなかった。
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author itouhiro
*/
[SWF (backgroundColor="0xEEEEEE",frameRate="30",width="465",height="465")]
public class Main extends Sprite {
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
sceneTop();
}
private function sceneTop():void {
addChild(new Page1(sceneRound1, 0x808080 + 0x808080 * Math.random() * 0.5));
}
private function sceneRound1():void {
addChild(new Page2(sceneTop, 0x808080 * Math.random() * 0.5));
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
interface IPage {
function open():void;
function close(e:MouseEvent):void;
}
class Page1 extends Sprite implements IPage {
private var nextPage:Function;
public function Page1(f:Function, c:uint):void {
nextPage = f;
graphics.beginFill(c);
//365 .. stage.stageWidth - 100。 stage.stageWidth だとerror
graphics.drawRect(365 * Math.random(), 365 * Math.random(), 100, 100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, close);
}
public function open():void {
}
public function close(e:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, close);
parent.removeChild(this);
nextPage();
nextPage = null;
}
}
class Page2 extends Sprite implements IPage {
private var nextPage:Function;
public function Page2(f:Function, c:uint):void {
nextPage = f;
graphics.beginFill(c);
graphics.drawCircle(365 * Math.random(), 365 * Math.random(), 50);
graphics.endFill();
addEventListener(MouseEvent.CLICK, close);
}
public function open():void {
}
public function close(e:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, close);
parent.removeChild(this);
nextPage();
nextPage = null;
}
}サンプル2
http://www.kuma-de.com/blog/2010-02-03/1561 のソースを読んでみた。上の流れを参考にすると読むことができた。
Main見るとScene.getNextScene()で次に向かっているんだな。 あと、個々のシーンからMainに戻るために、個々のシーンでFunction.call()するのではなく、個々のシーンでDispatchEventでEvent.COMPLETEを投げてMainに制御を戻している。
https://sites.google.com/site/itouhiro/2013/20130603scene.swf
ソース Main.as
package {
import flash.display.Scene;
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author itouhiro
*/
[SWF (backgroundColor="0xEEEEEE",frameRate="30",width="465",height="465")]
public class Main extends Sprite {
private var scene:SceneBase;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
scene = new SceneTop();
addChild(scene);
scene.start();
scene.addEventListener(Event.COMPLETE, onComplete);
}
private function onComplete(e:Event):void {
scene.removeEventListener(Event.COMPLETE, onComplete);
var newScene:SceneBase = scene.getNext();
scene.stop();
removeChild(scene);
scene = null;
scene = newScene;
scene.init();
addChild(scene);
scene.start();
scene.addEventListener(Event.COMPLETE, onComplete);
}
}
}SceneBase.as (Sceneというクラス名は使えなかった)
package {
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author itouhiro
*/
public class SceneBase extends Sprite {
protected var nextScene:SceneBase;
public function SceneBase() {
super();
}
public function getNext():SceneBase {
return nextScene;
}
public function init():void {
}
public function start():void {
}
public function stop():void {
}
public function close():void {
dispatchEvent(new Event(Event.COMPLETE));
}
}
}SceneTop.as
package {
import flash.display.CapsStyle;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.StyleSheet;
import flash.text.TextField;
/**
* ...
* @author itouhiro
*/
public class SceneTop extends SceneBase {
public function SceneTop() {
init();
}
override public function init():void {
graphics.beginFill(0xCCCCCC);
graphics.lineStyle(3, 0x666666);
graphics.drawRoundRect(50, 50, 365, 365, 10, 10);
graphics.endFill();
var tf:TextField = new TextField();
var css:StyleSheet = new StyleSheet();
css.setStyle('p', { fontSize:'48px', fontFamily:'Verdana', fontWeight:'bold', color:'#FFFFFF' } );
tf.styleSheet = css;
tf.htmlText = '<p>Flash Quest</p>';
tf.width = 465;
tf.x = 70;
tf.y = 180;
addChild(tf);
}
override public function start():void {
var btnStart:Sprite = new Sprite;
var g:Graphics = btnStart.graphics;
g.beginFill(16731648, 1);
g.lineStyle(3, 0x000000, 0.8, true, "normal", CapsStyle.ROUND, JointStyle.ROUND, 1);
g.drawRoundRect(0, 0, 83, 37, 30, 30);
g.endFill();
btnStart.x = 100;
btnStart.y = 350;
addChild(btnStart);
btnStart.addEventListener(MouseEvent.CLICK, onClickStart);
}
private function onClickStart(e:MouseEvent):void {
nextScene = new SceneGame();
close();
}
override public function stop():void {
}
}
}SceneGame.as
package {
import flash.display.CapsStyle;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.StyleSheet;
import flash.text.TextField;
/**
* ...
* @author itouhiro
*/
public class SceneGame extends SceneBase {
public function SceneGame() {
init();
}
override public function init():void {
graphics.beginFill(0x996666);
graphics.lineStyle(3, 0xCC3333);
graphics.drawRoundRect(40, 80, 385, 305, 10, 10);
graphics.endFill();
var tf:TextField = new TextField();
var css:StyleSheet = new StyleSheet();
css.setStyle('p', { fontSize:'48px', fontFamily:'Verdana', fontWeight:'bold', color:'#FFFFFF' } );
tf.styleSheet = css;
tf.htmlText = '<p>PlayGame</p>';
tf.width = 465;
tf.x = 70;
tf.y = 180;
addChild(tf);
}
override public function start():void {
var btnStart:Sprite = new Sprite;
var g:Graphics = btnStart.graphics;
g.beginFill(0x00CC00, 1);
g.lineStyle(3, 0x000000, 0.8, true, "normal", CapsStyle.ROUND, JointStyle.ROUND, 1);
g.drawRoundRect(0, 0, 83, 37, 30, 30);
g.endFill();
btnStart.x = 280;
btnStart.y = 300;
addChild(btnStart);
btnStart.addEventListener(MouseEvent.CLICK, onClickStart);
}
private function onClickStart(e:MouseEvent):void {
nextScene = new SceneGameOver();
close();
}
override public function stop():void {
}
}
}SceneGameOver.as
package {
import flash.display.CapsStyle;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.StyleSheet;
import flash.text.TextField;
/**
* ...
* @author itouhiro
*/
public class SceneGameOver extends SceneBase {
public function SceneGameOver() {
init();
}
override public function init():void {
graphics.beginFill(0x000000);
graphics.drawRect(0, 120, 465, 225);
graphics.endFill();
var tf:TextField = new TextField();
var css:StyleSheet = new StyleSheet();
css.setStyle('p', { fontSize:'48px', fontFamily:'Verdana', fontWeight:'bold', color:'#FFFFFF' } );
tf.styleSheet = css;
tf.htmlText = '<p>GameOver</p>';
tf.width = 465;
tf.x = 70;
tf.y = 180;
addChild(tf);
}
override public function start():void {
var btnStart:Sprite = new Sprite;
var g:Graphics = btnStart.graphics;
g.beginFill(0xEEEE00, 1);
g.lineStyle(3, 0x999900, 0.8, true, "normal", CapsStyle.ROUND, JointStyle.ROUND, 1);
g.drawRoundRect(0, 0, 83, 37, 30, 30);
g.endFill();
btnStart.x = 200;
btnStart.y = 270;
addChild(btnStart);
btnStart.addEventListener(MouseEvent.CLICK, onClickStart);
}
private function onClickStart(e:MouseEvent):void {
nextScene = new SceneTop();
close();
}
override public function stop():void {
}
}
}
0 件のコメント:
コメントを投稿