(メインページへ)
今日のTips

今日のTips

一定時間待つ

ムービークリップの再生を一定時間だけ停止したいってことありますよね。
Flashではムービークリップが停止stop()しても、その中に配置してあるムービークリップは停止しないので、ループアニメーションを一定時間だけ再生したいというときに便利に使えるスクリプトです(言ってる意味わかります?)。

class Navi {
var mc:MovieClip;
var waitTimer:Number;
//コンストラクタ
function Navi(targetMC:MovieClip) {
mc = targetMC;
}
//一定時間待つ
function waitAndPlay(milisec:Number) {
mc.stop();
clearInterval(waitTimer);
waitTimer = setInterval(this, "timeout", milisec);
}
//タイムアウト
function timeout() {
clearInterval(waitTimer);
mc.play();
}
}

使い方は簡単。まず、再生を一旦停止したいムービークリップのタイムラインの最初のフレームアクションで次のようにNaviクラスのインスタンスを作ります。

var naviObj:Navi = new Navi(this);

次に、一旦停止をしたいフレームをキーフレームにし、3秒間止めたいならば次のフレームアクションを書きます。

naviObj.waitAndPlay(3000);

さらに別のフレームで5秒間止めたければ、そのフレームをキーフレームにして次のフレームアクションを書きます。

naviObj.waitAndPlay(5000);

メインのタイムライン、個々のムービークリップのタイムラインごとにNaviクラスのインスタンスを作っておけば、それぞれのムービークリップごとに一定時間停止を自由に指定できるようになりますね。

個別リンク | コメント (0)

クラス定義内でのクラスメンバーの参照

クラスメンバーを参照するには、「クラス名. クラスメンバー」の書式を使いますが、クラス定義内では自身のクラスメンバーをクラスメンバー名だけで参照できます。次のサンプルでは3つのボタンがグループ化されています。どのボタンがハイライトになっているかをクラスプロパティで管理しています。







↓解説とサンプルのダウンロード


サンプルファイルのダウンロード

このサンプルでは、ButtonGroupクラスのselectedBtnクラスプロパティでハイライトになっているムービークリップを管理しています。ムービークリップをクリックされたならばselectBtn()メソッドを呼び出し、まず、selectedBtnクラスプロパティにで管理しているそれまで選ばれていたムービークリップをフレーム"off"に移動します。次に、クリックされたムービークリップ自身をフレーム"on"に移動して、さらにselectedBtnクラスプロパティに登録します。

ButtonGroupクラス定義ファイル
class ButtonGroup {
static var selectedBtn:MovieClip;
var mc:MovieClip;
//コンストラクタ関数
function ButtonGroup(targetMC:MovieClip) {
mc = targetMC;
}
//ボタンの選択
function selectBtn() {
if (selectedBtn != undefined) {
selectedBtn.gotoAndStop("off");
}
mc.gotoAndStop("on");
selectedBtn = mc;
}
}

このムービーのメインのタイムラインのフレームアクションでは、グループにするボタンのムービークリップのインスタンスをButtonGroupクラスに登録しています。これにより、ムービークリップがクリックで動作するようになり、クリックによってselectBtn()メソッドが呼び出されるようになります。

//グループ化するムービークリップを登録する
var btn1:ButtonGroup = new ButtonGroup(yamaBtn.tab);
var btn2:ButtonGroup = new ButtonGroup(kawaBtn.tab);
var btn3:ButtonGroup = new ButtonGroup(umiBtn.tab);
//ムービークリップのクリックでButtonGroupクラスのインスタンスのメソッドを呼び出す
yamaBtn.onPress = function() {
btn1.selectBtn();
};
kawaBtn.onPress = function() {
btn2.selectBtn();
};
umiBtn.onPress = function() {
btn3.selectBtn();
};

個別リンク | コメント (0)

移動するラベルをリスト管理しよう(その1)

さてさて、次のムービーはどういう作り、スクリプトになっているでしょうか?ちょっと考えてみてください。簡単じゃん?







ヒント1:
ステージにはabcMorphというインスタンスが置いてあり、abcMorphムービークリップのタイムラインの1フレーム目には、次のフレームアクションが書いてあります。"a", "b", "c"...は、アニメーションの区切りとなるキーフレームのフレームラベル名です。

var labels =["a", "b", "c", "d", "e"];

個別リンク | コメント (0)

移動するラベルをリスト管理しよう(その2)

「移動するラベルをリスト管理しよう(その1)」に掲載したムービーでは、次のNaviLabelクラスを使っています。このクラスをどのように使えばいいか考えてみてください。

naviLabel.zipのダウンロード

class NaviLabel {
var mc:MovieClip;
var labels:Array;
var loop:Boolean;
var currentPos:Number = 0;
//コンストラクタ
function NaviLabel(targetMC:MovieClip, lbs:Array, loopMode:Boolean) {
mc = targetMC;
labels = lbs;
loop = loopMode;
}
//先頭のラベルへ
function topLabel():Void {
var labelName:String = labels[0];
mc.gotoAndPlay(labelName);
}
//最後のラベルへ
function lastLabel():Void {
var lastPos:Number = labels.length-1;
var labelName:String = labels[lastPos];
mc.gotoAndPlay(labelName);
}
//次のラベルへ
function nextLabel():Void {
var nextPos:Number = currentPos+1;
if (nextPos< labels.length ) {
currentPos = nextPos;
} else if (nextPos == labels.length) {
if (loop) {
currentPos = nextPos=0;
}
}
var labelName:String = labels[nextPos];
mc.gotoAndPlay(labelName);
}
//手前のラベルへ
function prevLabel():Void {
var prevPos:Number = currentPos-1;
if (prevPos>=0) {
currentPos = prevPos;
} else if (prevPos<0) {
if (loop) {
currentPos = prevPos=(labels.length-1);
}
}
var labelName:String = labels[prevPos];
mc.gotoAndPlay(labelName);
}
}

個別リンク | コメント (0)

山川海(その2)

クラス定義内でのクラスメンバーの参照」で紹介したButtonGroupクラスですが、これってもっと単純なことだと気付いちゃいませんでしたか?
ButtonGroupクラスを次のように書き換えたらどうでしょうか?

buttongroup2.zipのダウンロード

class ButtonGroup {
static var selectedBtn:MovieClip;
//ボタンの選択
static function selectBtn(mc:MovieClip) {
if (selectedBtn != undefined) {
selectedBtn.gotoAndStop("off");
}
mc.gotoAndStop("on");
selectedBtn = mc;
}
}

そして、yamaKawaUmi.flaのフレームアクションはたったこれだけ。これでよくないかな?

yamaBtn.onPress = function() {
ButtonGroup.selectBtn(this.tab);
};
kawaBtn.onPress = function() {
ButtonGroup.selectBtn(this.tab);
};
umiBtn.onPress = function() {
ButtonGroup.selectBtn(this.tab);
};

ここまで単純化できてうれしいー!クラスメンバー万歳!と感じいったところで新たな不満がむくむくと・・・
このButtonGroupクラスだと1つのグループしか管理できないではないですか。Aグループ、Bグループが必要なときは、A_ButtonGroupクラス、B_ButtonGroupクラスと2つのクラス定義が必要になってしまう。
う〜ん、かっこ悪い。やっぱ、こういうときこそインスタンスメンバーの出番なのでは?どうする?

個別リンク | コメント (0)

山川海(その3)

ボタングループといってもボタンをリストで管理するなどしてグループ化する必要はなく、ハイライト情報だけを管理すればいいのです。だったら、これで十分だったのです。

buttongroup3.zipのダウンロード


class ButtonGroup {
var selectedBtn:MovieClip;
//コンストラクタ関数
function ButtonGroup() {
}
//ボタンの選択
function selectBtn(mc:MovieClip) {
if (selectedBtn != undefined) {
selectedBtn.gotoAndStop("off");
}
mc.gotoAndStop("on");
selectedBtn = mc;
}
}

Aグループ、Bグループが必要なときは、それぞれ次のようにButtonGroupクラスのインスタンスを作ればよいわけで、

var groupA: ButtonGroup = new ButtonGroup();
var groupB: ButtonGroup = new ButtonGroup();

そして、次のようにインスタンスのselectBtnメソッドにクリックされたボタンのインスタンスを送ればいいんですね。

yamaBtnA.onPress = function() {
groupA.selectBtn(this.tab);
};
kawaBtnA.onPress = function() {
groupA.selectBtn(this.tab);
};
umiBtnA.onPress = function() {
groupA.selectBtn(this.tab);
};
//
yamaBtnB.onPress = function() {
groupB.selectBtn(this.tab);
};
kawaBtnB.onPress = function() {
groupB.selectBtn(this.tab);
};
umiBtnB.onPress = function() {
groupB.selectBtn(this.tab);
};








個別リンク | コメント (0)

playlistという考え方(その1)

好きな曲を3曲入れたプレイリストがあるとします。そして3曲を順に再生します。次のようなメソッドを作ったとしましょう。

function プレイリストを続けて再生(){
プレイリストの1曲目再生開始;
プレイリストの2曲目再生開始;
プレイリストの3曲目再生開始;
}

これでOKのように思えますが、ちょっと考えてみてください。これだと3曲がいっぺんにかかってしまいませんか?本来ならば、1曲目が終わったら2曲目へ、2曲目が終わったら3曲目へと再生しなければならないですよね。
まったくこれと同じことが図を描くときにも言えます。三角形を描くことはさほど難しくないですが、三角形を1辺ずつ描くにはどうすればいいでしょう?やり方はいろいろありそう?

個別リンク | コメント (0)

Google MapsモドキFlash

Google Mapsのような画像表示を行うFlashを作ってみました。大量のモザイク的な画像を扱えます。某プロジェクトの一部で使うための試作です。このバージョンでは、ドラッグ操作のみに対応しています。

Google MapsモドキFlash
Yoogle Maps a02

個別リンク | コメント (0)

Flash Player 7以降での_global変数の注意点

拙著の「ActonScriptスーパーサンプル集」(ピンク色の本)のp.119「雪が降るアニメーション」がどーしてもちゃんと動かないという質問をいただきました。サンプルファイルはちゃんと動くのになぜ〜というものです。

その原因は、この本がFlash MX対応つまりFlash Player 6対応で書かれているからです。そして、サンプルファイルがうまく動作する理由は、パブリッシュ設定がFlash Player 6になっているからです。Flash Player 7以降の設定でパブリッシュするとうまく動作しない部分があるんです。

Flash Player 7以降で_global変数を使う場合には、次のように_global.depthの初期化が必要になってしまいました。p.120の該当箇所を次のように修正して試してみてください。

function init() {
//擬似的な深度
if (_global.depth == undefined) {
_global.depth = 1;
} else {
myDepth = ++_global.depth;
}
//遠くほど小さく、手前ほど大きくする
this._width = 3+0.5*myDepth;
this._height = 3+0.5*myDepth;
//半透明
this._alpha = 50;
}

※このページ以外にも同様のスクリプトがあります。Flash Player 7以降に対応するためには修正してご利用ください。

個別リンク | コメント (1)

Pointクラスを使おう

Flash 8に座標をx,yで管理できるPointクラスが追加されました。x座標、y座標をペアで扱えるので便利ですね。Pointクラスの機能は意外とシンプルなので自分でも作れそうです。実際、ぼくはFlash 7でもPointクラスをカスタム定義して使っています。Pointクラスは次のように定義できますね。
(注意:Flash 8のPointクラスの使い方ではありません)


(訂正:addは予約語でコンパイルできなかったのでplusに変更しました)

class Point {
var x:Number;
var y:Number;
//コンストラクタ
function Point(x:Number, y:Number) {
this.x = x;
this.y = y;
}
//point同士の足し算
function plus(pt:Object):Point {
x += pt.x;
y += pt.y;
return this;
}
//point同士の引き算
function subtract(pt:Object):Point {
x -= pt.x;
y -= pt.y;
return this;
}
}

使うときには、こんな感じ。
var pointA:Point = new Point(5, 50);
var pointB:Point = new Point(100, 200);
var pointC = pointA.plus(pointB);
これで、pointCは{x:105,y:250}の値をもったデータになります。

でも、これだけではいまいち面白くない。Flash8も面白くない。せっかく座標をポイントで指定できるのだから、次のようにムービークリップの座標を指定できると便利だと思いませんか?

myMC.loc = pointA;

あれ?MovieClipクラスにlocプロパティなんてあったっけ?
ありません。なければ作るわけです。次のようにMovieClipクラスを継承するExtMovieClipクラスを定義し、ムービークリップシンボルにリンケージします。
プロパティの値を=で設定・参照できるようにgetter / setterの機能を使ったfunctionを書いちゃいます。


class ExtMovieClip extends MovieClip {
//
//getter / setter
//------ loc
function set loc(pt:Object) {
this._x = pt.x;
this._y = pt.y;
}
//
function get loc():Object {
var pt:Object = new Object();
pt.x = this._x;
pt.y = this._y;
return pt;
}
}

以上です。わかりました?

個別リンク | コメント (0)

リングフォーメーションの意味

「日本の伝統音楽『楽器編』」は「インターフェースを懲りすぎ!」という声もありますが、実際ぼくも作りながらにコレでいいのか?と思ってましたが、できあがってみるとなかなか考えられていると思えてきました。

wagakki_ring.jpg
箏(こと)の楽器データ

「楽器図鑑」ではリング状にアイテムが並ぶデザインが使ってあります。リング状になっていることから、
1.ぐるっと回ることがわかる。
2.データの要素の種類と量を一度に俯瞰(ふかん)できる。
3.要素にダイレクトにアクセスできる。
4.マウス操作だけでデータを選べる。

リング状に並んだアイテムは、詳しく観たいアイテムを選ぶインターフェースである以前に、選ばれた楽器の属性データでもあるという点にも着目してください。それが2番の意味です。
これに比較し「演奏図鑑」というコンテンツはアイテムが直線的に並んでいます。リニア状であることから、アイテムの並びには順番があり、1個ずつ順に見てくださいということを示しています。
通常、これぐらい大量のデータをもったデーターベースをブラウジングするには、それなりのコンピュータリテラシーが必要ですが、「楽器図鑑」ではとりあえず興味の向くままに触っているだけで多くのデータに触れることができるかと思います。全体的にボードゲームの感覚(自分の持ちカードをひろげる感じ)で作ってあり、アニメーションのコンセプトは昔のゲームのゼビウスなんですよ。

リングフォーメーションの習作
test-ring1.jpg

リニアフォーメーションの習作
linear.jpg

個別リンク | コメント (3)

ロールオーバーで再生と逆再生

この絵を見て「ん?」って思った人もいるでしょうね。ピンク色の表紙「FLASH ActionScriptスーパーサンプル集」の「03-1ロールオーバーで再生と逆再生」のサンプルです。
このサンプルを動作を同じままでスクリプトを書き換えてみました。サンプルは2個あって、1つはムービークリップシンボルにフレームアクションを書き込んだスタイル。もう1つはMovieClipクラスを拡張したPistonクラスをリンケージするスタイルです。

サンプル:
piston.jpg

スクリプトリストとflaファイルのダウンロードのリンクは「続き・・・」にあります↓


Pistonクラス:
class Piston extends MovieClip {
var rollover:Boolean = false;
//
//最初は停止から始める
//
function onLoad() {
stop();
}
//
//マウスカーソルがロールオーバーした
//
function onRollOver() {
//ロールオーバー開始
rollover = true;
onEnterFrame = animation;
}
//
//マウスカーソルがロールアウトした
//
function onRollOut() {
//ロールオーバー終了
rollover = false;
onEnterFrame = animation;
}
//
//フレームが進む度に実行
//
function animation() {
if (rollover) {
//次のフレームへ進む(最終フレームでは無視される)
nextFrame();
} else {
//手前のフレームに戻る(先頭フレームでは無視される)
prevFrame();
}
//先頭または最後のフレームに到達したらアニメーションを終了する
if ((_currentframe == 1) || (_currentframe == _totalframes)) {
//onEnterFrameイベントハンドラを消去する
delete onEnterFrame;
}
}
}

flaファイルとasファイルはココからダウンロードできます。→ダウンロード

個別リンク | コメント (0)

雪が降るアニメーション

ピンク本「Flash ActionScriptスーパーサンプル集」の「07-1 雪が降るアニメーション」もFlash 8用に書き換えてみました。ただ、見た目はほとんど同じですが、手法はまったく別のやり方になっています。
雪のインスタンスを[start]ボタンでアタッチし、アタッチした複数のインスタンスを配列で管理する方法に書き換えてあります。カスタムクラスは使っていませんが、ムービークリップのインスタンスをアタッチ・消去する、配列で管理するというサンプルになっています。


サンプル:
snow8.jpg

flaファイルはココからダウンロードできます。→ダウンロード

個別リンク | コメント (2)

ホッピングするボール

ボールをクリックすると落下して地面で跳ね返ります。ボールの位置はドラッグできて、どこからでも落とすことができます。傾斜にぶつかったら斜めに跳ね返らないのかよ〜っていうのは、スクリプトを単純化するために省略です。
いったいどうやっているのか考えてみてください? 斜めに跳ね返らせる方法もね。
地面を突き抜けないようにするくふうもポイント。

サンプル:
hopping.jpg

flaファイルはココからダウンロードできます。→ダウンロード

個別リンク | コメント (0) | トラックバック

障害物と方向転換

ちょっと変わったサンプルを作ってみました。障害物となるインスタンスの中に入ると進む向きを変更します。動きをよく観察してみてください。

衝突チェックはMovieClip.hitTest()で行います。
var hit:Boolean = hit_mc.hitTest(_x, _y, true);

移動から衝突チェックまでのスクリプト(抜粋)は次のようになります。vx、vyがベクトルの成分です。高校数学を思い出してね。

//移動      
_x += vx;
_y += vy;
//向き
_rotation = d;
//
//衝突チェック
var hit:Boolean = hit_mc.hitTest(_x, _y, true);
if (hit) {
//10度曲がる
d += 10;
vx = speed*Math.cos(d*Math.PI/180);
vy = speed*Math.sin(d*Math.PI/180);
}

サンプル:
slippy.jpg

個別リンク

クリックした位置を中心に回転する

ムービークリップを回転させるには_rotationプロパティの値を少しずつ加算(減算)すればいいですよね。では、次のサンプルのようにクリックした位置を中心点にして回転させるにはどうすればいいでしょう??
ぼくもけっこう試行錯誤したんですが、答えは意外にも簡単でした! さあ、考えてみてください。

サンプル:
clickPt1.jpg

で、これをさらに発展させたのが次のサンプルです。今度はドラッグしてぐるぐる回せます。こっちはちょっと難しいですね。

サンプル:
clickPt2.jpg

個別リンク | コメント (1)

クリックした位置を中心に回転する(回答)

先日の「クリックした位置を中心に回転する」はどうやるかを種明かししましょう。写真をクリックするとクリックした点を中心に写真が回転します。そのままドラッグすることもできるというサンプルです。

サンプル:
clickPt1.jpg


ムービークリップのインスタンスを回転させるには、インスタンスの_rotationプロパティを連続的に変更します。_rotationプロパティの単位は度数なので、

this._rotation += 5;

とすれば5度ずつ回転します。このとき、回転の中心はムービークリップの座標の中心点です。ムービークリップには変形の中心点と座標の中心点がありますが、変形の中心点はあくまでもオーサリング時の[自由変形ツール]での変形の中心であって、スクリプトでは座標の中心点が回転や拡大などの中心点になるので誤解しないようにしましょう。

さてここからが種明かしです。(最後にflaファイルのダウンロードのリンクがあります)

回転させるためには写真をムービークリップシンボルにしなければならないというのは予想できると思いますが、実は回転させているのは写真のインスタンスではないのです。ステージに写真のインスタンスを作ったならば、それを選択してもう1回ムービークリップシンボルに変換します。つまり、入れ子になっているムービークリップを作ります。ステージに置いてあるのは、この写真が入れ子になっているインスタンスです。

インスタンスがクリックされたならば、クリックされた座標にインスタンスを移動します。これでマウスの位置にインスタンスの中心点が移動します。しかし、これでは写真の位置が動いてしまうので、インスタンスをマウスの位置に移動しただけ、中に入っている写真のインスタンスを逆方向に動かします。これで写真は元に位置から動いていないように見えます。後はこのままインスタンスを回転させればインスタンスはマウスの位置で回転するので、写真はマウスクリックした位置を中心点にして回転するように見えるのです。

//回転・ドラッグ開始
function onPress() {
//ドラッグ開始
this.startDrag(false);
//クリックした位置に移動
var xm:Number = this._xmouse;
var ym:Number = this._ymouse;
this._x = _root._xmouse;
this._y = _root._ymouse;
//移動した分だけmyMC(写真)の位置を補正
myMC._x -= xm;
myMC._y -= ym;
onEnterFrame = mawasu;
onMouseMove = updateStage;
}
//回転・ドラッグ終了
function onRelease() {
this.stopDrag();
delete this.onEnterFrame;
delete this.onMouseMove;
}
//回転・ドラッグ終了
function onReleaseOutside() {
this.stopDrag();
delete this.onEnterFrame;
delete this.onMouseMove;
}
//画面リフレッシュ
function updateStage() {
updateAfterEvent();
}
//インスタンスを回す
function mawasu() {
this._rotation += 5;
}

マウスクリックの位置を中心として回す方法はほかにも考えられますが、この方法がもっともお手軽なのではないかと思いますよ。発想の転換ですね。この考え方はいろいろなケースで応用できると思うので、研究してみてください。

flaファイルはココからダウンロードできます。→ダウンロード

個別リンク | コメント (0)

バトン

バトンを回してみました。

サンプル:
baton.jpg

class Kaiten extends MovieClip {
	var speed:Number;
	var rd:Number = 0;
	//
	//回転開始
	function startRotaSin(s:Number) {
		speed = (typeof s == "number") ? s : 30;
		this.onEnterFrame = rotaSinStep;
	}
	//
	//逆回転あり
	function rotaSinStep() {
		rd += 3;
		//-1〜1
		var a:Number = Math.sin(rd*Math.PI/180);
		this._rotation += speed*a;
	}
	//
	//回転停止
	function stopRotaSin() {
		delete this.onEnterFrame;
	}
}

個別リンク

ActionScript3搭載Flash9パブリックアルファ

Flash9のパブリックアルファ(英語版)をもう試しましたか?
Flash9ではActionScript3が搭載されています。ActionScript2でさえよくわからんのにーと困惑している人もいるでしょうけど、駅伝の繰り上げスタートと考えればラッキーかもというのは言い過ぎですかね。

パブリックアルファとサンプルは次のサイトからダウンロードできますが、Flash Professional 8がインストールされていないとインストールできないので注意してください。
Flash Professional 9 ActionScript 3.0 Preview

あくまでもアルファ版なのでまだバギーだってことをお忘れなく。
このサイトでもAS3についてもできるだけ紹介しますね。

個別リンク | コメント (0)

リングフォーメーションの習作

お待たせしました。リングフォーメーションの習作のダウンロードファイルです。和楽器サイトではこの習作を土台にしています。
説明など用意できないんですが、これを研究してみてください。

flaファイルとASファイルはココからダウンロードできます。→ダウンロード

リングフォーメーションの習作
test-ring1.jpg

個別リンク | コメント (1)

ドラッグして振り回す

「クリックした位置を中心に回転する」を応用した「ドラッグして振り回す」のflaファイルをアップしました。どうぞ研究してみてください。

flaファイルはココからダウンロードできます。→ダウンロード

サンプル:
clickPt2.jpg


個別リンク | コメント (0)

ベルばら

マウスで乙女チックに描いちゃってください。
ムービークリップを貼っているのではなく、BitmapDataクラスを使ってイメージを描いています。サイズの変形などはMatrixクラスを使っています。

flowerstamp.jpg

個別リンク | コメント (0)

擬似的な回転

六角形のムービークリップをアタッチし、その中にjpegファイルを読み込んでいます。インスタンスが横回転しているように見せるにはスケールを-100〜100のように変化させる方法がありますが、そうするとイメージが反転してしまいます。イメージを反転させたくない場合には、_widthプロパティを0〜100で変化させます。MovieClip.setMask()でマスクをかける場合、写真を読み込み終わってから設定しないとうまくいきません。

hexagon.jpg

個別リンク | コメント (0)