Flashでビットマップ画像をBitmapDataとして表示する。
FlashCS6に素材を用意する。以前「Flashを学習する(2) シューティングゲームを作成」http://d.hatena.ne.jp/itouhiro/20081005で使った素材をそのまま使う。
pngファイルをFlashの「ライブラリー」にDrag&Dropして、プロパティで「ActionScriptに書き出し」チェックしたら勝手に基本クラスがflash.display.BitmapDataになった。
BitmapDataの扱いは
http://sipo.jp/blog/2009/12/flashbitmapdata.html
はわかりやすそうだ。公式の
http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/flash/display/BitmapData.html
も読む。
codingはFlashDevelopでおこなう。FlashDevelopはEmacs操作できるようにカスタマイズしてるので使いやすい。
ビルドはFlashCS6で。
BitmapData表示
まずはBitmapDataを表示するだけ。
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.events.Event; /** * ... * @author itouhiro */ [SWF(width="640",height="480",backgroundColor="0xdcdcfc",frameRate="60")] public class Stg201305 extends Sprite { private var myShip:Bitmap; public function Stg201305():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 myShip = new Bitmap(new MyShip1(), PixelSnapping.AUTO, false); myShip.x = stage.stageWidth / 2; myShip.y = stage.stageHeight / 2; addChild(myShip); myShip.addEventListener(Event.ENTER_FRAME, enterFrameHandler); } private function enterFrameHandler(e:Event):void { var sin:Number = Math.sin( (myShip.x % 360) * Math.PI / 180) * 100; //myShip.xに応じて-100~+100に変化 myShip.x = (myShip.x + 1) % stage.stageWidth; myShip.y = (stage.stageHeight / 2) + sin; myShip.scaleX = myShip.scaleY = 3.0 + sin / 50; // 1.0~5.0に変化 } } }
smoothingをOFFにしたので、ビットマップでカクカクですけどそれがいい。
マウス操作
マウスで操作可能にする。
Stg201305.as
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix; /** * ... * @author itouhiro */ [SWF(width="640",height="480",backgroundColor="0x100830",frameRate="60")] public class Stg201305 extends Sprite { private var myShip:MyShip; public function Stg201305():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 myShip = new MyShip(stage.stageWidth / 2, stage.stageHeight / 2, stage.frameRate); addChild(myShip); } } }
MyShip.as
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; /** * ... * @author ... */ public class MyShip extends Sprite { private var img:Bitmap; private var backfire:Bitmap; private var bulletCount:int = 0; //弾を射出してからのカウント var imgSrc:Array = []; var count:int = 0; var displayBackFire:Boolean = true; var fps:int = 0; public function MyShip(_x:int, _y:int, _fps:int) { imgSrc[0] = new MyShip1(); imgSrc[1] = new MyShip2(); img = new Bitmap(imgSrc[0], PixelSnapping.AUTO, false); img.scaleX = img.scaleY = 4.0; img.x = -(img.width / 2); //マウスカーソルが指すのをimg画像「中央」にする。0の場合、画像「左上端」を指す img.y = -(img.height / 2); addChild(img); backfire = new Bitmap(new MyShipBackFire(), PixelSnapping.AUTO, false); backfire.scaleX = backfire.scaleY = 4.0; backfire.x = -(img.width / 2) + 1; //素材が1pixelずれてるので補正 backfire.y = -(img.height / 2) + img.height; //myShipImgの画面下部に位置するよう指定 backfire.alpha = 0.8; displayBackFire = true; addChild(backfire); x = _x; //stage.stageWidthにここのclassからアクセスするとエラーになるので、引数で数値を受け取る y = _y; fps = _fps; count = 0; addEventListener(Event.ENTER_FRAME, enterFrameHandler); bulletCount = 0; addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); } private function mouseDownHandler(e:MouseEvent):void { var bullet:MyBullet = new MyBullet(x, y - img.height / 2); parent.addChild(bullet); //myShipの子ではなく、stageの子にする parent.setChildIndex(bullet, 0); //背面に配置 bulletCount = fps / 4; } private function enterFrameHandler(e:Event):void { x += (parent.mouseX - x) / 10; //parent. つけないと値がおかしい y += (parent.mouseY - y) / 10; count++; if (count >= fps / 2) { //半秒間ごとにロケット噴射の描写を切り替え count = 0; displayBackFire = ! displayBackFire; backfire.visible = displayBackFire; } if (bulletCount > 0) { //弾を射出してから1/4秒は、自機の画像を別のに変更 img.bitmapData = imgSrc[1]; bulletCount--; }else { img.bitmapData = imgSrc[0]; } } } }
MyBullet.as
package { import flash.display.Bitmap; import flash.display.Sprite; import flash.events.Event; /** * ... * @author ... */ public class MyBullet extends Sprite { private var img:Bitmap; public function MyBullet(_x:int, _y:int) { img = new Bitmap(new MyFire()); img.scaleX = img.scaleY = 4.0; img.x = -(img.width / 2); img.y = -(img.height / 2); addChild(img); x = _x; y = _y; addEventListener(Event.ENTER_FRAME, enterFrameHandler); } private function enterFrameHandler(e:Event):void { //trace('bullet: x='+ x +', y='+ y); y--; if (y < -img.height * 4) { //画面外に出たら消去 removeEventListener(Event.ENTER_FRAME, enterFrameHandler); removeChild(img); parent.removeChild(this); delete this; } } } }
自機はマウスカーソルに追従して動く。マウスクリックで弾を射出。
続編
- ActionScript3.0でSTGを作成(1) http://itouhiro.hatenablog.com/entry/20130517/flash
- copyPixels()使ってBitmapDataをcopy