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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

2回答

3642閲覧

Tetrisの次に来るブロックの表示について

Kokkoo

総合スコア7

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/01/19 05:38

編集2018/01/19 14:41

テトリスの本家には次に出てくるブロックが右上の部分に表示されているのでその機能を追加させたいのですがどのようにすれば良いのか分かりません。実際にテトリスが動くコードは作成してあり、背景枠の大きさを拡大させてこのような機能を追加させたいです。

Java

1import java.awt.Color; 2 3import java.awt.Graphics; 4 5import java.awt.Point; 6 7import java.awt.event.KeyEvent; 8 9import java.awt.event.KeyListener; 10 11import java.util.ArrayList; 12 13import java.util.Collections; 14 15 16 17import javax.swing.JFrame; 18 19import javax.swing.JPanel; 20 21 22 23public class Tetris extends JPanel { 24 25 26 27 private static final long serialVersionUID = -8715353373678321308L; 28 29 30 31 private final Point[][][] Tetraminos = { 32 33 // I-Piece 34 35 { 36 37 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(3, 1) }, 38 39 { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(1, 3) }, 40 41 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(3, 1) }, 42 43 { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(1, 3) } 44 45 }, 46 47 48 49 // J-Piece 50 51 { 52 53 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(2, 0) }, 54 55 { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(2, 2) }, 56 57 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(0, 2) }, 58 59 { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(0, 0) } 60 61 }, 62 63 64 65 // L-Piece 66 67 { 68 69 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(2, 2) }, 70 71 { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(0, 2) }, 72 73 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(0, 0) }, 74 75 { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(2, 0) } 76 77 }, 78 79 80 81 // O-Piece 82 83 { 84 85 { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }, 86 87 { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }, 88 89 { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }, 90 91 { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) } 92 93 }, 94 95 96 97 // S-Piece 98 99 { 100 101 { new Point(1, 0), new Point(2, 0), new Point(0, 1), new Point(1, 1) }, 102 103 { new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 2) }, 104 105 { new Point(1, 0), new Point(2, 0), new Point(0, 1), new Point(1, 1) }, 106 107 { new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 2) } 108 109 }, 110 111 112 113 // T-Piece 114 115 { 116 117 { new Point(1, 0), new Point(0, 1), new Point(1, 1), new Point(2, 1) }, 118 119 { new Point(1, 0), new Point(0, 1), new Point(1, 1), new Point(1, 2) }, 120 121 { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(1, 2) }, 122 123 { new Point(1, 0), new Point(1, 1), new Point(2, 1), new Point(1, 2) } 124 125 }, 126 127 128 129 // Z-Piece 130 131 { 132 133 { new Point(0, 0), new Point(1, 0), new Point(1, 1), new Point(2, 1) }, 134 135 { new Point(1, 0), new Point(0, 1), new Point(1, 1), new Point(0, 2) }, 136 137 { new Point(0, 0), new Point(1, 0), new Point(1, 1), new Point(2, 1) }, 138 139 { new Point(1, 0), new Point(0, 1), new Point(1, 1), new Point(0, 2) } 140 141 } 142 143 }; 144 145 146 147 private final Color[] tetraminoColors = { 148 149 Color.cyan, Color.blue, Color.orange, Color.yellow, Color.green, Color.pink, Color.red 150 151 }; 152 153 154 155 private Point pieceOrigin; 156 157 private int currentPiece; 158 159 private int rotation; 160 161 private ArrayList<Integer> nextPieces = new ArrayList<Integer>(); 162 163 164 165 private long score; 166 167 private Color[][] well; 168 169 170 171 // Creates a border around the well and initializes the dropping piece 172 173 private void init() { 174 175 well = new Color[12][24]; 176 177 for (int i = 0; i < 12; i++) { 178 179 for (int j = 0; j < 23; j++) { 180 181 if (i == 0 || i == 11 || j == 22) { 182 183 well[i][j] = Color.GRAY; 184 185 } else { 186 187 well[i][j] = Color.BLACK; 188 189 } 190 191 } 192 193 } 194 195 newPiece(); 196 197 } 198 199 200 201 // Put a new, random piece into the dropping position 202 203 public void newPiece() { 204 205 pieceOrigin = new Point(5, 2); 206 207 rotation = 0; 208 209 if (nextPieces.isEmpty()) { 210 211 Collections.addAll(nextPieces, 0, 1, 2, 3, 4, 5, 6); 212 213 Collections.shuffle(nextPieces); 214 215 } 216 217 currentPiece = nextPieces.get(0); 218 219 nextPieces.remove(0); 220 221 } 222 223 224 225 // Collision test for the dropping piece 226 227 private boolean collidesAt(int x, int y, int rotation) { 228 229 for (Point p : Tetraminos[currentPiece][rotation]) { 230 231 if (well[p.x + x][p.y + y] != Color.BLACK) { 232 233 return true; 234 235 } 236 237 } 238 239 return false; 240 241 } 242 243 244 245 // Rotate the piece clockwise or counterclockwise 246 247 public void rotate(int i) { 248 249 int newRotation = (rotation + i) % 4; 250 251 if (newRotation < 0) { 252 253 newRotation = 3; 254 255 } 256 257 if (!collidesAt(pieceOrigin.x, pieceOrigin.y, newRotation)) { 258 259 rotation = newRotation; 260 261 } 262 263 repaint(); 264 265 } 266 267 268 269 // Move the piece left or right 270 271 public void move(int i) { 272 273 if (!collidesAt(pieceOrigin.x + i, pieceOrigin.y, rotation)) { 274 275 pieceOrigin.x += i; 276 277 } 278 279 repaint(); 280 281 } 282 283 284 285 // Drops the piece one line or fixes it to the well if it can't drop 286 287 public void dropDown() { 288 289 if (!collidesAt(pieceOrigin.x, pieceOrigin.y + 1, rotation)) { 290 291 pieceOrigin.y += 1; 292 293 } else { 294 295 fixToWell(); 296 297 } 298 299 repaint(); 300 301 } 302 303 304 305 // Make the dropping piece part of the well, so it is available for 306 307 // collision detection. 308 309 public void fixToWell() { 310 311 for (Point p : Tetraminos[currentPiece][rotation]) { 312 313 well[pieceOrigin.x + p.x][pieceOrigin.y + p.y] = tetraminoColors[currentPiece]; 314 315 } 316 317 clearRows(); 318 319 newPiece(); 320 321 } 322 323 324 325 public void deleteRow(int row) { 326 327 for (int j = row-1; j > 0; j--) { 328 329 for (int i = 1; i < 11; i++) { 330 331 well[i][j+1] = well[i][j]; 332 333 } 334 335 } 336 337 } 338 339 340 341 // Clear completed rows from the field and award score according to 342 343 // the number of simultaneously cleared rows. 344 345 public void clearRows() { 346 347 boolean gap; 348 349 int numClears = 0; 350 351 352 353 for (int j = 21; j > 0; j--) { 354 355 gap = false; 356 357 for (int i = 1; i < 11; i++) { 358 359 if (well[i][j] == Color.BLACK) { 360 361 gap = true; 362 363 break; 364 365 } 366 367 } 368 369 if (!gap) { 370 371 deleteRow(j); 372 373 j += 1; 374 375 numClears += 1; 376 377 } 378 379 } 380 381 382 383 switch (numClears) { 384 385 case 1: 386 387 score += 100; 388 389 break; 390 391 case 2: 392 393 score += 300; 394 395 break; 396 397 case 3: 398 399 score += 500; 400 401 break; 402 403 case 4: 404 405 score += 800; 406 407 break; 408 409 } 410 411 } 412 413 414 415 // Draw the falling piece 416 417 private void drawPiece(Graphics g) { 418 419 g.setColor(tetraminoColors[currentPiece]); 420 421 for (Point p : Tetraminos[currentPiece][rotation]) { 422 423 g.fillRect((p.x + pieceOrigin.x) * 26, 424 425 (p.y + pieceOrigin.y) * 26, 426 427 25, 25); 428 429 } 430 431 } 432 433 434 435 @Override 436 437 public void paintComponent(Graphics g) 438 439 { 440 441 // Paint the well 442 443 g.fillRect(0, 0, 26*12, 26*23); 444 445 for (int i = 0; i < 12; i++) { 446 447 for (int j = 0; j < 23; j++) { 448 449 g.setColor(well[i][j]); 450 451 g.fillRect(26*i, 26*j, 25, 25); 452 453 } 454 455 } 456 457 458 459 // Display the score 460 461 g.setColor(Color.WHITE); 462 463 g.drawString("" + score, 19*12, 25); 464 465 466 467 // Draw the currently falling piece 468 469 drawPiece(g); 470 471 } 472 473 474 475 public static void main(String[] args) { 476 477 JFrame f = new JFrame("Tetris"); 478 479 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 480 481 f.setSize(12*26+10, 26*23+25); 482 483 f.setVisible(true); 484 485 486 487 final Tetris game = new Tetris(); 488 489 game.init(); 490 491 f.add(game); 492 493 494 495 // Keyboard controls 496 497 f.addKeyListener(new KeyListener() { 498 499 public void keyTyped(KeyEvent e) { 500 501 } 502 503 504 505 public void keyPressed(KeyEvent e) { 506 507 switch (e.getKeyCode()) { 508 509 case KeyEvent.VK_UP: 510 511 game.rotate(-1); 512 513 break; 514 515 case KeyEvent.VK_DOWN: 516 517 game.rotate(+1); 518 519 break; 520 521 case KeyEvent.VK_LEFT: 522 523 game.move(-1); 524 525 break; 526 527 case KeyEvent.VK_RIGHT: 528 529 game.move(+1); 530 531 break; 532 533 case KeyEvent.VK_SPACE: 534 535 game.dropDown(); 536 537 game.score += 1; 538 539 break; 540 541 } 542 543 } 544 545 546 547 public void keyReleased(KeyEvent e) { 548 549 } 550 551 }); 552 553 554 555 // Make the falling piece drop every second 556 557 new Thread() { 558 559 @Override public void run() { 560 561 while (true) { 562 563 try { 564 565 Thread.sleep(1000); 566 567 game.dropDown(); 568 569 } catch ( InterruptedException e ) {} 570 571 } 572 573 } 574 575 }.start(); 576 577 } 578 579

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

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

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

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

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

guest

回答2

0

数十行のコードを提示して「どう変えたらよいか」という質問は閲覧者に

(A) あなたのコードを中身の説明なしに理解させることを強いる
(B) あなたが「どういう点について躓いているか」の材料がないため、それをコードの内容から推測することを強いる

ということで、閲覧者からみると「なぞ解き」のように見えます。そういうことを避け「何がわからないのか」をもっと直接的に述べる方がよいと思います。

さて、申し訳ないですが(A)を詳細に見ず(B)は方針のみ提示するつもりで

(A)は「自分ならこんなイメージで作るはず」という想定を置き
(B)は「新たなピースを生成する部分をどう処理しているかnewPieceのみ見る」

だけを行ってコメントしてみますと

newPieceでやっていることは
(P1)「ピースのパターンをどれにするかを決定」
(P2)「そのパターンを初期位置へ配置」
という2点を同時に行っていると思います。

方針としてはこの2つの処理を分割すればよいと思います。つまり、

(P1)新たなピースを画面上に配置したら即座に次のパターンを決定する
(P2)あらかじめ決定しておいたパターンを初期位置へ配置すればよい

これに加えて(P1)で次のパターンを決定したタイミングで「次のピースを表示すべき場所」へピースを描画すればよいと思います。

投稿2018/01/19 06:45

編集2018/01/19 06:46
KSwordOfHaste

総合スコア18394

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

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

KSwordOfHaste

2018/01/19 09:34 編集

一点追記します。質問者さんのオリジナルのコードはきちんと字下げされていますがteratailの質問を作る際にコードをそのまま張り付けてもごらんのとおり字下げは消えてしまいます。閲覧者に見やすくコードを提示するためにマークダウン(文章の修飾をするための簡易的な構文の一つ)がありますので最小限学んでおくとよいです。 https://teratail.com/help#about-markdown を参照してみてください。質問文は編集できますので、マークダウンを付けて見え方がどう変わるかやってみることをお奨めします。こういう点にも配慮した質問ができるとよいと思います。
Kokkoo

2018/01/19 13:51

大変細かくご指摘ありがとうございます。その点を踏まえて質問の編集と方針通りのプログラム作成を行ってみようと思います。
guest

0

テトリス久々に楽しくやりました^^;ありがとうございます。
この後の拡張のご相談だと思いますが、Tetrisクラスはこのまま残して、NextBlockView(仮称)といったJPanelサブクラスを別途用意するのが良いと思います。そのためには、現在のコードを少しいじっていろんな部品を配置できるようにします。

コードのmainのところを少し手を入れてみたので、そこだけ抜粋しますね。

java

1 public static void main(String[] args) { 2 JFrame f = new JFrame("Tetris"); 3 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 4 f.setSize(600, 650); 5 f.setLayout(null); 6 f.getContentPane().setBackground(Color.darkGray); 7 f.setVisible(true); 8 final Tetris game = new Tetris(); 9 game.setBounds(30, 20, 12 * 26 + 10, 26 * 23 + 25); 10
  • JFrameのサイズをとりあえず600 x 650に変更した。
  • JFrameのレイアウト機能を無効にした。
  • 背景色はとりあえずdarkGrayにした。
  • Tetris画面はsetBounds(x, y, w, h)を使い、表示位置を決めた。

これで拡張のための土台はできたので、NextBlockView(仮称)を作って、同じようにsetBounds(x, y, w, h)で画面の適切な位置に配置してください。

投稿2018/01/19 12:32

編集2018/01/19 12:35
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Kokkoo

2018/01/19 14:16

回答ありがとうございます。実際に流れはつかめました。あとは次に出るブロックを右上に配置した新たに作成したpanelを作るだけですが、次のブロックを実際にどうやったら表示させることを実現できるのかがいまいち分かりません。
退会済みユーザー

退会済みユーザー

2018/01/19 14:57 編集

それはまだ全体のゲームシステムを考えていないためですから、これから考えていけばよいと思います。現在のコードは起動したらいきなりゲームが始まっていますね。また、終了判定もこれからですね。ゲームが何らかのトリガーで開始され、何ららかの状態で停止するようにすれば、開始前状態で、次のブロックを小窓に表示しておくことができます。現在のコードでは、currentPieceというインデクス値を直接使ってますが、まず、そのインデクスを使って小窓にブロックを描画し、次のサイクルでそのインデクスを使い本画面に描画すればよいです。その時に、新しいインデクス値を生成し、小窓のほうも更新します。本画面のほうは長くインデクスを必要とするので、小窓用と本画面用の2つの変数を用意したほうが良いでしょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問