質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

3884閲覧

HTML5のシューティングゲームで敵の弾発射と爆発アニメーションを実現したい

nosonosolife

総合スコア42

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2015/12/15 02:39

編集2015/12/15 23:04

現在HTML5のcanvasを使用してシューティングゲームを制作しており、
自機・敵の移動、自機の弾が当たると敵が消える、という所まではできたのですが、

  • 敵に弾が当たった時の爆発
  • 敵の弾発射

の部分で詰まっています。

Javascript

1window.onload = function() { 2 var canvas = document.getElementById('screen'); 3 canvas.width = 640; 4 canvas.height = 480; 5 var ctx = canvas.getContext('2d'); 6 document.addEventListener("keydown", keyDownFunc); 7 document.addEventListener("keyup", keyUpFunc); 8 var keyDown = {}; 9 var key = { 10 U: 38, 11 L: 37, 12 D: 40, 13 R: 39, 14 S: 32 15 }; 16 var player = new Player(); //自機 17 var pbullet = []; //自機の弾 18 var enemys = []; //敵 19 var ebullet = []; //敵の弾 20 var explosion = []; //爆発 21 var ShotBInterval = 0; //弾の有効期限 22 var EInterval = 0; //敵の有効期限 23 var playerdamage = 0; //自機のダメージフラグ 24 var enemysdamage = 0; //敵のダメージフラグ 25 // 音声ファイル 26 var AUDIO_LIST = { 27 "bshot": new Audio("sound/bshot.mp3"), 28 "bomb": new Audio("sound/bomb.mp3"), 29 "bstruck": new Audio("sound/bstruck.mp3"), 30 "fall": new Audio("sound/fall.mp3"), 31 "damage": new Audio("sound/damage.mp3") 32 }; 33 aloop = setInterval(loop, 1000 / 60); 34 35 function keyDownFunc(e) { 36 keyDown[e.keyCode] = true; 37 } 38 39 function keyUpFunc(e) { 40 keyDown[e.keyCode] = false; 41 } 42 // メイン 43 function loop() { 44 ctx.clearRect(0, 0, canvas.width, canvas.height); 45 playerDraw(); 46 enemyDraw(); 47 if(playerdamage == 0){ 48 playerMove(); 49 if (keyDown[key.S]) pBulletShot(); 50 pbulletDraw(); 51 pbulletMove(); 52 calcpBulletLimit(); 53 bulletInterval(); 54 enemypush(); 55 enemyMove(); 56 enemyInterval(); 57 }else{ 58 player_damage_out(); 59 } 60 for (var i = 0; i < enemys.length; i++) { 61 if (hitCheck(player.x, player.y, player,enemys[i].x, enemys[i].y, enemys[i])) { 62 playerdamage = 1; 63 AUDIO_LIST["damage"].play(); 64 } 65 for (var c = 0; c < pbullet.length; c++) { 66 if (hitCheck(pbullet[c].x, pbullet[c].y, pbullet[c],enemys[i].x, enemys[i].y, enemys[i])) { 67 pbullet.splice(c, 1); 68 enemys.splice(i, 1); 69 c--; 70 i--; 71 AUDIO_LIST["bstruck"].play(); 72 AUDIO_LIST["bstruck"] = new Audio(AUDIO_LIST["bstruck"].src); 73 AUDIO_LIST["damage"].play(); 74 AUDIO_LIST["damage"] = new Audio(AUDIO_LIST["damage"].src); 75 AUDIO_LIST["bomb"].play(); 76 AUDIO_LIST["bomb"] = new Audio(AUDIO_LIST["bomb"].src); 77 } 78 } 79 } 80 } 81 // 自機 82 function Player() { 83 this.width = 55; 84 this.height = 46; 85 this.x = 10; 86 this.y = ((canvas.height / 2) - (this.height / 2)); 87 this.dx = 7; // x座標の速度 88 this.dy = 7; // y座標の速度 89 this.friction = 1; // 摩擦(減速率) 90 this.alpha = 1; // 透明度 91 this.outdy = 0; // 敵に当たった時のy座標の速度 92 } 93 94 function playerDraw() { 95 // 表示 96 var img = new Image(); 97 img.src = "img/player.png"; 98 /* 画像を描画 */ 99 ctx.drawImage(img, player.x, player.y); 100 ctx.globalAlpha = player.alpha; 101 } 102 103 function playerMove() { 104 // 加速 105 if (keyDown[key.U] || keyDown[key.D] || keyDown[key.L] || keyDown[key.R]) { 106 if (keyDown[key.U] || keyDown[key.D] && keyDown[key.L] || keyDown[key.R]) 107 player.friction = 0.7; 108 if (keyDown[key.U]) player.y -= (player.dy * player.friction); 109 if (keyDown[key.L]) player.x -= (player.dx * player.friction); 110 if (keyDown[key.D]) player.y += (player.dy * player.friction); 111 if (keyDown[key.R]) player.x += (player.dx * player.friction); 112 if (keyDown[key.S]) player.friction *= 0.7; 113 if ((canvas.width - player.width) <= player.x) { 114 player.x = canvas.width - player.width; 115 } 116 if (player.x < 0) { 117 player.x = 0; 118 } 119 if ((canvas.height - player.height) <= player.y) { 120 player.y = canvas.height - player.height; 121 } 122 if (player.y < 0) { 123 player.y = 0; 124 } 125 } 126 } 127 function player_damage_out(){ 128 player.outdy += 0.1; 129 player.y += (player.outdy * 3); 130 if ((canvas.height - player.height) > player.y) { 131 AUDIO_LIST["fall"].play(); 132 } 133 } 134 // 弾 135 function Bullet(size, x, y, speed) { 136 this.width = 32; 137 this.height = 15; 138 this.x = x; 139 this.y = y; 140 this.speed = speed; 141 this.friction = 0.9; // 摩擦(減速率) 142 this.limit = 140; 143 } 144 145 function pBulletShot() { 146 if (ShotBInterval == 0) { 147 pbullet.push(new Bullet(0, player.x + (player.width / 2), player.y + ( 148 player.height / 2), 5)); 149 AUDIO_LIST["bshot"].play(); 150 AUDIO_LIST["bshot"] = new Audio(AUDIO_LIST["bshot"].src); 151 ShotBInterval = 15; 152 } 153 } 154 155 function pbulletDraw() { 156 for (var i = 0; i < pbullet.length; i++) { 157 ctx.beginPath(); 158 var img = new Image(); 159 img.src = "img/p_bullet.png"; 160 /* 画像を描画 */ 161 ctx.globalCompositeOperation = "destination-over"; 162 ctx.drawImage(img, pbullet[i].x, pbullet[i].y); 163 } 164 } 165 166 function pbulletMove() { 167 for (var i = 0; i < pbullet.length; i++) { 168 pbullet[i].x += pbullet[i].speed * pbullet[i].friction; 169 } 170 } 171 172 function calcpBulletLimit() { 173 for (var i = 0; i < pbullet.length; i++) { 174 if (pbullet[i].limit > 0) { 175 pbullet[i].limit--; 176 } else { 177 pbullet.splice(i, 1); 178 i--; 179 } 180 } 181 } 182 183 function bulletInterval() { 184 if (ShotBInterval > 0) { 185 ShotBInterval--; 186 } 187 } 188 // 敵 189 function Enemy() { 190 this.width = 53; 191 this.height = 51; 192 this.x = canvas.width; 193 this.y = Math.floor(Math.random() * (canvas.height - this.height)); 194 this.dx = 0; // x座標の速度 195 this.dy = 0; // y座標の速度 196 this.acceleration = 0.3; // 加速度 197 this.friction = 0.9; // 摩擦(減速率) 198 } 199 200 function enemypush() { 201 if (EInterval == 0) { 202 enemys.push(new Enemy()); 203 EInterval = 45; 204 } 205 } 206 207 function enemyDraw() { 208 for (var i = 0; i < enemys.length; i++) { 209 var img = new Image(); 210 img.src = "img/enemy.png"; 211 /* 画像を描画 */ 212 ctx.drawImage(img, enemys[i].x, enemys[i].y); 213 } 214 } 215 216 function enemyMove() { 217 for (var i = 0; i < enemys.length; i++) { 218 // 加速 219 enemys[i].dx += enemys[i].acceleration; 220 // 減速 221 enemys[i].dx = enemys[i].dx * enemys[i].friction; 222 enemys[i].dy = enemys[i].dy * enemys[i].friction; 223 // 移動 224 enemys[i].x -= enemys[i].dx; 225 enemys[i].y -= enemys[i].dy; 226 if ((enemys[i].x + enemys[i].width) < 0) { 227 enemys.splice(i, 1); 228 i--; 229 } 230 } 231 } 232 233 function enemyInterval() { 234 if (EInterval > 0) { 235 EInterval--; 236 } 237 } 238 // 衝突判定 239 var hitCheck = function(x1, y1, obj1, x2, y2, obj2) { 240 var cx1, cy1, cx2, cy2, r1, r2, d; 241 // 中心座標の取得 242 cx1 = x1 + obj1.width / 2; 243 cy1 = y1 + obj1.height / 2; 244 cx2 = x2 + obj2.width / 2; 245 cy2 = y2 + obj2.height / 2; 246 // 半径の計算 247 r1 = (obj1.width + obj1.height) / 4; 248 r2 = (obj2.width + obj2.height) / 4; 249 // 中心座標同士の距離の測定 250 // Math.sqrt(d) -- dのルートを返す 251 // Math.pow(x, a) -- xのa乗を返す 252 d = Math.sqrt(Math.pow(cx1 - cx2, 2) + Math.pow(cy1 - cy2, 2)); 253 // 当たっているか判定 254 // ちなみに `return r1+r2 > d;` とだけ書いてもOK 255 if (r1 + r2 > d) { 256 // 当たってる 257 return true; 258 } else { 259 // 当たっていない 260 return false; 261 } 262 }; 263};

html

1<canvas id="screen"></canvas>

ご教授よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

len_souko

2015/12/15 06:38

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
liguofeng29

2015/12/15 09:08

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
sutonea

2015/12/15 10:38

こちらの質問が他のユーザから「質問の範囲が広すぎる」という評価を受けています わからない点を明確にし、調査したこと・試したことと共に記入していただくと、回答が得られやすくなります。
guest

回答1

0

敵が死亡した時に発生するイベント処理のようなものを自作しておいて、発生したら死亡した敵座標にエフェクトみたいな感じでいいのではないですかね?
敵の弾発射に関してですが自機の弾発射ができているなら特に問題はなく、組めるのではないかと思えるのですがどうなのでしょう?

どう詰まっているかを明確に示すと回答者も回答しやすいと思いますよ。
「こういうコードを書いたのですが上手くいきませんでした。こういう風に○○したいのですがどのようにすべきでしょうか」
といった形で、具体的に何をしたか、どうしたいかがあるといいのではないかと思います。

全く本題ではないのですが、命名規則がバラバラな気がします。
flagであることが分からないflag変数(playerdamage、enemysdamage)。
(しかもローワーキャメルになっていませんし)
定数は大文字とアンダースコア(AUDIO_LISTのように)なのかと思えば、keyは小文字だったり。
ShotBIntervalはなぜか先頭大文字ですし、EInterval、ebulletでも先頭文字がバラバラです。
(配列はローワーキャメルでないみたいな命名規則だったりするんですかね?)
他にもありますが……。
player_damage_out()では唐突にスネーク記法ですしね。
全体的に切って繋げたような状態なのが非常に気になります。
これではコードを読もうって人がなかなかいないかもしれません(読みにくさがあるので)。
定期的にリファクタリングの機会を設けるといいのではないかと思います。

投稿2015/12/25 06:14

Cf_cwd

総合スコア730

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問