JavaScriptを使ってシューティングゲームを作ろうとした時のことです。
動きを表現する方法として、JavaScriptのCanvasとsetIntervalを使って、「Canvasに絵を描く → 描いた絵を消す → また絵を描く →(以降、繰り返し・・・)」をすればよいことは分かりました。
でも、例えばシューティングの連射を表現したい場合、撃った弾の位置をすべて覚えさせておく必要があります!!(-_-;)
その際に配列をようやく理解して使うことができましたので、このページに書かせていただこうと思います!^^
(ちなみにスプラトゥーンのシューティングを作りました!よければ遊んで下さい^^ →コチラ)
やりたいことは下記のような内容です!
① プレイヤーから弾を撃ち放ち、玉の初期位置を記憶させる。
② 2発目以降に撃った玉の初期位置も記憶させる。
③ ①も②もsetIntervalで動かし続けるけど、敵に当たると弾は消える。
①と②はプレイヤーから弾が出るので、「 弾の初期位置 = プレイヤーが発射した位置 」です。
①~③のなかでも③がJavaScriptで処理するのがムズカシいぃぃ!と感じてました(;o;)
まず最初に これならできるんじゃない?(^_^) と思ってやろうとしたのが、letでそれぞれの弾の初期位置を定義する方法です。。。
結果的には廃案なのと、うまく動きもしないし、コードの書き方としても間違っているので、記すのもなんだか気恥ずかしいのですが、一応ぼんやりと下記コードをイメージしてました。
let PposiX; //プレイヤーのx座標
let PposiX; //プレイヤーのy座標
let TposiX; //弾のx座標
let TposiY; //弾のy座標
let num = 0; //弾ごとの追番用
function shot(){
num+=1
TposiX = TposiX + $(num); //※色々ムリなやつ。座標に追番付ける。
TposiY = TposiY + $(num); //※色々ムリなやつ。座標に追番付ける。
TposiX = PposiX;
TposiY = PposiY;
for(let a = 0; a <= num; a++){
~~~弾が進むようにTposiXとTposiYを変化させる処理~~~
}
}
自分で書いててわけ分からなくなってきました(笑)
先述のletで数字を定義してナンバリングするやり方は、今改めて読んでてもわけ分かりません^^;
ではどのようなコードで処理することに成功したかと言いますと、そうです、配列なんです!!
配列を使って実際に書いたのは以下のコードです(^_^)b
let PposiX; //プレイヤーの x 座標
let PposiX; //プレイヤーの y 座標
let TposiX = []; //弾の x 座標 ※[]が配列の書き方らしいです!
let TposiY = []; //弾の y 座標 ※[]が配列の書き方らしいです!
let yMove = -5; //弾の速度
function drawShot() {
TposiX.push(PposiX); //この push が配列の最後に入れるやつ!
TposiY.push(PposiY); //この push が配列の最後に入れるやつ!
}
function moveShot(){
for(let a = 0; a <= TposiY.length-1; a++){
TposiY[a] += yMove;
//ここから下は Canvas に弾を描く処理↓↓
//今回メインで話したいところじゃないけど載せます(^_^;)
ctx.beginPath();
ctx.arc(TposiX[a] + P_width/2, TposiY[a], T_radius, 0, Math.PI * 2);
//P_width はプレイヤーの幅で、T_radius は弾の半径
ctx.fillStyle = #CCFF00;
ctx.fill();
ctx.strokeStyle = #CCFF00;
ctx.lineWidth = 2;
ctx.stroke();
ctx.closePath();
}
ここで書いた push っていうのが配列の最後にヒョイっと入れてくれるヤツらしいです^^
これでプレイヤーが発射した位置 を 弾の初期位置として全部記憶していってくれます!!!
弾が敵に当たった時には敵も消しますが、弾を貫通型にさせないなら弾自体も消す必要があります!
あと撃った弾をすべて記憶し続けると配列が莫大になって、処理がカクカクする原因になりそうです。(ホントに原因になってるかは定かじゃないですが^^;)
なので弾がフレームアウトした時にも弾を消す処理を入れたいと思いました!
やり方は調べればいくらでも出ると思いますが、私も例に漏れず splice を使いました (^o^)v
実際に弾がフレームアウトした時の処理のコードは以下の通りです!!
for(let a = 0; a <= TposiY.length - 1; a++){
//↑この length というヤツで TposiY の配列に入ってる個数が分かります!
//↑配列が 0 から始まるから、配列に入ってる個数から 1 引いてます。
if((TposiY[a] + T_radius) <= 0){
TposiX.splice(a, 1); //この splice が a 番目に記憶させた弾の位置を 1 個消すコード
TposiY.splice(a, 1); //この splice が a 番目に記憶させた弾の位置を 1 個消すコード
}
「配列って色々な場で聞いたことはあるけど、別に使えなくても困らなくない?」と思っておりましたが、この度シューティングゲームを JavaScript で自分で作ってみてようやく配列の重要性が分かりました!!!
このページでは「配列を使えると便利だよー!」ということも言いたいですが、「私のようなド素人がプログラミングを理解するためには実際に書いてみるのが一番手っ取り早いんだなぁ」ということも言いたい、知ってもらいたいです^^
最後まで読んで下さりありがとうございました!
ここで書いたことが何かしら皆さまのお役に立ってくれればうれしいです!!(>人<)