Web プログラミング

【もりけん塾93記事】JavaScriptでブロック崩しゲームの写経

フロントエンドエンジニアを目指している、まゆ(@Ymayu_it)です。

 

すごろくを理解して作成しようとやってみてもまだ難しかったので、JavaScriptの写経に戻りました。

 

今日はJavaScriptのブロック崩し。

ブロック崩し

 

youtubeでJavaScriptのブロック崩しがあったので写経しました。

書き方や流れなどコードを打った方が良いのかなと思い、写経しました。

 

 

htmlとJavaScript

動画ではindex.htmlにcssとJavaScriptを入れて作成されていました!

 

 htmlとJavaScript
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>blockgame</title>
</head>
<body>
 
//JavaScriptスタート
<script>
//キャンバス作成
//キャンバス内にブロック崩しゲームを実行
//createElementはタグだけが指定された要素を作るときに使うメソッド、画像を表示させるときのように作成することでも使う
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
//キャンバスのサイズ
canvas.width = 400;
canvas.height = 400;
//キャンバスを中央揃えと背景色をグレーに
//setAttribute()メソッドは属性の指定として使い、引数には設定した属性名と値を指定
//setAttribute()メソッドは存在しない属性に対しnullを返す
//今回はcssを変更している
canvas.setAttribute('style','display:block;margin:auto;background-color:#ddd');
//appendとappendChileの違いはjQueryかJavaScriptの違い
//appendChiledは親要素に引数を追加し親要素内の末尾に追加されるもの
//用途は自動署名や固定挨拶、クリックしてアイコンを増やすこと
//ブロックゲームではcanvas表示のために記載
document.body.appendChild(canvas);
//ブロック崩しのプログラム
const ball = {
//nullはObjectの値が存在しないことを示す特殊な値で引数に指定するものはないよと伝えていること
x: null,
y: null,
width: 5,
height: 5,
speed: 4,
dx: null,//跳ね返り
dy: null,//跳ね返り
update: function(){
ctx.fillRect(this.x, this.y, this.width, this.height);
ctx.fill();
//ボールが壁にあたったときに跳ね返す条件分岐
if (this.x < 0 || this.x > canvas.width)this.dx *= -1;//反転は-1
if (this.y < 0 || this.y > canvas.height)this.dy *= -1;//反転は-1
//ボールが地面にあたったときゲームを終了させる場合は
//if(this.y > canvas.height)を条件式にプログラムする
//this.プロパティ名で自分自身のプロパティにアクセスできるのでデータ取得で使う
this.x += this.dx;
this.y += this.dy;
}
}
//
const paddle = {
x: null,//x座標
y: null,//y座標
width: 100,//幅
height: 15,//高さ
speed: 0,
//パドルの描画はctxを取得する必要がある
//塗りつぶしのcanvas
update: function(){
ctx.fillRect(this.x, this.y, this.width,this.height);
ctx.fill();
this.x += this.speed;//パドルを動かす
}
}
const block = {
width: null,//可変するようにしたいからひとまずnull
height: 20,
data: [],//全ブロックの位置情報を格納する
update: function() {
this.data.forEach(brick =>{
ctx.strokeRect(brick.x, brick.y, brick.width, brick.height);//ブロックはstrokeで描く
ctx.stroke();strokeを実行
})
}
}
//ブロックの配置を配列で指定できるようにする
//ここでレベル別に作成できる
//0:非表示 1:表示
const level = [
[0,0,0,0,0,0],//0がブロックがない状態
[0,0,0,0,0,0],
[1,1,1,1,1,1],//1はブロックがある状態
[1,1,1,1,1,1],
[1,1,1,1,1,1],
[1,1,1,1,1,1],
]
//パドルを半分の位置に持ってくる処理
const init = () => {
paddle.x = canvas.width / 2 - paddle.width / 2;//中央値で幅を割る2
paddle.y = canvas.height - paddle.height;
ball.x = canvas.width / 2;
ball.y = canvas.height / 2 + 50;//対角線上の跳ね返りをずらす
ball.dx = ball.speed;
ball.dy = ball.speed;
block.width = canvas.width / level[0].length;
//全ブロックの位置情報を設定する
//0か1かを判別し1の場合だけデータを作る
for (let i = 0; i < level.length; i++){
for(let j=0; j<level[i]. length; j++){
if(level[i][j]){
block.data.push({
x: block.width * j,
y: block.height *i,//縦方向に並べる
width: block.width,
height: block.height
})
}
}
}
}
//あたり判定
//2つのObjectをtrueとfalseで返す
const collide = (obj1, obj2) => {
return obj1.x < obj2.x + obj2.width &&
obj2.x < obj1.x + obj1.width &&
obj1.y < obj2.y + obj2.height &&
obj2.y < obj1.y + obj1.height;
}
//メイン処理
const loop = () =>{
ctx.clearRect(0,0,canvas.width,canvas.height);//指定した範囲を削除する
paddle.update();
ball.update();
block.update();
//ボールとパドルのあたり判定
if(collide(ball, paddle)){
ball.dy *= -1;//パドルにあててボールを返す
ball.y = paddle.y - ball.height; //パドルの端にボールがあたったときにめり込まないようにする
}
//ボールとブロックのあたり判定
block.data.forEach((brick, index) => {
if(collide(ball, brick)){
ball.dy *= -1;//ボールが当たればy方向へ返す
block.data.splice(index, 1);//あたったブロックを消す役割
}
})
//ブラウザの最適なタイミングで繰り返し処理
window.requestAnimationFrame(loop);
}
init();
loop();
//キーボートのイベント処理
//対象要素.addEventListener('イベントタイプ名',実行したい関数名);イベント発生をあらかじめ指定して関数を実行
document.addEventListener('keydown', e => {
//keyプロパティで表示
if(e.key === 'ArrowLeft') paddle.speed = -6;//左方向へ-6
if(e.key === 'ArrowRight') paddle.speed = 6;//右方向へ6
})
//キーボートのイベント処理(キーボートから離したとき)
document.addEventListener('keyup', () => paddle.speed = 0);
</script>
</body>
</html>

 

まずは骨組みを作りでconstをつくり、メインを作成していく流れで動画で紹介されていました。

終わりに

模写をしていつも終わっていたので、何がどう使われいているのかを今回調べる方法をとってみました。

 

これだと眠くならずに理解しながらできるかな?楽しいけど理解できないと眠くなるので対策。

 

 

 

もりけん塾(@terrace_tech

Thanks:もりけんさん

 

もりけんさんの『武骨日記』へ

 

-Web, プログラミング

© 2020 Mayu_Yamada