ブロック崩しゲーム
初めてjavascriptでゲームをつくりました。
https://app.u-chop.com/breakout/
下記のサイトに沿ってブロック崩しをつくってみました。
【そのままのJavaScriptを使ったブロックくずしゲーム】
https://developer.mozilla.org/ja/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript
自分で作ったゲームを見返して、理解を深めていけたらと思ってます。
自己満足の自分のメモとしてまず書きます。
ステップ1
■今回私は、cssとjavascriptそれぞれファイルをつくった
【 css 】
■ * の padding 、 margin を消してみても特に変化なし
■ canvas の display は margin を使うため(canvas を画面の中央に持ってくるため)だから、なくても良し
(inline-block にしてみたら canvas が左によるだけだった)
■ 今回背景色以外は特に必要なし(なんなら背景白ならcssなくてもいける)
【 canvasタグ 】
■ html と javascript を使って、グラフや図形などを表示できる
■幅と高さの初期値 → 300 × 150
■幅と高さは html に書き込む
→ css に width と height を追加すると、
html で設定している幅と高さで表示していた内容のままで拡大縮小する
【 var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d"); 】
変数canvas に <canvas> を代入する
変数ctx に 2Dコンテキスト(手法)を javascript で操作するための CanvasRenderingContext2Dオブジェクト を代入する
■ CanvasRenderingContext2Dオブジェクト
→「線を引く」「塗りつぶす」などの2Dグラフィックを描くためのAPIが備わっている
■この変数ctx に <canvas> に描画したい図形などを保存していく
例)ctx.globalAlpha = 0.5; → <canvas> のグラフィックの透明度を 0.5 にする
【 rect() と fillRect() の違い 】
■ rect
rect だけでは何も表示されない。一緒に stroke や fill を使う必要がある。
■ fillRect
fillRect の範囲は塗りつぶされる。線で囲むことはできない。
【 closePath() 】
パスを閉じるときに使う
rect などですでに四角形が完成しているときは書かなくても変化なし
【 Math.PI 】
円周率を取得できる
■ Math.PI → 半円 ( .arc の場合)
■ 2 * Math.PI → 円 ( .arc の場合)
例)ctx.arc(75, 75, 50, 0, 2 * Math.PI);
→ x軸75、y軸75 を中心とした半径50 の円を描画
ステップ2
■ var x = canvas.width/2; → <canvas> の中央(キャンバス幅の半分)
■ var y = canvas.height-30; → <canvas> の下から30
■ setInterval() の delay でボールの速さが決まる
■ dx と dy の数字でボールの進む角度が決まる
ステップ3
■ if(y + dy < 0) {dy = -dy;}
→もし y座標が 0 未満になったなら、dy に -dy を代入する
→下に跳ね返る
ステップ4
■ (canvas.width-paddleWidth)/2
→パドルを中央に表示する
canvas.width/2 だと、パドル幅の分だけ右に寄ってしまうため、paddleWidthを引く
【 キーボードイベントオブジェクト 】
■ keydown → キーが押されたら
■ keyup → キーが離されたら
例) document.addEventListener("keydown", keyDownHandler, false);
→キーが押されたら、関数keyDownHandler を実行する(初期値は false)
■変数e → イベント引数が存在していた場合、変数e が保持している
■ e.key → 押されたキーについての情報
ステップ5
■ document.location.reload() と location.reload() に違いはあまりないように感じる
■ clearInterval() → setInterval() を解除する
■ x > paddleX && x < paddleX + paddleWidth
意味)ボールの中心がパドルの右端と左端の間にある場合
・変数x はボールの x座標
・paddleX はパドルの左上の x座標
・paddleWidth はパドルの幅
ステップ6
【ブロックのために作った変数】
・ブロックを縦に何個並べるかの数(行)
・ブロックを横に何個並べるかの数(列)
・ブロックの幅
・ブロックの高さ
・ブロックのパディング
・一番左上にくるブロックの上からの位置
・一番左上にくるブロックの左からの位置
【 ブロックを配置するための座標を配列に代入する 】
for(var c=0; c<brickColumnCount; c++) {
bricks[c] = [];
for(var r=0; r<brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0 };
}
}
■ for(var c=0; c<brickColumnCount; c++)
意味)変数c が変数brickColumnCount 未満の場合、1 を加算して繰り返す
■ bricks[c] = [];
意味)配列bricks の c番目の要素に、空の配列を代入する
変数c は、0~4 の間繰り返されるから、配列bricksは
[ [ ], [ ], [ ], [ ], [ ]];
■ bricks[c][r] = { x: 0, y: 0 };
意味)配列bricks の c番目の要素の中の r番目の要素に、 { x: 0, y: 0 }; を代入する
配列bricks は下記のようになる
[ [ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } ], [ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 }], [ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } ], [ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } ], [ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } ]];
■配列bricks の x と y に正しい数字を代入して描画すればブロックを配置できる
【 ブロック1つ1つの x座標, y座標 】
■ var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
意味)変数c にブロック幅とブロックパディングを足した数を掛けて、変数brickOffsetLeft を足す
これから描画したい列の前までの列の幅を足した合計になる
3列目を描画する場合、変数c は 2 なので、ブロック幅とパディングを 2列分足すことになる
ステップ9
■ .clientX → スクロール関係なく、ページ左上を 0 としたマウスの位置を取得
■ .offsetLeft → スクロール関係なく、イベントが起きた要素の位置を取得
どれだけスクロールをしていようと、左上が 0 になる
【 パドルの動きをマウスの動きと連動させる 】
function mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if(relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth/2;
}
}
イベント発生したときに、マウスの位置がキャンバス内にあった場合
マウスの x座標とパドルの中心の x座標を同じにする
■ e.clientX → マウスの位置の x座標
■ canvas.offsetLeft → キャンバスの位置の x座標
■ paddleX = relativeX - paddleWidth/2;
意味)マウスの位置にパドルの中心を持ってくる
relativeX をそのまま代入すると、マウスの位置がパドルの左端になる
パドル幅の半分を引けば、マウスの位置よりパドルの左端が左にずれるから中心に持ってこれる
ステップ10
■ ! 変数名 → 0
if ( !lives ) → 意味)もし変数lives が 0 ならば
例)
for(var i = 2; i > -6; i--) {
if(!i) {
document.writeln(i);
}
}
結果) 0