プログラマが何もする必要がないとき、私たちは自分でゲームを書きます。 パート1

最近、ハブに「プログラマーが何もすることがないとき...」という記事があり、ここにこのような状況がありますが、 Color Linesへのリンクを与えるだけでなく、自分でそれを作る方法を教えてください。 猫の下で歓迎に興味がある人



私は何について話している



多くの人々がこのゲームを知っています;それは遠い子供時代から「カラーライン」と呼ばれます。 私がゲームのルールを覚えていない人は、ボールが燃え尽きるときを除いて、移動するたびに異なる色のボールが正方形のフィールドに投げられます。 同じ色の線を水平、垂直または斜めに作成するには、ボールを移動する必要があります。 さらに、ボールは通過できるポイントまでしか移動できません。 5つ以上のボールのラインを構築すると、それらは破壊されます。



準備する



ゲームのページテンプレートは非常にシンプルで、2つのフィールドが含まれます。 1つはフィールドで、2つ目はスコアを表示します。 フィールドのセルは、スクリプトを使用して生成されます。

Index.htmlファイル

< html >

< head >

< meta HTTP-EQUIV ="Content-Type" CONTENT ="text/html; charset=utf-8" />

< title > ColorLines </ title >

< script type ="text/javascript" src ="jsfw.js" ></ script >

<script type= "text/javascript" src= "main.js" ></script>

<script type= "text/javascript" src= "lines.js" > </ script >

< link href ="style.css" rel ="stylesheet" type ="text/css" />

</ head >

< body >

< a href ="/" > </ a >

< h1 > - Color Lines </ h1 >

< table >

< tr >

< td >

< div class ="gamepole" >

< div id ="pole" >

</ div >

< div class ="gameOver" id ="gameover" style ="display:none" >

< div class ="bg" ></ div >

< div class ="block" >

< h4 > </ h4 >

</ div >

</ div >

</ div >

</ td >

< td class ="menu" >

< p > : < span id ="score" > 0 </ span ></ p >

< input type ="button" onclick ="game.start()" value =" " />

</ td >

</ tr >

</ table >

</ body >

</ html >




* This source code was highlighted with Source Code Highlighter .









< html >

< head >

< meta HTTP-EQUIV ="Content-Type" CONTENT ="text/html; charset=utf-8" />

< title > ColorLines </ title >

< script type ="text/javascript" src ="jsfw.js" ></ script >

<script type= "text/javascript" src= "main.js" ></script>

<script type= "text/javascript" src= "lines.js" > </ script >

< link href ="style.css" rel ="stylesheet" type ="text/css" />

</ head >

< body >

< a href ="/" > </ a >

< h1 > - Color Lines </ h1 >

< table >

< tr >

< td >

< div class ="gamepole" >

< div id ="pole" >

</ div >

< div class ="gameOver" id ="gameover" style ="display:none" >

< div class ="bg" ></ div >

< div class ="block" >

< h4 > </ h4 >

</ div >

</ div >

</ div >

</ td >

< td class ="menu" >

< p > : < span id ="score" > 0 </ span ></ p >

< input type ="button" onclick ="game.start()" value =" " />

</ td >

</ tr >

</ table >

</ body >

</ html >




* This source code was highlighted with Source Code Highlighter .









< html >

< head >

< meta HTTP-EQUIV ="Content-Type" CONTENT ="text/html; charset=utf-8" />

< title > ColorLines </ title >

< script type ="text/javascript" src ="jsfw.js" ></ script >

<script type= "text/javascript" src= "main.js" ></script>

<script type= "text/javascript" src= "lines.js" > </ script >

< link href ="style.css" rel ="stylesheet" type ="text/css" />

</ head >

< body >

< a href ="/" > </ a >

< h1 > - Color Lines </ h1 >

< table >

< tr >

< td >

< div class ="gamepole" >

< div id ="pole" >

</ div >

< div class ="gameOver" id ="gameover" style ="display:none" >

< div class ="bg" ></ div >

< div class ="block" >

< h4 > </ h4 >

</ div >

</ div >

</ div >

</ td >

< td class ="menu" >

< p > : < span id ="score" > 0 </ span ></ p >

< input type ="button" onclick ="game.start()" value =" " />

</ td >

</ tr >

</ table >

</ body >

</ html >




* This source code was highlighted with Source Code Highlighter .












ファイルstyle.css

.gamepole {position:relative;}

.Pole {width:414px;}

.Cell {width:30px;height:30px;background:#333;float:left;margin:1px;color:#FFF}

.Ball {width:26px;height:26px;margin:2px;position:relative;}

.Ball1 {background:#F00;}

.Ball2 {background:#0F0;}

.Ball3 {background:#00F;}

.Ball4 {background:#0FF;}

.Ball5 {background:#F0F;}

.Ball6 {background:#FF0;}

.gameOver {position:absolute;top:0;left:0;width:384px;padding-top:75px;text-align:center;}

.gameOver .bg {z-index:1;position:absolute;top:0;left:0;width:384px;height:384px;background:#C78BA3; filter:alpha(opacity=60);-moz-opacity:.6;opacity:.6;}

.gameOver h4{font-size:30px;}

.gameOver .block{position:relative;z-index:2;background:#FFF;padding:30px;width:300px;margin:0 auto;}

td.menu {vertical-align:top;background:#333;color:#FFF;width:260px;padding:10px;}







始めましょう



実装では、私はjsバイクを使用しますが、そのコードはもちろん提供していませんが、ソースで見つけられる興味のある機能についてコメントします。 jquery、prototypeなどではなく、それが私にとってより便利だからです。

ゲームには3つのクラスのみがあります。

ゲーム-ゲームのメインクラス

セル-セルクラス

ボール-ボールクラス



ゲームを作成してテンプレートに関連付けるmain.jsファイルを作成します

jsfw.ready( function ()

{

game = new Game( 'pole' );

game.addEvent( 'onchangescore' , function (score){

$( 'score' ).innerHTML = score;

});

game.addEvent( 'onstart' , function (score){

$( 'gameover' ).style.display = 'none' ;

});

game.addEvent( 'ongameover' , function (score){

$( 'gameover' ).style.display = '' ;

});

game.start();

});




* This source code was highlighted with Source Code Highlighter .






ゲームはイベントシステム上に構築されます。 したがって、Gameオブジェクトを作成し、そのイベントをサブスクライブします。 彼はそれらのうちの3つだけを持ちます。

onchangescore-アカウントの変更。

onstart-ゲームの始まり。

ongameover-ゲームの終了。

最初に、得点の変化をキャッチし、画面に表示します。 他の2つでは、ゲームの終了に関するメッセージを非表示または表示します。



残りのコードをlines.jsファイルに入れます

ゲームクラス


var Game = jsfw.Class( function (){

/**



*/

function setScore(score)

{

this .score = score;

this .callEvent( 'onchangescore' ,[ this .score]); //

}

return {

width:12, //

height:12, //

speed:30, //

minline:5, //

countNewBall:3, //

costBall:1, //

costBonus:5, //

/**

*

* @param ID

*/

__constructor: function (el)

{

this .dom = $(el); //

this .score = 0; //

this .cell = []; //

/*

$d

*/

this .dSelectBall = $d( this , this .selectBall); //

this .dSelectCell = $d( this , this .selectCell);

this .countCell = this .width* this .height; //

},

/**

*

*/

start: function ()

{

setScore.call( this ,0); //

this .createCell(); //

this .callEvent( 'onstart' ); //

},

/**

*

*/

gameOver: function ()

{

//

this .callEvent( 'ongameover' );

},

/**

*

*/

createCell: function ()

{

/* */

}

}},

jsfw.Object //

)




* This source code was highlighted with Source Code Highlighter .






コメントですべてを説明しているようです。関数jsfw.Class(Object | Function、baseClass)は継承を実装し、オブジェクトのプロトタイプまたはプロトタイプを最初のパラメーターとして返す関数のいずれかを受け入れることしか説明できません(プライベートメソッドの実装用)。 これらは外部から見える主要なメソッドであり、開始することもできます:)。 セルクラスを作成した後に実装するcreateCellメソッド。

セルクラス


セルにはボールのみを含めることができ、クリックすると応答するため、ボールとonclickイベントを追加、削除するメソッドを実装します。

var Cell = jsfw.Class({

__constructor: function (x,y)

{

//

this .x = x;

this .y = y;

/*

$.create DOM , , DOM

*/

this .dom = $.create( 'div' ,{

className: 'Cell' , //

onclick:$d( this , this .click) //

}, this .dom);

},

/**

*

* @param

*/

addBall: function (ball)

{

if (ball.cell) ball.cell.ball = null ; // ( )

this .ball = ball; //

ball.cell = this ; //

this .dom.appendChild(ball.getDom()); // DOM

},

/**

*

*/

removeBall: function ()

{

$.remove( this .ball.getDom()); // DOM

this .ball.cell = null ; //

this .ball = null ;

},

/**

*

*/

isBall: function ()

{

return !! this .ball;

},

/**

*

*/

getBall: function ()

{

return this .ball;

},

/**

* DOM

*/

getDom: function ()

{

return this .dom;

},

/**

*

*/

click: function ()

{

// onclick

return this .callEvent( 'onclick' );

}

},jsfw.Object);




* This source code was highlighted with Source Code Highlighter .






すでにスタイルがあります。float:leftを使用するセルと、セルとコンテナの幅と高さの厳密な設定は、必要に応じて単純に加算されます。 このクラス以上に、彼から必要なものすべてに触れることはしません。彼はその方法を知っています。 次に、セルの作成を実装します。 フィールド全体を移動し、セルを作成してイベントを追加するだけです。 セルを格納するための配列は1次元です。 配列内のセルの位置は、式x * this.width + yによって計算されます。便宜上、関数getIndex(x、y)を作成し、座標が指定された範囲内にあるかどうかをチェックし、そうでない場合は-1を返します。 このための関数を作成して、Gameクラスに追加しましょう。

/**

*

*/

createCell: function ()

{

$.empty( this .dom); // DOM

var p = $.create( 'div' ,{className: 'Pole' }); //

//

for ( var y=0,lenY= this .height;y<lenY;y++)

for ( var x=0,lenX= this .width;x<lenX;x++)

{

var cell = new Cell(x,y); //

cell.addEvent( 'onclick' , this .dSelectCell); // ,

p.appendChild(cell.getDom()); // DOM

this .cell[ this .getIndex(x,y)] = cell; // ,

}

this .dom.appendChild(p); // DOM

},

/**

*

*/

selectCell: function (cell)

{

alert( ' x=' +cell.x+ ' y=' +cell.y);

},

/**

*

* @param X

* @param Y

*/

getIndex: function (x,y)

{

return (x >= 0 && x < this .width && y>=0 && y< this .height)?x* this .width+y:-1;

}




* This source code was highlighted with Source Code Highlighter .






さて、すべてを正しく行った場合、スクリプトを実行すると、素敵なメッシュが表示されます:)。

ボールクラス


私たちと一緒にいるボールのクラスは、onclickイベントにのみ応答し、点滅によってそれ自体を区別することができます。 ボール自体を探すと、ボールの色が選択されます。

var Ball = jsfw.Class({

countColor:6, //

__constructor: function ()

{

this .color = c = Math.rand(1, this .countColor); // , .Ball{}

this .dom = $.create( 'div' ,{className: 'Ball Ball' + this .color,onclick:$d( this , this .click)}, this .dom); // DOM , onclick

},

/**

* DOM

*/

getDom: function ()

{

return this .dom;

},

/**

*

*/

click: function ()

{

return this .callEvent( 'onclick' );

},

/**

*

*/

select: function ()

{

// jsFW.fx.blink time

this .blink = jsFW.fx.blink( this .dom,{time:300}); //

},

/**

*

*/

unselect: function ()

{

if ( this .blink) //

{

this .blink.stop();

delete this .blink;

}

},

/**

* ,

*/

remove: function ()

{

if ( this .cell)

{

$.remove( this .dom);

this .cell.ball= null ;

this .cell = null ;

}

}

},jsfw.Object);




* This source code was highlighted with Source Code Highlighter .








これで、さらにいくつかのメソッドをGameクラスに追加して、ランダムな空きスペースにボールを作成および追加できます。

/**

*

*/

addRandBall: function (ball)

{

/*

this.emptyCell

*/

var i = Math.rand(0, this .emptyCell.length-1); //

this .cell[ this .emptyCell[i]].addBall(ball); //

this .emptyCell.splice(i,1); // , ..

},

/**

*

*/

newBall: function (){

this .emptyCell = []; // , ,

for ( var i= this .cell.length;i--;)

{

if (! this .cell[i].isBall()) this .emptyCell.push(i); //

}

/*

this.countNewBall



*/

for ( var i=Math.min( this .countNewBall, this .emptyCell.length);i--;)

{

var ball = new Ball();

ball.addEvent( 'onclick' , this .dSelectBall); //

this .addRandBall(ball); //

}

//

if ( this .emptyCell.length<= this .countNewBall) this .gameOver();

},

/**

*

*/

selectBall: function (ball){

if ( this .seletedBall) this .seletedBall.unselect(); //

this .seletedBall = ball; //

ball.select();

return false ;

}




* This source code was highlighted with Source Code Highlighter .








また、このような開始関数にnewBallメソッドへの呼び出しを追加する必要があります

start: function ()

{

setScore.call( this ,0); //

this .createCell(); //

this .newBall();

this .callEvent( 'onstart' ); //

},




* This source code was highlighted with Source Code Highlighter .








セル選択関数selectCellを少し変更してみましょう

selectCell: function (cell)

{

if (!cell.isBall() && this .seletedBall) //

{

cell.addBall( this .seletedBall); //

this .newBall();

}

return false ;

}




* This source code was highlighted with Source Code Highlighter .






実行して何が起こったかを確認します。 これで、ボールが落ちて自由な場所に移動できるフィールドができました。



記事は大きいことがわかったので、いくつかの部分に分けることにしました。



おわりに



ゲームのロジックに取り組むためにすべてを準備しましたが、これはゲームプログラミングの最も興味深い部分です。 次の部分では、収集されたラインをチェックし、焼けたボールのポイントをカウントするアルゴリズムを検討します。 そして、道を見つけるための最も興味深いアルゴリズム、私たちのボールは今のように飛ぶべきではありません-私たちは彼らの翼を切ります。 > :)



はい、最初の部分のソースをほとんど忘れていました



この例では、ボールの代わりに正方形が使用されました。 ボールは不明な理由で忙しかった。



私はコメントで建設的な批判を待ち、スペルミスでのみスペルミスを待っています



All Articles