最近、友人から、JS を使用して、「白いブロックを踏まないでください」という小さなゲーム プログラムを模倣するのを手伝ってほしいと頼まれました。しかし、彼がくれたソース コードは複雑でコメントがなく、理解するのが難しかったです。ということで、主にJSを使ってDOMや配列を操作する小さなゲームを自分で考えて作ってみました。
プログラムのアイデア: 図に示すように: ゲーム領域の CSS を相対配置とオーバーフロー非表示に設定します。2 つの「ゲーム ボード」に 24 個の正方形が配置され、各行に 1 つの黒い正方形がランダムに生成されます。 「ゲーム盤」の面 下にスクロールして交互に表示し、各操作パネルの黒ブロックの位置を配列に格納し、クリックするたびに配列をポップアウトして比較します(ここがハイライトだと思います...)。
ここにゲームの GitHub アドレスがあります。そこにアクセスし、中央のメニューの右端にある [ZIP をダウンロード] ボタンをクリックすると、HTML と JS が含まれており、サーバーは必要ありません。
以下は、主要な部分についてのコメントを含む具体的な実装です。
HTML 部分:
<!DOCTYPE html> <html> <head><title>别踩白块</title></head> <body> <div id="gameZone"><div id="boardb" style="position: absolute;top: 0px;"></div></div>//初始化一个boardb,使ab同时存在 </body> </html>
CSS 部分:
#gameZone{width: 302px;height: 602px;border: 1px plain green;margin: 20px auto;position:relative;overflow: hidden;} //ゲーム領域、境界線を削除するにはあと 2 ピクセルが必要です。 300*600
.square{幅: 75px;高さ: 100px;float: left;border: 1px 単色黒;}
.squareBlack{width: 75px;height: 100px;border: 1px Solid black;float: left;background: black;}//各小さな正方形は 75*100 で、黒い小さな正方形の背景色を設定します。
JS 部分:
機能の紹介は次のとおりです:
グローバル変数の初期化
var loc=600;//黑块落地失败判定 var count=0;//初始化击中黑块总数 var locArr=[];//初始化游戏板上黑块位置的 var order=(function(){ var ord="A"; return function(){ if(ord=='boarda')ord='boardb'; else ord='boarda'; return ord; } })()
//クロージャ関数を使用して、毎回作成されるゲームボードのIDをboardaとboardbにします。実際にはグローバル変数を使用することもできますが、もう少し形式的です。 。 。
各クリックの結果を決定する関数
function judge(){ var num=this.id.substr(3)//获取元素的ID号 if(num!=locArr.pop()){ //与位置数组pop出的对比 clearTimeout(timer); alert("你的得分为:"+count+"分!"); return; //失败清除定时器,结算分数。 }else{ loc+=100; this.style.background="silver"; count+=1;//成功将落地标志加方格的高度,将方格背景色改变一下,击中数+1 } if(count!=0&&count%15==0){ clearTimeout(timer); newtimer=50-count/15*5; timer=setInterval('fall()',newtimer); }//每击中15个后将速度加快一点,这个式子可自行定义。 }
大きなボックス内の小さな黒いボックスの位置の乱数を生成します。この関数はゲームボードが作成されるたびに呼び出され、生成された番号に基づいて小さな黒いボックスの位置が定義されます。
function generateRand(){ var numArr=[]; for(var j=0;j<6;j++){ var num=Math.floor(Math.random()*4)+j*4; numArr.push(num); } return numArr; }
各呼び出しは、ゲーム領域の上にスクロールダウンするゲームボードを生成し、黒い部分の数字を locArr に PUSH します
function drawBoard(){ var temArr=generateRand();//这里应用一个临时的位置数组,为了防止两块游戏板之间的位置冲突。 locArr=temArr.concat(locArr);//将临时数组相连到全局位置数组中 var board=document.createElement('div'); board.setAttribute('id',order()); board.style.position="absolute"; board.style.top='-600px'; for(var i=0;i<24;i++){ var ele=document.createElement('div'); ele.setAttribute('id',"ele"+i); if(temArr.indexOf(i)>-1){ //判断当前创建的小方块的ID序列是否属于临时位置数组 ele.setAttribute('class','squareBlack') }else{ ele.setAttribute('class','square'); } ele.addEventListener('click',judge,false); //给每一个小方格添加点击判定函数judge board.appendChild(ele); } var gameZone=document.getElementById('gameZone'); gameZone.appendChild(board); }
スクリプト内に存在する 2 つのゲーム ボードを見つけて、下にスクロールします
function fall(){ gameZone=document.getElementById('gameZone'); var boarda=document.getElementById('boarda');//因为ab两个游戏板全局一直存在,所以不需要定义找不到时的逻辑 var anowtop=parseInt(boarda.style.top);//因为获取到的top位置是xxxpx类型,所以用一个parseInt()将其转换为整数便于处理。 if(anowtop==595){ //这里数目为595而不是600是因为在这一帧删除后,下一帧正好600px,刚好使两块游戏板衔接完好。 gameZone.removeChild(boarda); drawBoard();//删除游戏区域的游戏板,并在最上方新生成一个。 } anowtop+=5; boarda.style.top=anowtop+"px"; var boardb=document.getElementById('boardb'); var bnowtop=parseInt(boardb.style.top); if(bnowtop==595){ gameZone.removeChild(boardb); drawBoard(); } bnowtop+=5; boardb.style.top=bnowtop+"px"; loc-=5; if(loc==0){ clearTimeout(timer); alert("你的得分为:"+count+"分!"); return; } //每一帧将落地判定减5,当落地判定为0时表示落地,结算分数。 }
ページのゲーム領域がロードされた後に関数を呼び出せるように、window.onload 関数にメイン呼び出しを記述します。
window.onload=function(){ drawBoard(); fall(); var timer=setInterval('fall()',50); }
ゲーム拡張機能:
ページ UI の追加: 最初の HTML は非常にシンプルなので、ボタンを設定し、クリックして開始機能をトリガーする UI も簡単に変更できます。
ゲームの難易度を変更する: setInterval の値を変更すると、ジャッジ関数のインターバル数を変更したり、落下加速度の表現を最適化することもできます。
スコアやランキングなどの追加: ajax を使用してサーバーに接続し、ゲーム終了後に結果をデータベースに書き込み、データ内のランキングを参照します。
アーケード モードに変更: タイミングを削除し、ゲーム ボードをクリックするたびに小さな正方形ずつドロップするようにジャッジ機能を変更します。合計数、開始タイミング、終了タイミングを設定します。