🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

Q&A

解決済

1回答

413閲覧

作っているシューティングゲームが機能を追加したら正常に動かなくなった

faguri

総合スコア16

JavaScript

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

0グッド

0クリップ

投稿2019/12/30 04:52

前提・実現したいこと

JavaScriptでシューティングゲームを作っています
周りに球が入ってきたら敵が上に行くようにする機能を追加しました。
そうすると別の敵が上に行ったりなどの動作をするようになってしまいました。

該当のソースコード

JavaScript

1 2<html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>シューティングゲーム</title> 6 </head> 7 <body> 8 <canvas id="block_kuzushi"width="640"height="480"></canvas> 9 </body> 10</html> 11<script type="text/javascript"> 12 13// 定数 14var PADDLE_COLOR = 'YellowGreen' 15var PADDLE_COLOR_2 = 'Blu' 16var BACKGROUND_COLOR = '#000000' 17var BALL_COLOR = 'Red' 18var BALL_SIZE = 5; 19var BALL_X = 320; 20var BALL_Y = 290; 21var PADDLE_SIZE = 50; 22var CVS_WIDTH = 640; 23var CVS_HEIGHT = 480; 24var TEKI_SPEED = 7; 25var TEKI_X = 0; 26var TEKI_Y = 0; 27var TEKI_COLOR = 'Green' 28var BLOCK_STROKECOLOR = 'Black' 29var BALL_SPEED = 1; 30var TAMA_SPEED = 10; 31var FPS = 40; 32 33//変数 34var ctx = null; 35var paddle_x = 0; 36var paddle_y = 0; 37var teki_dx = 0; 38var teki_x = 320; 39var teki_y = 290; 40var ball_x = 0; 41var ball_y = 0; 42var ball_dx = 0; 43var ball_flg = false; 44var ball_dy = 0; 45var teki = null; 46var teki_2 = null; 47var teki_3 = null; 48var chek = false; 49var teki_dy=0; 50var teki_2_dy = 0; 51var teki_3_dy = 0; 52var teki = []; 53var isShot = false; 54var balls = []; 55var ball_i = 0; 56 57//マウスイベント 58window.addEventListener('mousemove',function(e){ 59 var rect = e.target.getBoundingClientRect(); 60 paddle_x = e.clientX - rect.left; 61},false); 62 63window.addEventListener('mousedown',function(e){ 64 isShot = true; 65},false); 66 67window.addEventListener('mouseup',function(e){ 68 isShot = false; 69},false); 70 71function main (){ 72 var cvs = document.getElementById('block_kuzushi'); 73 ctx = cvs.getContext('2d'); 74 75 paddle_x = 0; 76 paddle_y = CVS_HEIGHT - 60; 77 78 ball_x = BALL_X; 79 ball_y = BALL_Y; 80 81 teki_dy = BALL_SPEED; 82 teki_2_dy = BALL_SPEED; 83 teki_3_dy = BALL_SPEED; 84 85 for (var a = 0; a<3;a++){ 86 teki[a] = { 87 x:100 + (a*200), 88 y:100, 89 w:50, 90 h:50, 91 isBlock:true 92 }; 93 } 94 95 setInterval(function(){ 96 97 ctx.fillStyle = BACKGROUND_COLOR; 98 ctx.fillRect(0, 0, CVS_WIDTH, CVS_HEIGHT); 99 100 ctx.fillStyle = PADDLE_COLOR; 101 ctx.fillRect(paddle_x,paddle_y, 50,20); 102 103 if(isShot){ 104 balls[ball_i] = { 105 x:paddle_x+(PADDLE_SIZE/2), 106 y:paddle_y 107 }; 108 ball_i++; 109 } 110 111 for (var i = 0; i< balls.length;i++){ 112 ctx.fillStyle = BALL_COLOR; 113 ctx.beginPath(); 114 ctx.arc(balls[i].x, balls[i].y, BALL_SIZE, 0, 2 * Math.PI); 115 ctx.fill(); 116 balls[i].y = balls[i].y - TAMA_SPEED; 117 } 118 119 ball_x += ball_dx; 120 ball_y += ball_dy; 121 122 teki_dx += TEKI_SPEED; 123 124 for (var i=0;i<3;i++){ 125 teki[i].y += teki_dy; 126 if (teki[i].isBlock) { 127 128 for (var k = 0; k< balls.length;k++){ 129 var ball = balls[k]; 130 131 if (ball.y >= teki[i].y && ball.y <= teki[i].y+teki[i].h && ball.x >= teki[i].x && ball.x <= teki[i].x+teki[i].w){ 132 teki[i].isBlock = false; 133 } 134 135 if (ball.y <= teki[i].y+teki[i].h+55 && ball.x <= teki[i].x-55 || ball.x >= teki[i].x+teki[i].w+55){ 136 teki[i].y-=5; 137 } 138 } 139 // ブロック描画 140 ctx.fillStyle = TEKI_COLOR; 141 ctx.fillRect(teki[i].x, teki[i].y, teki[i].w, teki[i].h); 142 ctx.strokeStyle = BLOCK_STROKECOLOR; 143 ctx.strokeRect(teki[i].x, teki[i].y, teki[i].w, teki[i].h); 144 } 145 } 146 147 },parseInt(1000 / FPS)); 148} 149 window.onload = function(){ 150 main(); 151 } 152 153</script>

#追加したコード

JavaScript

1if (ball.y <= teki[i].y+teki[i].h+55 && ball.x <= teki[i].x-55 || ball.x >= teki[i].x+teki[i].w+55){ 2 teki[i].y-= 3}

こんな質問でごめんなさいお願いします。

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

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

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

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

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

mouse_484

2019/12/30 07:46

追加したコードが間違ってると思います
guest

回答1

0

ベストアンサー

別の敵が上に行ったりなどの動作をするようになってしまいました。

グローバル変数が多すぎて混乱しているはずです。

まずは、プレイ画面(Canvas)、自機(パドル)、敵機(ブロック)、弾(ボール)の
全てを抽象化してください。

共通する内容:

  1. 表示位置を決める x, y, width, height, X:x+width, Y:y+height
  2. ヒットテスト関数(現状では不要ですが、消滅する実装が予測される)
  3. {CanvasRenderingContext2D} を与えるだけで、それぞれの描画を行う render(ctx) 関数

これを、{GameObject} として定義して {Screen}, {Paddle}, {Block}, {Ball} に派生します。

複数出現したいものは、配列のままで構いません。
teki ... {Array.<Block>}
balls .. {Array.<Ball>}

javascript

1for( block of teki ) { 2 for( ball of balls ) { 3 // block.x, block.X, ball.x, ball.X から後退条件を算出して切り分ける。 4 } 5}

setInterval() 内でフレームをカウントすると、「出現から何フレーム目で動きを変える」といったことにも対応できるようになりますが、 抽象化(JavaScript OOP)が必須になります。

ご質問の「正常に動いていたであろう内容」をOOPで書いてみました。

追記)

周りに球が入ってきたら敵が上に行くようにする機能

「球」「敵」という言葉で「抽象的」に問いかけたはずです。

抽象化の恩恵

  1. 関連する2つのオブジェクトを演算させやすい(いずれかのオブジェクトにメソッドを加えればいい)。
  2. 自動で動く量(ベクトル)などの「パラメータ」を各オブジェクトに保持できる。

ゲームループ依存コンテンツのセオリーは、おおよそ次のような順番で処理して同期します。

  1. すべての表示オブジェクトのパラメータ変化(表示位置変更も含む) : update()
  2. すべての表示オブジェクトを描画し直す : render()

フレーム(setInterval())内がシンプルになれば、抽象化された描画対象が扱いやすくなるはずです。


このようなゲーム開発の考え方は、AR(拡張現実)のコンテンツに応用できると思います。

投稿2019/12/30 08:55

編集2019/12/31 08:12
AkitoshiManabe

総合スコア5434

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

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

faguri

2019/12/31 01:57

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問