CreateJS ブロック崩し的なもの

nekome_block_130307
CreateJS×Flash Developで「ブロック崩し的なもの」を作成してみました。

Createjs ブロック崩してきなもの 


http://www.mztm.jp/moriya/blockbreak/
写真 alan guido/Cat Doing His Job

 

ブロック崩しの仕様

 ・再生時にランダム色のブロックが配置されます。
 ・クリックすると玉が5つ真ん中ラへんに落ちてきます。
 ・下の板がマウスに追従するので、玉が落ちないように操作します。
 ・ブロックが全部なくなるとクリア、玉が全部落ちるとゲームオーバーです。
  ※もう一度チャレンジする際は、リロードしてください。
 

作ってみて思ったこと

 ・おおむね、as3でのノウハウがいかせるので、迷いはそれほどなく製作できました。
 ・衝突判定の効率のよい方法を勉強したい。
 ・キャンバスや、ShapeなどのObjectに width、heightがなく戸惑った。
  ※bitmapには縦横プロパティ(bitmap.image.widthなど)があった。

 

参考リンク

 ・ブロック崩しの概要について
 ActionScript入門Wiki EaselJS – ブロック崩しデモ

 ・マウスイベント、ロールオーバーアウトについて
 ゆるぶ Mouse Interaction / CreateJS

 ・jsの配列について
 プログラム問答/JavaScript 配列は、要素を削除します。
 
 ・全般
 yoheim.net/[CreateJS] Canvasアニメーションを実装する時に便利で良く利用しているJSライブラリ、CreateJS
 
 ・読み込み関連
 fumiononaka.com/FLAからJSへ~CreateJS中級編
 kudox.jp > JavaScript > PreloadJSで外部ファイルを読み込む
 ActionScript入門Wiki/画像を読み込む

 ・色ランダム設定
 access_r/JavaScript > 背景色をランダムに変える方法
 落書屋雑貨店/JavaScript 工房/さらに気分次第で背景の色変えボタン
 
 ・toolkit for createjs関連
 AmazingFlash/Toolkit for CreateJS

 

今後CreateJSで学びたいこと

 ・外部ファイル apiの利用方法
 ・Flash CS6「toolkit for createjs」との連携方法
 ・深度管理
 ・クラス管理
 

 

下記 Flash Develop CreateJS Appプロジェクトのソースコード

[sourcecode language=”js”]
(function(){

/**
* Main class of the app.
*/
function Main(){}

/**
* Entry point of the app.
*/
//*********************************************************
var stage;
var isStart=false;
var traceTxt="",dspTxt="";//テキスト
var paddle,paddleX=0;//板
var _mouseX,_mouseY;//マウス座標
var tamaList=[],speed=3;//玉用
var blockList=[];//ブロック用
var fileList = ["img/neko.jpg"],imgList=[],setCnt=0;//読み込み画像

//*********************************************************

Main.main = function()
{
var main = new Main();
if (!window.HTMLCanvasElement)
{
alert("Your browser does not support HTML5 Canvas.");
return;
}
else main.initialize();
// entry point
//まずは画像を読み込んでみる
imgload();
}

function imgload() {
var loader =new createjs.PreloadJS(false);
loader.onFileLoad = fileLoaded;
loader.loadManifest(fileList,true);//loader.onError = loadErrorHandler;
loader.onComplete = completeHandler;
}

function completeHandler()
{
//BG
var bg=drawShikaku(stage.width,stage.height,"black");
stage.addChild(bg);

//トレース目的などに使いたい
traceTxt = new createjs.Text("最初に表示させる文字", "12px Arial", "white");
stage.addChild(traceTxt),traceTxt.text="出力:";
traceTxt.x = 10,traceTxt.y = 10,traceTxt.maxWidth = 200,traceTxt.lineWidth = 50,traceTxt.lineHeight = 28; // 行の高さ

//板
var paddleW=200;
paddle=drawShikaku(paddleW,10,"#FFFFFF");
paddle.width=paddleW,paddle.height=10,paddle.x=paddleX=(stage.width-paddle.width)/2,paddle.y=stage.height-45;
stage.addChild(paddle);

//読み込んだ画像
for(i=0;i<fileList.length;i++)
{
setInstance(fileList[i]);
}

//ブロックセット
var imgW=imgList[0].image.width,imgH=imgList[0].image.height;
var _cnt=0,_bwidth=40,_bheight=20,_boffsetX=imgList[0].x,_boffsetY=imgList[0].y,_bBorderW=0,_bBorderH=0;
var _bColumn=_bRow=0;
_bColumn=Math.floor(imgW/_bwidth);
_bRow=Math.floor(imgH/_bheight);

for(r=0;r<_bRow;r++)
{
for(c=0;c<_bColumn;c++)
{
blockList[_cnt]=drawShikaku(_bwidth,_bheight,randomColor());
blockList[_cnt].width=_bwidth,blockList[_cnt].height=_bheight;
blockList[_cnt].cnt=_cnt;
blockList[_cnt].x=(_bwidth+_bBorderW)*c+_boffsetX,blockList[_cnt].y=(_bheight+_bBorderH)*r+_boffsetY;
stage.addChild(blockList[_cnt]);
_cnt=_cnt+1;
}
}

//ゲーム進行用テキスト
dspTxt = new createjs.Text("CLICKしてSTART", "20px Arial", "white");
stage.addChild(dspTxt);
dspTxt.x = stage.width*0.5,dspTxt.y = stage.height*0.5+70,dspTxt.maxWidth = 200,dspTxt.lineWidth = 50,dspTxt.lineHeight = 28; // 行の高さ
dspTxt.textAlign = "center";
//FlashDebelop CreateJSのバージョンが古くて、addEventListenerが対応してないみたい、、、最新にするにはどうすればいいかな
stage.onMouseDown = mouseHandler,stage.onMouseMove = mouseMoveHandler;
}

//function loadErrorHandler(e){}
function setInstance(_imgsrc) {
var _bitmap = new createjs.Bitmap(_imgsrc);
_bitmap.x = (stage.width-_bitmap.image.width) / 2;
_bitmap.y = (stage.height-_bitmap.image.height-140) / 2;
//中心点の設定
//_bitmap.regX = _bitmap.image.width / 2;
//_bitmap.regY = _bitmap.image.height / 2;
imgList[setCnt]=_bitmap;
setCnt++;
stage.addChild(_bitmap);
}

function fileLoaded(e) {}

function start()
{
//玉セット
var tamaNum=5,tamaRadius=5;
for(i=0;i<tamaNum;i++)
{
var color=randomColor();
tamaList[i]=drawMaru(tamaRadius,color);
stage.addChild(tamaList[i]);
tamaList[i].cnt=i;
tamaList[i].vx=0,tamaList[i].vy=speed,tamaList[i].RADIUS=tamaRadius,tamaList[i].isReflect=false;
tamaList[i].x=Math.random()*10+350;
tamaList[i].y=stage.height-(Math.random()*20+100);
}
_cnt=0;
isStart=true,dspTxt.text="";
}

/**
* Updates the stage on Ticker tick.
* @param event The recieved tick event.
*/
Main.prototype.tick = function(event)
{
paddle.x = paddle.x+(paddleX-paddle.x)*0.5;
if(isStart){
//判定ここから
for(i=0;i<tamaList.length;i++)
{
var _circle = tamaList[i];
_circle.isReflect=false;
//玉移動
_circle.x = _circle.x + _circle.vx;
_circle.y = _circle.y + _circle.vy;
if (_circle.x – _circle.RADIUS < 0) _circle.x = _circle.RADIUS, _circle.vx = Math.random() * 4 + speed;
if (_circle.y – _circle.RADIUS < 0) _circle.y = _circle.RADIUS, _circle.vy = Math.random() * 4 + speed;
if (stage.width <= _circle.x + _circle.RADIUS) _circle.x = stage.width – _circle.RADIUS, _circle.vx = -(Math.random() * 4 + speed);
if(stage.height <= _circle.y + _circle.RADIUS)
{
//玉をリストから削除
stage.removeChild(_circle);
tamaList.splice(_circle.cnt, 1);
for(i=0;i<blockList.length;i++)tamaList[i].cnt=i;
}

//当たり判定
localPoint = paddle.globalToLocal(_circle.x, _circle.y+_circle.RADIUS);
if(paddle.hitTest(localPoint.x, localPoint.y))
{
if(_circle.vx<0)
{
_circle.vx=_circle.vx-Math.random()*4;
}else
{
_circle.vx=_circle.vx+Math.random() * 4;
}
_circle.vy = -(Math.random() * 4 + speed);
}
/*点と面で判定するのでhitTestは使いにくい、、、、(マウス座標が載ったかどうかだと有用)なのでhitTestやめて別の方法を考よう。*/
for(ii=0;ii<blockList.length;ii++)
{
var _block = blockList[ii];
//玉が入ってきてほしくない座標をブロックのプロパティを頼りに設定してみよう
var _cx=_circle.x,_cy=_circle.y,_cRadius=_circle.RADIUS;
var _right =_block.x+_block.width+_cRadius;
var _bottom = _block.y+_block.height+_cRadius;
if(((_cx+_cRadius) >= _block.x && (_cy+_cRadius) >= _block.y)&& (_cx <= _right && _cy <= _bottom))_circle.isReflect=true;
if(_circle.isReflect)
{
_circle.vy=(_circle.vy+Math.random() * 2)*-1;_circle.vx=(_circle.vx+Math.random() * 2)*-1;
if(_cx<=_right && _cx>=_right-_block.width*0.5)_circle.x=_circle.x+_circle.RADIUS/2;
else if(_cx>=_block.x-_cRadius && _cx<=_block.x-_cRadius+_block.width*0.5)_circle.x=_circle.x-_circle.RADIUS/2;
if(_cy<=_bottom && _cy >= _bottom -_block.height*0.5)_circle.y=_circle.y+_circle.RADIUS/2;
else if(_cy >= _block.y-_cRadius && _cy <= _block.y-_cRadius+_block.height*0.5 )_circle.y=_circle.y-_circle.RADIUS/2;

//ブロックをリストから削除
stage.removeChild(_block);
blockList.splice(_block.cnt, 1);
for(iii=0;iii<blockList.length;iii++){
blockList[iii].cnt=iii;
}
break;
}
}
}
if(blockList.length==0)dspTxt.text="GameClear",isStart=false;
if(tamaList.length==0)dspTxt.text="GameOver",isStart=false;
//判定ここまで
}
stage.update();
}

/**
*とりあえず適当な色の16進数をStringで返す
*
*/
function randomColor()
{
var _color = Math.floor(Math.random() * 0xFFFFFF).toString(16); //#RRGGBBを取得
for(count = _color.length; count < 6; count++)_color = "0" + _color;//上位に0を補完する
return _color = "#"+_color;
}

/**
*
*
*/
function drawMaru(_radius,_color)
{
var maru = new createjs.Shape(),_mg=maru.graphics;
_mg.beginFill(_color),_mg.setStrokeStyle(0.5),_mg.beginStroke("#FFFFFF"),_mg.drawCircle(0,0,_radius);
return maru;
}

function drawShikaku (_w,_h,_color){
var rect = new createjs.Shape(),_rg=rect.graphics;
_rg.beginFill(_color);
_rg.setStrokeStyle(0.5),rect.graphics.beginStroke("#FFFFFF");
_rg.drawRect(0,0,_w, _h),_rg.endFill();
return rect;
}

function mouseMoveHandler(eventObject)
{
_mouseX=eventObject.stageX;
_mouseY=eventObject.stageY;
paddleX=eventObject.stageX-paddle.width/2;
}

function mouseHandler(eventObject)
{
start();
stage.onMouseDown = null;
}

/**
* Initializes the basics of the app.
*/
Main.prototype.initialize = function()
{
/**
* mainCanvas
*/
this.mainCanvas = document.getElementById("mainCanvas");
/**
* mainStage
*/
stage = new createjs.Stage(this.mainCanvas);
stage.snapToPixelsEnabled = true,stage.width=580,stage.height=352;

/*
* createjs
*/
createjs.Ticker.addListener(this);
createjs.Ticker.useRAF = true;
createjs.Ticker.setFPS(60);
}

/**
* Expose class.
*/
window.Main = Main;

})();

[/sourcecode]