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

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

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

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

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

JavaScript

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

Q&A

解決済

1回答

2258閲覧

javascriptを使ったテトリスゲームで落ちたブロックが消えてしまう

tyaan

総合スコア8

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

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

JavaScript

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

0グッド

0クリップ

投稿2020/01/01 07:41

javascript

1<!DOCTYPE html> 2<html lang="ja"> 3<head><meta charset="utf-8"></head> 4<body> 5<canvas id="can"></canvas> 6<script> 7 8//落ちるスピード 9const GAME_SPEED = 300; 10 11//フィールドサイズ 12const FIELD_COL = 10; 13const FIELD_ROW = 20; 14 15//ブロック一つのサイズ(ピクセル) 16const BLOCK_SIZE = 30; 17 18//スクリーンサイズ 19const SCREEN_W = BLOCK_SIZE * FIELD_COL; 20const SCREEN_H = BLOCK_SIZE * FIELD_ROW; 21 22//テトロミノのサイズ 23const TETRO_SIZE =4; 24 25const TETRO_COLORS =[ 26 // "#000", //0空 27 "#6CF", //1水色 28 "#F92", //2オレンジ 29 "#66F", //3青 30 "#C5C", //4紫 31 "#FD2", //5黄色 32 "#F44", //6赤 33 "#5B5" //7緑 34]; 35 36const TETRO_TYPES = [ 37 // [], // 0.空っぽ 38 39 [ // 1.I 40 [ 0, 0, 0, 0 ], 41 [ 1, 1, 1, 1 ], 42 [ 0, 0, 0, 0 ], 43 [ 0, 0, 0, 0 ] 44 ], 45 [ // 2.L 46 [ 0, 1, 0, 0 ], 47 [ 0, 1, 0, 0 ], 48 [ 0, 1, 1, 0 ], 49 [ 0, 0, 0, 0 ] 50 ], 51 [ // 3.J 52 [ 0, 0, 1, 0 ], 53 [ 0, 0, 1, 0 ], 54 [ 0, 1, 1, 0 ], 55 [ 0, 0, 0, 0 ] 56 ], 57 [ // 4.T 58 [ 0, 1, 0, 0 ], 59 [ 0, 1, 1, 0 ], 60 [ 0, 1, 0, 0 ], 61 [ 0, 0, 0, 0 ] 62 ], 63 [ // 5.O 64 [ 0, 0, 0, 0 ], 65 [ 0, 1, 1, 0 ], 66 [ 0, 1, 1, 0 ], 67 [ 0, 0, 0, 0 ] 68 ], 69 [ // 6.Z 70 [ 0, 0, 0, 0 ], 71 [ 1, 1, 0, 0 ], 72 [ 0, 1, 1, 0 ], 73 [ 0, 0, 0, 0 ] 74 ], 75 [ // 7.S 76 [ 0, 0, 0, 0 ], 77 [ 0, 1, 1, 0 ], 78 [ 1, 1, 0, 0 ], 79 [ 0, 0, 0, 0 ] 80 ] 81]; 82 83//初期位置 84const START_X = FIELD_COL/2 - TETRO_SIZE/2; 85const START_Y = 0; 86 87//テトロミノ本体 88let tetro; 89//テトロミノの形 90let tetro_t; 91 92//テトロミノの座標 93let tetro_x = START_X; 94let tetro_y = START_Y; 95 96//フィールド本体 97let field = []; 98 99//ゲームオーバーフラグ 100let over = false; 101 102let can = document.getElementById("can"); 103let con = can.getContext("2d"); 104 105can.width = SCREEN_W; 106can.height = SCREEN_H; 107can.style.border = "4px solid #555"; 108 109tetro_t = Math.floor( Math.random()*(TETRO_TYPES.length-1) ); 110tetro = TETRO_TYPES[ tetro_t ]; 111 112init(); 113drawAll(); 114 115setInterval( dropTetro, GAME_SPEED ); 116 117//初期化 118function init() 119{ 120 //フィールドのクリア 121 for(let y=0; y<FIELD_ROW ; y++ ) 122 { 123 field[y] = []; 124 for(let x=0; x<FIELD_COL ; x++ ) 125 { 126 field[y][x] =0; 127 } 128 } 129 /* 130 field[5][8] = 1; 131 field[19][9] = 1; 132 field[19][0] = 1; 133 */ 134} 135 136//ブロック一つを描画する 137function drawBlock(x,y,c) 138{ 139 let px = x * BLOCK_SIZE; 140 let py = y * BLOCK_SIZE; 141 con.fillStyle=TETRO_COLORS[c]; 142 con.fillRect(px,py,BLOCK_SIZE,BLOCK_SIZE); 143 con.strokeStyle="black"; 144 con.strokeRect(px,py,BLOCK_SIZE,BLOCK_SIZE); 145} 146 147//全部描画する 148function drawAll() 149{ 150 con.clearRect(0,0,SCREEN_W,SCREEN_H); 151 152 for(let y=0; y<FIELD_ROW ; y++ ) 153 { 154 for(let x=0; x<FIELD_COL ; x++ ) 155 { 156 if( field[y][x] ) 157 { 158 drawBlock(x,y,field[y][x]); 159 } 160 } 161 } 162 for(let y=0; y<TETRO_SIZE ; y++ ) 163 { 164 for(let x=0; x<TETRO_SIZE ; x++ ) 165 { 166 if( tetro[y][x] ) 167 { 168 drawBlock(tetro_x+x, tetro_y+y,tetro_t); 169 } 170 } 171 } 172 173 if(over) 174 { 175 let s="GAME OVER"; 176 con.font = "40px 'MS ゴシック'"; 177 let w = con.measureText(s).width; 178 let x = SCREEN_W/2 - w/2; 179 let y = SCREEN_H/2 - 20; 180 con.lineWidth = 4; 181 con.strokeText(s,x,y); 182 con.fillStyle="white"; 183 con.fillText(s,x,y); 184 } 185} 186 187// ブロックの衝突判定 188function checkMove( mx,my ,ntetro) 189{ 190 if( ntetro == undefined ) ntetro = tetro; 191 192 for(let y=0; y<TETRO_SIZE ; y++ ) 193 { 194 for(let x=0; x<TETRO_SIZE ; x++ ) 195 { 196 if( ntetro[y][x] ) 197 { 198 let nx = tetro_x + mx + x; 199 let ny = tetro_y + my + y; 200 201 if( ny < 0 || 202 nx < 0 || 203 ny >= FIELD_ROW || 204 nx >= FIELD_COL || 205 field[ny][nx] ) 206 { 207 return false; 208 } 209 } 210 } 211 } 212 213 return true; 214} 215 216// テトロの回転 217function rotate() 218{ 219 let ntetro = []; 220 221 for(let y=0; y<TETRO_SIZE ; y++ ) 222 { 223 ntetro[y]=[]; 224 for(let x=0; x<TETRO_SIZE ; x++ ) 225 { 226 ntetro[y][x] = tetro[TETRO_SIZE-x-1][y]; 227 } 228 } 229 230 return ntetro; 231} 232 233//テトロを固定する 234function fixTetro() 235{ 236 for(let y=0; y<TETRO_SIZE ; y++ ) 237 { 238 for(let x=0; x<TETRO_SIZE ; x++ ) 239 { 240 if( tetro[y][x] ) 241 { 242 field[tetro_y + y][tetro_x + x] = tetro_t; 243 } 244 } 245 } 246} 247 248//ラインが揃ったかチェックして消す 249function checkLine() 250{ 251 let linec=0; 252 for(let y=0; y<FIELD_ROW ; y++ ) 253 { 254 let flag=true; 255 256 for(let x=0; x<FIELD_COL ; x++ ) 257 { 258 if( !field[y][x] ) 259 { 260 flag=false; 261 break; 262 } 263 } 264 265 if(flag) 266 { 267 linec++; 268 269 for(let ny = y; ny>0 ;ny-- ) 270 { 271 for(let nx=0;nx<FIELD_COL ; nx++) 272 { 273 field[ny][nx] = field[ny-1][nx]; 274 } 275 } 276 } 277 } 278} 279 280// ブロックの落ちる処理 281function dropTetro() 282{ 283 if(over)return; 284 285 if( checkMove( 0, 1 ) )tetro_y++; 286 else 287 { 288 fixTetro(); 289 checkLine(); 290 tetro_t = Math.floor( Math.random()*(TETRO_TYPES.length-1) ); 291 tetro = TETRO_TYPES[ tetro_t ]; 292 tetro_x = START_X; 293 tetro_y = START_Y; 294 295 if( !checkMove(0,0) ) 296 { 297 over=true; 298 } 299 } 300 drawAll(); 301} 302 303//キーボードが押された時の処理 304document.onkeydown = function(e) 305{ 306 if(over)return; 307 308 switch( e.keyCode ) 309 { 310 case 37://311 if( checkMove( -1, 0 ) )tetro_x--; 312 break; 313 case 38://314 //if( checkMove( 0,-1 ) )tetro_y--; 315 break; 316 case 39://317 if( checkMove( 1, 0 ) )tetro_x++; 318 break; 319 case 40://320 if( checkMove( 0, 1 ) )tetro_y++; 321 break; 322 case 32:// スペース 323 let ntetro = rotate(); 324 if( checkMove( 0, 0, ntetro) ) tetro = ntetro; 325 break; 326 } 327 328 drawAll(); 329} 330 331</script> 332</body> 333</html>

上記のようにTETRO_TYPESを0番目の空の配列をコメントアウトしてtetro_tのlengthを番号が合うように修正すると
0番目(I型)のブロックが下まで落ちると消えてしまいます。
左右と下の当たり判定は問題なく回転も問題なくできているため、fixTetroの記述が問題だと思うのですが…
配列0番目のからの配列を作らずにする方法となぜ消えてしまうのかおしえてほしいです

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

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

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

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

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

guest

回答1

0

ベストアンサー

配列0番目のからの配列を作らずにする方法

配列添字を 1 から扱いたい時は、「最初の配列要素に 敢えて null を置く」方法があります。

javascript

1[ 2 null 3, "item1" 4 : 5, "item7" 6]

なぜ消えてしまうのか

「0番目の空の配列をコメントアウトし…」と、ご自身でも原因は理解されています。
開発が進んだ段階でマスタデータの仕様は変えたため、実装で使う配列添字が狂ったからです。

投稿2020/01/01 11:59

AkitoshiManabe

総合スコア5432

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

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

tyaan

2020/01/01 12:17

質問の意図としては自分で作っててなんですが なぜ、0番目だとうまくいかないのかを知りたいのです。
AkitoshiManabe

2020/01/01 12:18

それって、デバッグ作業の依頼ですよ
tyaan

2020/01/01 13:03

回答ありがとうございます。 失礼ですが求めている回答が違うため自分なりに少し考えてみます
AkitoshiManabe

2020/01/01 13:05

ループ内の状況を収集する場合、console.table() や debugger; を使うと値の変化を特定しやすいかもしれません。頑張ってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問