[Study]最低限のaddEventListenerのための関数


umhr_studyaddEventListenerの管理が大変なときがあるので、簡単にするための関数。

たとえばデータを次々に読み込んでオブジェクトを配置しなおすような場合、
その管理が大変になることがある。
また、3D空間内で空気遠近法を使ったりで、手前に薄い霧がかかり、
その奥のオブジェクトをクリックしたい場合、判別が難しい。

そんな時、getObjectsUnderPointを活用して、マウスの下のオブジェクトのリストを取得し、
その、(ルールを決めた)一番手前のオブジェクトを返すようにすれば、解決する。

それをまとめたのがMousePointクラス。

MousePoint.objectFromStage(stage)で、
マウス下の名前をつけた一番手前のobjectを返す。

nameを明示的につけたものだけを対象する場合はinNamed = trueにする。

さらに条件をつけたいときには、isNegativaFnに関数を割り当てる。
はじく条件なので、注意。

おそらく、実務では、ルール付けをしたうえでobjectを返すほうが使えると思う。
霧の向こうのオブジェクトがほしい場合は、霧自体は無視してほしいから。

090529修正
inNamed = falseにデフォルト値を修正。
targetを一括で設定できるように修正。

 
このデモでは
addEventListenerはひとつだけで、クリックしたオブジェクトを取得し、右へ5px移動する。
ただし、名前をつけていないものと8文字以上の名前をつけたものには反応しない。

[sourcecode language=”as3″]
/*
◆addEventListenerの管理が大変なときがあるので、簡単にするための関数。

このデモでは
addEventListenerはひとつだけで、クリックしたオブジェクトを取得し、右へ5px移動する。
ただし、名前をつけていないものと8文字以上の名前をつけたものには反応しない。

たとえばデータを次々に読み込んでオブジェクトを配置しなおすような場合、
その管理が大変になることがある。
また、3D空間内で空気遠近法を使ったりで、手前に薄い霧がかかり、
その奥のオブジェクトをクリックしたい場合、判別が難しい。

そんな時、getObjectsUnderPointを活用して、マウスの下のオブジェクトのリストを取得し、
その、(ルールを決めた)一番手前のオブジェクトを返すようにすれば、解決する。

それをまとめたのがMousePointクラス。

MousePoint.objectFromStage(stage)で、
マウス下の名前をつけた一番手前のobjectを返す。

nameを明示的につけたものだけを対象する場合はinNamed = trueにする。

さらに条件をつけたいときには、isNegativaFnに関数を割り当てる。
はじく条件なので、注意。

おそらく、実務では、ルール付けをしたうえでobjectを返すほうが使えると思う。
霧の向こうのオブジェクトがほしい場合は、霧自体は無視してほしいから。

090529修正
inNamed = falseにデフォルト値を修正。
targetを一括で設定できるように修正。

*/
package {
import flash.display.Sprite;
import flash.text.TextFormat;
import flash.events.MouseEvent;
import flash.text.TextField;
public class Main extends Sprite {
public function Main() {
MakeUI.defaultTextFormat = new TextFormat("_sans", 18);

//薄緑の角丸四角。nameとbuttonModeを設定。わかりやすいように行を分けている。
var _sp:Sprite = MakeUI.newSprite([20,0],[["rotation",24]],[["beginFill",[0xC9D787,1]],["drawRoundRect",[10,10,250,250,50]]]);
_sp.name = "薄緑の角丸四角";
_sp.buttonMode = true;
stage.addChild(_sp);

//一行でまとめるとこんな感じ。
stage.addChild(MakeUI.newSprite([150, 350], [["name", "濃い緑の丸"], ["buttonMode", true]], [["beginFill", [0x7D8A2E, 1]], ["drawCircle", [0, 0, 100]]]));
stage.addChild(MakeUI.newShape([300, 250], [["name", "青い四角"]], [["beginFill", [0x0000FF, 1]], ["drawRect", [0, 0, 100, 100]]]));

//「サーモンピンクの楕円」は8文字以上なので反応しない。
stage.addChild(MakeUI.newSprite([50, 100], [["name", "サーモンピンクの楕円"]], [["beginFill", [0xFFC0A9, 1]], ["drawEllipse", [0, 0, 200, 100]]],MakeUI.newTextField([20,30,200,null,"8文字以上の名前",0xFFFFFF],[["name","12345678"],["selectable",false]])));

//nameを指定していないので、反応しない。
stage.addChild(MakeUI.newSprite([350, 10], null, [["beginFill", [0xFF8598, 1]], ["drawRect", [0, 0, 100, 100]]], MakeUI.newTextField([20, 30, 200, null, "ななし", 0xFFFFFF], [["selectable", false]])));

//下のテキストエリア
var dtxt:TextField = MakeUI.newTextField([50,400,400,50,"ステージ上をクリックしてください"],[["border",true],["name","テキストエリア"]]);
stage.addChild(dtxt);

//はじく条件
MousePoint.isNegativaFn = function(obj:Object):Boolean {
var str:String = obj.name;
var _is:Boolean;
//8文字以上の場合はtrueを返す=はじく
if(str.length > 7){
_is = true
}
return _is;
};

//名前がついている物だけを対象にする
MousePoint.isNamed = true;

//ターゲットを指定
MousePoint.target = stage;

//addEventListenerはひとつだけ
stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void{
var obj:Object = MousePoint.objectFromStage();
if(obj){
obj.x += 5;
dtxt.text = obj.name;
}else{
dtxt.text = "なんもないよ";
}
}

}
}
}

import flash.geom.Point;
class MousePoint extends Sprite {
public static var isNamed:Boolean;
public static var isNegativaFn:Function = function(obj:Object):Boolean{return false};
public static var target:Object;
public static function objectFromStage(argTarget:Object = null):Object {
if(!argTarget){
if(target){
argTarget = target;
}else{
trace("targetが指定されていません");
return null;
}
}

var list:Array = argTarget.getObjectsUnderPoint(argTarget.localToGlobal(new Point(argTarget.mouseX , argTarget.mouseY)));
var l:int = list.length;
var _result:String = null;
if(l > 0){
//上から順にnameを確認
for (var i:int = l-1; i>=0; i–) {
var str:String = list[i].name;
if (isNamed && str.substr(0, 8) == "instance" && !isNaN(parseInt(str.substr(8)))) {
//nameを設定をしてないと、instance123とかの名前になる。
//よって、この関数を使うには「instance123」(数字部は恐らくAVM起動後のinstanceの数)以外の名前にすること。
//nameを付けないオブジェクトに対して動作を指定したい場合はこちらに記入。
}else if (isNegativaFn(list[i])) {
//isNegativaの関数の条件がtrueの時にはここにくる。
}else{
return list[i];
}
}
};
return null;
}
}

/////////////////////////////////////////////////////////////////////////////

import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.BitmapData;
import flash.display.Bitmap;
class MakeUI{
public static var defaultTextFormat:TextFormat = new TextFormat();
public static function newShape(x_y_w_h_sh:Array = null,property:Array=null,graphics:Array=null):Shape{
var i:int;
var sh:Shape;
if(x_y_w_h_sh && x_y_w_h_sh[4]){
sh = x_y_w_h_sh[4];
}else{
sh = new Shape();
}
if(x_y_w_h_sh){
if (x_y_w_h_sh[0]) { sh.x = x_y_w_h_sh[0] };
if (x_y_w_h_sh[1]) { sh.y = x_y_w_h_sh[1] };
}
if(property){
for (i = 0; i < property.length; i++) {
if(property[i] && property[i].length > 1){
sh[property[i][0]] = property[i][1];
}
}
}
if(graphics){
for (i = 0; i < graphics.length; i++) {
if(graphics[i] && graphics[i].length > 1){
sh.graphics[graphics[i][0]].apply(null, graphics[i][1]);
}
}

}
if(x_y_w_h_sh){
if (x_y_w_h_sh[2]) { sh.width = x_y_w_h_sh[2] };
if (x_y_w_h_sh[3]) { sh.height = x_y_w_h_sh[3] };
}
return sh;
}
public static function newSprite(x_y_w_h_sp:Array = null,property:Array=null,graphics:Array=null,addChild:DisplayObject = null):Sprite{
var i:int;
var sp:Sprite;
if(x_y_w_h_sp && x_y_w_h_sp[4]){
sp = x_y_w_h_sp[4];
}else{
sp = new Sprite();
}
if(x_y_w_h_sp){
if (x_y_w_h_sp[0]) { sp.x = x_y_w_h_sp[0] };
if (x_y_w_h_sp[1]) { sp.y = x_y_w_h_sp[1] };
}
if(property){
for (i = 0; i < property.length; i++) {
if(property[i] && property[i].length > 1){
sp[property[i][0]] = property[i][1];
}
}
}
if(graphics){
for (i = 0; i < graphics.length; i++) {
if(graphics[i] && graphics[i].length > 1){
sp.graphics[graphics[i][0]].apply(null, graphics[i][1]);
}
}

}
if(addChild){
sp.addChild(addChild);
}
if(x_y_w_h_sp){
if (x_y_w_h_sp[2]) { sp.width = x_y_w_h_sp[2] };
if (x_y_w_h_sp[3]) { sp.height = x_y_w_h_sp[3] };
}
return sp;
}

public static function newTextField(x_y_w_h_txt_color_alpha:Array = null,property:Array=null,method:Array=null):TextField{
var i:int;
var ta:TextField = new TextField();
ta.defaultTextFormat = defaultTextFormat;
if(x_y_w_h_txt_color_alpha){
if (x_y_w_h_txt_color_alpha[0]) { ta.x = x_y_w_h_txt_color_alpha[0] };
if (x_y_w_h_txt_color_alpha[1]) { ta.y = x_y_w_h_txt_color_alpha[1] };
if (x_y_w_h_txt_color_alpha[2]) { ta.width = x_y_w_h_txt_color_alpha[2] };
if (x_y_w_h_txt_color_alpha[3]) { ta.height = x_y_w_h_txt_color_alpha[3] };
if (x_y_w_h_txt_color_alpha[4]) { ta.text = x_y_w_h_txt_color_alpha[4] };
if (x_y_w_h_txt_color_alpha[5]) { ta.textColor = x_y_w_h_txt_color_alpha[5] };
if (x_y_w_h_txt_color_alpha[6]) { ta.alpha = x_y_w_h_txt_color_alpha[6] };
}
if(property){
for (i = 0; i < property.length; i++) {
if(property[i] && property[i].length > 1){
ta[property[i][0]] = property[i][1];
}
}
}
if(method){
for (i = 0; i < method.length; i++) {
if(method[i] && method[i].length > 1){
ta[i].apply(null, method[i][1]);
}
}
}
return ta;
}
/*
//以下はテスト
public static function pozObject(x:Number=NaN,y:Number=NaN,width:Number=NaN,hight:Number=NaN,obj:Object = null):Object{
if(x){obj.x = x}
if(y){obj.y = y}
return obj;
}
public static function newBitmap(x:Number=NaN,y:Number=NaN,width:Number=NaN,hight:Number=NaN,bd:BitmapData = null):Bitmap{
var b:Bitmap = new Bitmap(bd);
if(x){b.x = x}
if(y){b.y = y}
return b;
}
*/
}
[/sourcecode]