AS3でゲームを作成する その31 | Photoshop CC Tutorials
今回は前回に引き続きさらにドット絵職人のアルテミス氏に
爆弾の炎がブロックに当たったときのブロックの素材を作成していただけたので
さっそく使わせていただきました。

アルテミス職人のサイト:http://ameblo.jp/yukineko-altemis/theme-10008493007.html
参考プログラムサイト:http://mot3601.blog20.fc2.com/blog-entry-928.html

できあがりはこちらをクリック。(BGM、効果音にご注意)

実行結果
$ピック社長のブログ

プログラムはこのようになりました。
Main.as
package 
{
/**
*
*
*/
import flash.display.Sprite;
import flash.events.Event;
import flash.display.Loader;
import flash.events.MouseEvent;
import flash.system.LoaderContext;
import flash.net.URLRequest;
import flash.display.Bitmap;
import flash.display.BitmapData;

public class Main extends Sprite
{
private var loader:Loader;
private var output:BitmapData;
private var display:Display;

public function Main():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
loader = new Loader();
loader.contentLoaderInfo.addEventListener("complete", loadingComplete);
loader.load(new URLRequest("./bomberimage.png"), new LoaderContext(true));

// 画面の準備
output = new BitmapData(465, 465);
var bitmap:Bitmap = new Bitmap(output);
bitmap.x = 0;
bitmap.y = 0;
addChild(bitmap);
}

public function loadingComplete(e:Event):void
{
var source:BitmapData = new BitmapData(320, 128, true, 0x00000000);
source.draw(loader);
display = new Display(source);
//test.loadImage(source);
//addChild(new Bitmap(source));
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.CLICK, onClick);
}

private function onEnterFrame(e:Event):void
{
display.bombshori();
display.fireshori();
display.blockshori();
display.render(output);
}

private function onClick(e:MouseEvent):void
{
display.bombset(Math.floor(mouseX / 32), Math.floor(mouseY / 32));
}

}

}

Display.as
package 
{
/**
*
*
*/
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Sound;
import flash.net.URLRequest;

public class Display
{
// 効果音
private var url_01:URLRequest = new URLRequest("bomb.mp3");
private var sound_obj_01:Sound = new Sound(url_01);

private var url_02:URLRequest = new URLRequest("setBomb.mp3");
private var sound_obj_02:Sound = new Sound(url_02);

private var url_03:URLRequest = new URLRequest("thema.mp3");
private var sound_obj_03:Sound = new Sound(url_03);

private var tile:Vector.;
private var bomb:Vector.;
private var bombx:Vector.;
private var bomby:Vector.;
private var bombanime:Vector.;
private var bombfire:Vector.;
private var bombtime:Vector.;
private var bombfireflag:Vector.;
private var fire:Vector.;
private var firex:Vector.;
private var firey:Vector.;
private var firetime:Vector.;
private var firelength:int = 5;
private var block:Vector.;
private var blockx:Vector.;
private var blocky:Vector.;
private var blocktime:Vector.;

private var chrnum:uint = 0;
private var field:Array = [];
private var fieldCopy:Array = [];

public function Display(source:BitmapData)
{
sound_obj_03.play(0, 0xffffff); // テーマ曲
var i:uint;
var j:uint;
field[0] = [26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26];
field[1] = [26, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 26];
field[2] = [26, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 26];
field[3] = [26, 0, 28, 0, 28, 0, 28, 0, 28, 0, 28, 0, 26];
field[4] = [26, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 26];
field[5] = [26, 0, 28, 0, 28, 0, 28, 0, 28, 0, 28, 0, 26];
field[6] = [26, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 26];
field[7] = [26, 0, 28, 0, 28, 0, 28, 0, 28, 0, 28, 0, 26];
field[8] = [26, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 26];
field[9] = [26, 0, 28, 0, 28, 0, 28, 0, 28, 0, 28, 0, 26];
field[10] = [26, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 26];
field[11] = [26, 0, 28, 0, 28, 0, 28, 0, 28, 0, 28, 0, 26];
field[12] = [26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26];

for (i = 0; i < field.length; i++ ) {
fieldCopy[i] = new Array();
for (j = 0; j < field[i].length; j++) {
var ran:int = Math.random() * 10;
// 0,29,28は地面(爆弾設置可)
if (field[i][j] == 0 || field[i][j] == 29 || field[i][j] == 28) {
if (ran > 5) {
fieldCopy[i][j] = field[i][j];
field[i][j] = 27; // 27はレンガ
}else {
fieldCopy[i][j] = field[i][j];
}
}else {
fieldCopy[i][j] = field[i][j];
}
}
}

bomb = new Vector.;
bombx = new Vector.;
bomby = new Vector.;
bombanime = new Vector.;
bombfire = new Vector.;
bombtime = new Vector.;
bombfireflag = new Vector.;
fire = new Vector.;
firex = new Vector.;
firey = new Vector.;
firetime = new Vector.;
block = new Vector.;
blockx = new Vector.;
blocky = new Vector.;
blocktime = new Vector.;
tile = new Vector.;
tile.length = 40;
tile.fixed = true;

for (i = 0; i < 40; i++) {
tile[i] = new BitmapData(32, 32);
}
//tile[0].setPixel(3, 3, 0x000000);

for (j = 0; j < 4; j++){
for (i = 0; i < 10;i++){
tile[j*10+i].copyPixels(source, new Rectangle(i*32, j*32, i*32+32, j*32+32), new Point(0, 0));
}
}

}

public function render(output:BitmapData):void
{
var dx:int;
var dy:int;
var n:int;
var rect:Rectangle = new Rectangle(0, 0, 32, 32);
var anime:int;
output.lock();

for (dy = 0; dy < 13;dy++){
for (dx = 0; dx < 13; dx++) {
if (field[dy][dx] == 27) { // レンガなら
output.copyPixels(tile[field[dy][dx]], rect, new Point(dx*32, dy*32));
}else {
output.copyPixels(tile[fieldCopy[dy][dx]], rect, new Point(dx*32, dy*32));
//output.copyPixels(tile[field[dy][dx]], rect, new Point(dx*32, dy*32));
}
}
}
//爆弾のアニメーション
n = bomb.length;
while (n--) {
anime = bombanime[n] % 40;
if (anime >= 0 && anime < 10) { output.copyPixels(tile[2], rect, new Point(bombx[n], bomby[n] ), null, null, true); }
else if (anime >= 10 && anime < 20) { output.copyPixels(tile[3], rect, new Point(bombx[n], bomby[n] ), null, null, true); }
else if (anime >= 20 && anime < 30) { output.copyPixels(tile[4], rect, new Point(bombx[n], bomby[n] ), null, null, true); }
else if (anime >= 30 && anime < 40) { output.copyPixels(tile[3], rect, new Point(bombx[n], bomby[n] ), null, null, true); }
}
//火のアニメーション
n = fire.length;
while (n--) {
if (firetime[n] > 0 && firetime[n] <= 5 ) { output.copyPixels(tile[fire[n] + 14], rect, new Point(firex[n], firey[n] ), null, null, true ); }
else if (firetime[n] > 5 && firetime[n] <= 10 ) { output.copyPixels(tile[fire[n] + 7 ], rect, new Point(firex[n], firey[n] ), null, null, true ); }
else if (firetime[n] > 10 && firetime[n] <= 15) { output.copyPixels(tile[fire[n] ], rect, new Point(firex[n], firey[n] ), null, null, true ); }
else if (firetime[n] > 15 && firetime[n] <= 20) { output.copyPixels(tile[fire[n] + 7 ], rect, new Point(firex[n], firey[n] ), null, null, true ); }
else if (firetime[n] > 20 ) { output.copyPixels(tile[fire[n] + 14], rect, new Point(firex[n], firey[n] ), null, null, true ); }
}
//ブロックのアニメーション
n = block.length;
while (n--) {
if (blocktime[n] > 0 && blocktime[n] <= 3 ) { output.copyPixels(tile[38], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 3 && blocktime[n] <= 6 ) { output.copyPixels(tile[37], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 6 && blocktime[n] <= 9) { output.copyPixels(tile[36], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 9 && blocktime[n] <= 11) { output.copyPixels(tile[35], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 11 && blocktime[n] <= 13 ) { output.copyPixels(tile[34], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 13 && blocktime[n] <= 15) { output.copyPixels(tile[33], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 15 && blocktime[n] <= 17) { output.copyPixels(tile[32], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 17 && blocktime[n] <= 20) { output.copyPixels(tile[31], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
else if (blocktime[n] > 20 ) { output.copyPixels(tile[30], rect, new Point(blockx[n], blocky[n] ), null, null, true ); }
}

output.unlock();
chrnum = (chrnum + 1) % 30;
}

public function bombset(bx:int, by:int):void
{
if(bx<12 && by<12){
if (field[by][bx] == 0 || field[by][bx] == 29 || field[by][bx] == 28) {
sound_obj_02.play();
bomb.push(1);
bombx.push(bx * 32); //爆弾の座標
bomby.push(by * 32);
bombanime.push(0); //爆弾のアニメーション用
bombtime.push(128); //爆弾が爆発するまでの時間
bombfire.push(firelength); //火の長さ
bombfireflag.push(0);
field[by][bx] = 2;
}
}
}

public function bombshori():void
{
var i:int = bomb.length;
while(i--){
bombanime[i] = (bombanime[i] + 1) % 160;
bombtime[i]--;
if (bombtime[i] < 0) {
sound_obj_01.play();
var cx:int = Math.floor(bombx[i] / 32);
var cy:int = Math.floor(bomby[i] / 32);
makefire(cx, cy,i);
}
}
}

public function makefire(cx:int, cy:int, i:int):void
{
var count:int;
var n:int;
var cx2:int;
var cy2:int;
fire.push(5);
firex.push(cx*32);
firey.push(cy*32);
firetime.push(25);
cx2 = cx;
cy2 = cy;
//上方向の火
if ((bombfireflag[i] & 4) == 0) {
cy2--;
count = 0;
while (field[cy2][cx2] == 0 && count < firelength || field[cy2][cx2] == 29 && count < firelength || field[cy2][cx2] == 28 && count < firelength || field[cy2][cx2] == 27) {
if (count == firelength - 1 || field[cy2][cx2] == 27) {
fire.push(10);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
count++;
if (field[cy2][cx2] == 27) { // 27はブロック
block.push(1);
blockx.push(cx2 * 32);
blocky.push(cy2 * 32);
blocktime.push(25);
}
field[cy2][cx2] = fieldCopy[cy2][cx2]; // ブロックを消す
break;
} else {
fire.push(7);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
count++;
}
cy2--;
}
if (field[cy2][cx2] == 2) { //火が爆弾にあたった
n = bomb.length;
while (n--) {
if (cx2 == Math.floor(bombx[n] / 32) && cy2 == Math.floor(bomby[n] / 32)) {
bombtime[n] = 0;
bombfireflag[n] = bombfireflag[n] | 8;
}
}
}
}
//下方向の火
cx2 = cx;
cy2 = cy;
if ((bombfireflag[i] & 8) == 0) {
cy2++;
count = 0;
while (field[cy2][cx2] == 0 && count < firelength || field[cy2][cx2] == 29 && count < firelength || field[cy2][cx2] == 28 && count < firelength || field[cy2][cx2] == 27) {
if (count == firelength - 1 || field[cy2][cx2] == 27) {
fire.push(11);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
count++;
if (field[cy2][cx2] == 27) { // 27はブロック
block.push(1);
blockx.push(cx2 * 32);
blocky.push(cy2 * 32);
blocktime.push(25);
}
field[cy2][cx2] = fieldCopy[cy2][cx2]; // レンガを消す
break
} else {
fire.push(7);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
count++;
}
cy2++;
}
if (field[cy2][cx2] == 2) { //火が爆弾にあたった
n = bomb.length;
while (n--) {
if (cx2 == Math.floor(bombx[n] / 32) && cy2 == Math.floor(bomby[n] / 32)) {
bombtime[n] = 0;
bombfireflag[n] = bombfireflag[n] | 4;
}
}
}
}
//右方向の火
cx2 = cx;
cy2 = cy;
if ((bombfireflag[i] & 1) == 0) {
cx2++;
count = 0;
while (field[cy2][cx2] == 0 && count < firelength || field[cy2][cx2] == 29 && count < firelength || field[cy2][cx2] == 28 && count < firelength || field[cy2][cx2] == 27 && count < firelength) {
if (count == firelength - 1 || field[cy2][cx2] == 27) { // 27はレンガ
fire.push(9);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
if (field[cy2][cx2] == 27) { // 27はブロック
block.push(1);
blockx.push(cx2 * 32);
blocky.push(cy2 * 32);
blocktime.push(25);
}
count++;
field[cy2][cx2] = fieldCopy[cy2][cx2]; // レンガを消す
break;
} else {
fire.push(6);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
count++;
}
cx2++;
}

if (field[cy2][cx2] == 2) { //火が爆弾にあたった
n = bomb.length;
while (n--) {
if (cx2 == Math.floor(bombx[n] / 32) && cy2 == Math.floor(bomby[n] / 32)) {
bombtime[n] = 0;
bombfireflag[n] = bombfireflag[n] | 2;
}
}
}
}
//左方向の火
cx2 = cx;
cy2 = cy;
if ((bombfireflag[i] & 2) == 0) {
cx2--;
count = 0;
while (field[cy2][cx2] == 0 && count < firelength || field[cy2][cx2] == 29 && count < firelength || field[cy2][cx2] == 28 && count < firelength || field[cy2][cx2] == 27) {
if (count == firelength - 1 || field[cy2][cx2] == 27) {
fire.push(8);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
if (field[cy2][cx2] == 27) { // 27はブロック
block.push(1);
blockx.push(cx2 * 32);
blocky.push(cy2 * 32);
blocktime.push(25);
}
field[cy2][cx2] = fieldCopy[cy2][cx2]; // レンガを消す
count++;
break;
} else {
fire.push(6);
firex.push(cx2 * 32);
firey.push(cy2 * 32);
firetime.push(25);
count++;
}
cx2--;
}
if (field[cy2][cx2] == 2) { //火が爆弾にあたった
n = bomb.length;
while (n--) {
if (cx2 == Math.floor(bombx[n] / 32) && cy2 == Math.floor(bomby[n] / 32)) {
bombtime[n] = 0;
bombfireflag[n] = bombfireflag[n] | 1;
}
}
}
}
//爆弾を消す
field[cy][cx] = 0;
bomb.splice(i,1);
bombx.splice(i,1);
bomby.splice(i,1);
bombanime.splice(i,1);
bombtime.splice(i,1);
bombfire.splice(i, 1);
bombfireflag.splice(i, 1);
}

public function fireshori():void
{
var n:int = fire.length;
while (n--) {
firetime[n]--;
if (firetime[n] < 0) {
//火を消す
fire.splice(n, 1);
firex.splice(n,1);
firey.splice(n,1);
firetime.splice(n,1);
}
}
}

public function blockshori():void
{
var n:int = block.length;
while (n--) {
blocktime[n]--;
if (blocktime[n] < 0) {
//火を消す
block.splice(n, 1);
blockx.splice(n,1);
blocky.splice(n,1);
blocktime.splice(n,1);
}
}
}
}

}


BGM,効果音をお借りしたサイトです。
http://www.skipmore.com/
http://koukaongen.com/cgi/se_search/herodb.cgi?table=sound&search=%94%9A%94%AD

このゲームに使用されている素材です。
$ピック社長のブログ

画像を使用する場合はドット絵専門家のアルテミス職人の許可を取ってください。

アルテミス職人のサイト:
↓は爆弾の素材です。
http://ameblo.jp/yukineko-altemis/entry-11016380157.html
↓は壁と炎の素材です。
http://secret.ameba.jp/yukineko-altemis/amemberentry-11041239304.html
↓は壁、地面、レンガの素材です。
http://ameblo.jp/yukineko-altemis/entry-11045283691.html
↓はブロックの素材です。
http://ameblo.jp/yukineko-altemis/theme-10008493007.html