さて、ActionScript3.0(as3)を使ってアイソメトリックな世界を簡単に作れるライブラリー「as3isolib」の解説5回目。
概要やインストール方法については解説第一回目 を見てみてください。
今回は、好きな画像をas3isolibで扱う方法について説明します。
好きな画像を表示させるために、as3isolibでは専用のクラス、IsoSpriteクラスが用意されています。
早速、ゲーム界で世界一有名な次の画像を、as3isolib上に表示させてみましょう。
package
{
import as3isolib.display.IsoSprite;
import as3isolib.display.scene.IsoGrid;
import as3isolib.display.scene.IsoScene;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.net.URLRequest;
public class IsoSpriteSample extends Sprite
{
private var _isoScene:IsoScene;
public function IsoSpriteSample()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
// シーンを作る
_isoScene = new IsoScene();
// displayListと繋ぐ
_isoScene.hostContainer = this;
// 分かりにくいのでおなじみのグリッドも追加
var grid:IsoGrid = new IsoGrid();
grid.cellSize = 16;
_isoScene.addChild( grid );
/*
* 外部画像をロードしてセット
*/
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, _setImage );
loader.load( new URLRequest( "./images/mario.gif" ) );
function _setImage( e:Event ):void
{
// ロードした画像をセット
var marioImage:Bitmap = e.target.content;
// マリオの足下がグリッドの座標と一致するように修正
marioImage.x = -marioImage.width/2;
marioImage.y = -marioImage.height;
var isoSprite:IsoSprite = new IsoSprite();
// spritesに表示したい画像をセット
isoSprite.sprites = [ marioImage ];
isoSprite.x = 16;
isoSprite.y = 16;
// シーンに追加
_isoScene.addChild( isoSprite );
// レンダリング
_isoScene.render();
}
}
}
}
IsoSpriteのspritesに画像を配列で指定するだけです。とてもシンプル。
DisplayObjectであればMovieClipでも何でもOKです。
例えば、次の3つの画像とマリオさんを使うと、こんなものが作れちゃいます。
クリックするとマリオさんが動くようになっているのですが、Flashを貼り付けられないので、実際に動くサンプルが見たい方は、「コチラ 」の同じ内容のブログをご覧になって下さい。
少し長くなりますが、ソースはこんな感じです。マリオ移動のために、有名なGTween というTweenライブラリを利用しています。
package
{
import as3isolib.core.ClassFactory;
import as3isolib.core.IsoDisplayObject;
import as3isolib.display.IsoSprite;
import as3isolib.display.renderers.DefaultShadowRenderer;
import as3isolib.display.scene.IsoGrid;
import as3isolib.display.scene.IsoScene;
import as3isolib.geom.IsoMath;
import as3isolib.geom.Pt;
import com.gskinner.motion.GTween;
import com.gskinner.motion.GTweener;
import eDpLib.events.ProxyEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.geom.Point;
public class IsoSpriteSample2 extends Sprite
{
private const GRID_SIZE:int = 16;
private var _mario:IsoSprite;
private var _isoScene:IsoScene;
public function IsoSpriteSample2()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// シーンを作る
_isoScene = new IsoScene();
// displayListと繋ぐ
_isoScene.hostContainer = this;
// 見切れちゃうので、全体の表示位置をちょっとずらず
x = 120;
y = 50;
_mario = new IsoSprite();
/*
* Flashで作ってswcに入れたMovieClipをセット
*/
// マリオさん
var marioImage:MovieClip = new Mario();
marioImage.y = GRID_SIZE/2;
_mario.sprites = [ marioImage ];
_mario.width = GRID_SIZE;
_mario.length = GRID_SIZE;
_mario.height = GRID_SIZE*2;
_mario.x = GRID_SIZE*3;
_mario.y = GRID_SIZE*3;
_mario.z = GRID_SIZE*1;
_isoScene.addChild( _mario );
/*
* 5x5の床を敷き詰める
*/
for ( var i:int = 0; i < 7; i++ )
{
for ( var j:int = 0; j < 7; j++ )
{
var isoGroundBlock:IsoSprite = _createBlock( "groundBlock", GRID_SIZE*i, GRID_SIZE*j, 0 );
_isoScene.addChild( isoGroundBlock );
}
}
/*
* 1-1のブロック配置を再現
*/
var blockBitmapData:BitmapData = new Block(0,0);
var questionBlockBitmapData:BitmapData = new QuestionBlock(0,0);
// ブロック1
var isoBlock1:IsoSprite = _createBlock( "block", GRID_SIZE*1, GRID_SIZE*3, GRID_SIZE*4 );
_isoScene.addChild( isoBlock1 );
// ?ブロック1
var isoQuestionBlock1:IsoSprite = _createBlock( "questionBlock", GRID_SIZE*2, GRID_SIZE*3, GRID_SIZE*4 );
_isoScene.addChild( isoQuestionBlock1 );
// ブロック2
var isoBlock2:IsoSprite = _createBlock( "block", GRID_SIZE*3, GRID_SIZE*3, GRID_SIZE*4 );
_isoScene.addChild( isoBlock2 );
// ?ブロック2
var isoQuestionBlock2:IsoSprite = _createBlock( "questionBlock", GRID_SIZE*4, GRID_SIZE*3, GRID_SIZE*4 );
_isoScene.addChild( isoQuestionBlock2 );
// ブロック3
var isoBlock3:IsoSprite = _createBlock( "block", GRID_SIZE*5, GRID_SIZE*3, GRID_SIZE*4 );
_isoScene.addChild( isoBlock3 );
// 表示
_isoScene.render();
// クリックしたところへマリオを移動させる
addEventListener( MouseEvent.CLICK, _moveMario );
}
private function _createBlock( type:String, x:int, y:int, z:int ):IsoSprite
{
var image:BitmapData;
switch ( type )
{
case "block":
image = new Block( 0, 0 );
break;
case "questionBlock":
image = new QuestionBlock( 0, 0 );
break;
case "groundBlock":
image = new GroundBlock( 0, 0 );
break;
}
// 画像を作って、グリッドに合わせて真ん中にする
var bitmap:Bitmap = new Bitmap( image );
bitmap.x = -bitmap.width/2;
bitmap.y = -bitmap.height/2;
var isoBlock:IsoSprite = new IsoSprite();
isoBlock.width = GRID_SIZE;
isoBlock.length = GRID_SIZE;
isoBlock.height = GRID_SIZE;
isoBlock.sprites = [ bitmap ];
isoBlock.x = x;
isoBlock.y = y;
isoBlock.z = z;
return isoBlock;
}
private function _moveMario( e:MouseEvent ):void
{
// 見切れるのを直した分を考慮して、クリック座標を計算する
var clickPos:Point = new Point( e.stageX-120, e.stageY-50 );
// 目的地の極座標を、グリッド座標に変換する
var destPt:Pt = new Pt( clickPos.x, clickPos.y+GRID_SIZE/2 );
IsoMath.screenToIso( destPt );
// フィールドの外をクリックした場合は無視する
if ( destPt.x > GRID_SIZE * 7 || destPt.y > GRID_SIZE * 7 )
{
return;
}
var distance:Number = Pt.distance( new Pt( _mario.x, _mario.y ), destPt );
var mario:MovieClip = _mario.sprites[ 0 ];
mario.gotoAndPlay( "run" );
// マリオのグリッド座標を、極座標に変換する
var marioPt:Pt = new Pt( _mario.x, _mario.y );
IsoMath.isoToScreen( marioPt );
mario.scaleX = (clickPos.x - marioPt.x)/Math.abs(clickPos.x - marioPt.x);
// 実行済みのtweenをキャンセルする
GTweener.removeTweens( _mario );
// 目的地までマリオをtweenさせる
GTweener.to( _mario, distance/(GRID_SIZE*6), { "x":destPt.x, "y":destPt.y }, { onChange:_render, onComplete:_complete } );
}
private function _render( tween:GTween ):void
{
_isoScene.render();
}
private function _complete( tween:GTween ):void
{
var mario:MovieClip = _mario.sprites[ 0 ];
mario.gotoAndPlay( "stop" );
}
}
}
なんとなく、アメーバぴぐっぽいものが作れそうな雰囲気がでてきました。ね?
以上で、IsoSpriteの説明は終了です!
次回は、フィルターについて書いてみたいと思います。