おいしいAS3 -44ページ目

テーブルデータでページを作る

このクラス自体も表示オブジェクトにして
いろいろな種類のサムネール表示方法を
用意されたメソッドをインスタンスに
実行させるだけで実現できるようにしようとか

変なこといろいろかんがえたけど
なんやかんやで結局最初に戻った気がします

アニメーション関連は無理してオリジナルクラスでやらずに
TweenMaxとか使ったほうが賢いですからね

画像のURLを入れたフィールド名を
new Page(csv,{images:["フィールド名1","フィールド名1"]}
とやればデータの値を画像を読み込んだLoaderに置き換えるようにしてます

ここでiconとなるフィールド名も指定するんですが、略せます
でも略したらこのクラス使う意味が全然ないのですがね

なんでこんなつくりにしてるのかというと
後々このに設定できる値を増やして
アイコンを生成する以外のことをできるようにしたかったから

Tweenerで初めてこのコンストラクタの書き方をみたときは目から鱗でした

それまでは、任意な値を渡したい時は(...arg)でそれぞれ型を調べて・・・
とか回りくどいこと考えてましたよ


…で、

画像の読み込みが終わったらonCompFuncに設定された関数を実行します
この関数は画像を読み込んだ状態のテーブルデータを引数に実行されるので
それでアイコンのレイアウトとかしたりします

このアイコンはそれぞれにロールオーバー、ロールアウト、クリックの
マウスイベントに対してそれぞれの対応する行のデータを引数にして
onOverFunc,onOutFunc,onClickFuncで指定された関数を実行します
ここで内容の表示とかレイアウトとかさせるわけです


とりあえずseachメソッドつけました
こいつは静的じゃないのでインスタンスで使います

search({フィールド名:値,フィールド名:値…})でor検索します
意外にフィールド名日本語でもちゃんと動きますね
多分アウトな文字ってのはあるんでしょうがとりあえず
漢字かなまじりでもちゃんと動いてくれました

sliderMenuというのも作りましたがいまいちです
まあ、これはこれでありかな


/*
CSVクラス等が読み込んだ
テーブルデータを元に
指定されたフィールドの画像やタイトル等を受けて
ロールオーバー時、ロールアウト時、クリック時
それぞれが対応するオブジェクトを引数として
指定の関数を実行するアイコンを生成します


■パブリックプロパティ
dataSource テーブルデータをロードしてコンプリートイベントを発生させるクラスのインスタンス
data 読み込んだテーブルデータの指定のフィールドを画像や動画で置き換えたオブジェクトの配列、iconフィールドのみ追加の形

onCompFunc dataプロパティがそろったときにdataプロパティを引数に実行される関数、主にアイコンをレイアウトする為に使う
onOverFunc アイコンのロールオーバー時に各オブジェクトを引数に実行される関数、主に内容の説明を表示する為に使う
onOutFunc アイコンのロールアウト時に各オブジェクトを引数に実行される関数、主に内容の説明の表示終了の為に使う
onClickFunc アイコンのクリック時に各オブジェクトを引数に実行される関数、主に内容をレイアウトして表示する為に使う

■パブリックメソッド
Page(テーブルデータ、データ構成)
・データ構成オブジェクト
icon アイコンとなる画像のURLが入ったフィールド
images データロード後画像をロードする画像のURLのフィールドの配列

search({フィールド名:値,.....})

*/

package simplizer.page{

import flash.display.*
import flash.text.*
import flash.events.*
import flash.geom.*
import flash.net.URLRequest

public class Page extends EventDispatcher{

public var dataSource:EventDispatcher
public var data:Array=new Array()
public var onCompFunc:Function=function(data:Array){}
public var onOverFunc:Function=function(tgt:Object){}
public var onOutFunc:Function=function(tgt:Object){}
public var onClickFunc:Function=function(tgt:Object){}

private var images:Array=new Array()

public function Page(src:EventDispatcher,fldObj:Object){
dataSource=src
fldObj.icon=fldObj.icon||""
fldObj.images=fldObj.images||[]
fldObj.dummyIcon=fldObj.dummyIcon||"noimage.jpg"
fldObj.dummyImage=fldObj.dummyImage||"noimage.jpg"
src.addEventListener(Event.COMPLETE,init)
function init(e){
for each(var row in (src as Object).data){
var newRow=new Object()
for(var col in row){
if(col==fldObj.icon){
newRow.icon=new MovieClip()
if(fldObj.images.some(function(tgt){return (tgt==col)})){
newRow.icon.image=newRow.icon.addChild(new Loader())
images.push(newRow.icon.image)
with(newRow.icon.image){
load(new URLRequest(row[col]||fldObj.dummyIcon))
}
}else{
newRow.icon.text=newRow.icon.addChild(new TextField())
with(newRow.icon.text){
text=row[col]
background=true
selectable=false
}
}
with(newRow.icon){
addEventListener(MouseEvent.ROLL_OVER,makeListener("Over",newRow))
addEventListener(MouseEvent.ROLL_OUT,makeListener("Out",newRow))
addEventListener(MouseEvent.CLICK,makeListener("Click",newRow))
}
}
if(fldObj.images.some(function(tgt){return (tgt==col)})){
newRow[col]=new Loader()
newRow[col].load(new URLRequest(row[col]||fldObj.dummyImage))
images.push(newRow[col])
}else{
newRow[col]=row[col]
}
}
data.push(newRow)
}
addEventListener(Event.COMPLETE,makeListener("Comp"))
var cnt=images.length
if(cnt==0)this.dispatchEvent(new Event(Event.COMPLETE))
for each(var img in images){
img.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e){
e.target.removeEventListener(e.type,arguments.callee);
cnt--;
if(cnt==0)dispatchEvent(new Event(Event.COMPLETE));})
}
}
function makeListener(type:String,tgt:Object=null):Function{
switch(type){
case "Over":
return function(e){onOverFunc(tgt)}
break;
case "Out":
return function(e){onOutFunc(tgt)}
break;
case "Click":
return function(e){onClickFunc(tgt)}
break;
case "Comp":
return function(e){onCompFunc(data)}
break;
default:
return null
}
}
}
public function search(keyObj):Array{
var rtn=new Array()
var filterFnc=function(tgt){
var frg:Boolean=false
for(var nm in keyObj){
frg=tgt[nm]==keyObj[nm]
if(frg)break;
}
if(frg)frg=rtn.indexOf(tgt)==-1
return frg
}
rtn=data.filter(filterFnc)
return rtn
}
public static function slideMenu(rowList:Array,paramObj:Object):Sprite{
var rtn=new Sprite()
paramObj.iconWidth=paramObj.iconWidth||80
paramObj.iconHeight=paramObj.iconHeight||80
paramObj.margine=paramObj.margine||0
paramObj.width=paramObj.width||550
for(var i in rowList){
var maskRct=rowList[i].icon.addChild(new Sprite())
with(maskRct.graphics){
beginFill(0)
drawRect(0,0,paramObj.iconWidth,paramObj.iconHeight)
endFill()
}
rowList[i].icon.image.mask=maskRct
with(rowList[i].icon.image.content){
scaleX=scaleY=Math.max(paramObj.iconWidth/width,paramObj.iconHeight/height)
}
rtn.addChild(rowList[i].icon)
}
rtn.addEventListener(Event.ADDED_TO_STAGE,function(e){rtn.addEventListener(Event.ENTER_FRAME,frameTick)})
rtn.addEventListener(Event.REMOVED_FROM_STAGE,function(e){rtn.removeEventListener(Event.ENTER_FRAME,frameTick)})
var totalLen=rowList.length*(paramObj.iconWidth+paramObj.margine)
var dst=0
var frg=false
function frameTick(e){
if((rtn.mouseY>paramObj.iconHeight||rtn.mouseY<0)&&frg)return;
frg=true
dst=dst+(rtn.mouseX*totalLen/paramObj.width-paramObj.width/2-dst)/8
for(i in rowList){
var minX=i*paramObj.margine
var maxX=paramObj.width-paramObj.iconWidth+(i-rowList.length+1)*paramObj.margine
rowList[i].icon.x=Math.min(Math.max(-dst+i*(paramObj.iconWidth+paramObj.margine),minX),maxX)
if(rowList[i].icon.x>paramObj.width/2){
rtn.setChildIndex(rowList[i].icon,0)
}else{
rtn.setChildIndex(rowList[i].icon,rtn.numChildren-1)
}
}
}
return rtn
}
}
}

最大公約数、最小公倍数を求める

アクセス解析見るとフリーのASのコードを
探してきてる人がいるみたいだから
お土産になるもんでも一つぐらい
置いとこうかなと思って
オリジナルクラスのライブラリを見てみたのだけど

ひどいな・・・


なにせ一つのクラスになんでもかんでも詰め込み過ぎで
Effectクラスが約500行
Pictクラスが約650行
Ballクラスが約700行ある

Effectクラスは80%ぐらいが
フィルタとかマトリックスを
簡単に生成するための静的メソッドで

Pictクラスも80%ぐらいが
ポイントの配列を加工したり
色を生成したりするための静的メソッド

BallクラスはそもそもはMCにマウスチェイサーとか
何かを追いかけたり何かから逃げたりとか
するような動作をさせる為のクラスなんだけど
その名の通り簡単な球の当たり処理とかするので
この処理がほとんどを占めてる


とてもじゃないけどブログにコードを丸ごと乗せれる量じゃない

ってことで手みやげ程度に最大公約数を求めるメソッドと
最小公倍数を求めるメソッドでも載せとこう




private static function getComDiv(A:int,B:int):int {
var a=Math.max(A,B);
var b=Math.min(A,B);
while (a%b!==0) {
var n=a%b;
a=b;
b=n;
}
return b;
}//最大公約数
private static function getComMul(A:int,B:int):int {
return A * B / getComDiv(A,B);
}//最小公倍数




属性がprivateなのはあんまり使わないからですね

結局・・・

クラス構成どうするか
どこまでやるのか
どういうプロパティとメソッド用意するのかとか
そんなん考えるだけで終わってしまった・・・


脱線し過ぎ


風呂のなかで考えてた事は
落下運動のムービーを
時間プロパティなしでやる方法だった・・・


空気抵抗を無視できるなら

移動した距離+=(移動した距離*2/加速度)^(1/2)*加速度+加速度

とやれば時間のプロパティがなくても
落下運動が表現できる

こんなカンジ



with (new Timer(50,100)) {
addEventListener(TimerEvent.TIMER,timeTick);
start();
}
var dst=0
var g=0.5
function timeTick(e) {
dst+=Math.sqrt(dst*2/g)*g+g
with(this.graphics){
beginFill(0)
drawEllipse(275,dst,5,5)
endFill()
}
}



落下運動の表現で、動かされるもの以外は
ENTER_FRAMEのリスナー関数のなかで
プロパティを完結させたかったので
こんなことを考えてました

これだと結局外にプロパティ作ってるから意味ないんですが