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

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

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

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

Q&A

解決済

1回答

7744閲覧

java初心者です、テトリスを作っているのですが落ちてきたブロックがつみあがると外壁と同じ色になって困っています。どうしたら外壁と落ちてきたブロックの色を分けて描画できるのでしょうか?ご教授願います。

hozumi_45

総合スコア8

Java

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

0グッド

0クリップ

投稿2014/12/17 15:39

ボールドテキストjava初心者です。
テトリスを作っているんですが、このコードでブロックが外壁まで落ちてきたときに外壁と同じ色になってしまいます。外壁の色を赤、落ちてくるブロックをランダムな色として設定し、ブロックが落ちたときに外壁の色と同化せず落ちてきた色のままつみあげるにはどうしたらいいのでしょうか?
かなり悩んでいます。

lang

1コード 2``` 3import java.applet.Applet; 4import java.awt.Color; 5import java.awt.Graphics; 6import java.awt.Point; 7import java.awt.event.KeyEvent; 8import java.awt.event.KeyListener; 9import java.util.Random; 10 11 12public class Tetris extends Applet implements KeyListener{ 13 public static final int HEIGHT=23;//縦 14 15 public static final int WIDTH=14;//横 16 17 public static final int SIZE =30;//ブロックの大きさ 18 19 private int [][]field=new int[WIDTH][HEIGHT]; 20 21 public static final Color[] COLSELECT={Color.pink,Color.black,Color.green,Color.yellow,Color.gray,Color.MAGENTA,Color.orange};//色の選択 22 23 public static final int BLANK=0; 24 public static final int WALL=1; 25 26 Point Point = new Point(5,0);//初期配置座標 27 28 Random rnd = new Random(); 29 int select =rnd.nextInt(7); 30 Color nextColor=COLSELECT[select]; 31 /** 32 * 初期化処理 33 */ 34 @Override 35 public void init(){ 36 addKeyListener(this); 37 for(int y=0;y<HEIGHT;y++) { 38 for(int x=0;x<WIDTH; x++) { 39 field[x][y]=BLANK; 40 } 41 } 42 for (int x=0;x<WIDTH;x++) { 43 field[x][HEIGHT-1]=WALL; 44 } 45 for(int y=0;y<HEIGHT;y++) { 46 field[0][y]=WALL; 47 field[WIDTH-1][y]=WALL; 48 } 49 } 50 /** 51 * @param e KeyEventオブジェクト 52 */ 53 @Override 54 public void keyPressed(KeyEvent e){ 55 int key = e.getKeyCode();//キーの情報を取得 56 if (key==KeyEvent.VK_LEFT){// 方向キー左が押されたとき 57 if(field[Point.x-1][Point.y]==BLANK){ 58 Point.x--; 59 repaint(); 60 } 61 62 }else if (key==KeyEvent.VK_RIGHT){// 方向キー右が押されたとき 63 if(field[Point.x+1][Point.y]==BLANK){ 64 Point.x++ ; 65 repaint(); 66 } 67 }else if (key==KeyEvent.VK_DOWN){// 方向キー下が押されたとき 68 if(field[Point.x][Point.y+1]==BLANK){ 69 Point.y++ ; 70 repaint(); 71 }else{ 72 field[Point.x][Point.y]=WALL; 73 Block(); 74 Point = new Point(5,0);// ブロック初期座標 75 repaint(); 76 } 77 } 78 } 79 @Override 80 public void keyReleased(KeyEvent e){ 81 } 82 83 @Override 84 public void keyTyped(KeyEvent e){ 85 } 86 /** 87 *@param g Graphicsオブジェクト 88 */ 89 @Override 90 public void paint(Graphics g){ 91 if(field[Point.x][Point.y]==BLANK){ 92 g.setColor(nextColor); 93 g.fillRect(Point.x*SIZE,Point.y*SIZE,SIZE,SIZE); 94 } 95 // 外壁 96 for(int i = 0;i <WIDTH;i++){ 97 for(int j = 0;j <HEIGHT;j++){ 98 if(field[i][j]!=BLANK){ 99 g.setColor(COLSELECT[field[i][j]]); 100 //g.setColor(Color.red); 101 g.fillRect(i*SIZE,j*SIZE,SIZE,SIZE); 102 } 103 } 104 } 105 g.setColor(Color.black); 106 for(int i=0;i<=HEIGHT;i++){ 107 g.drawLine(0,i*SIZE,WIDTH*SIZE,i*SIZE); 108 } 109 for(int j=0;j<=WIDTH;j++){ 110 g.drawLine(j*SIZE,0,j*SIZE,HEIGHT*SIZE); 111 } 112 } 113 public void Block(){ 114 Random rnd = new Random(); 115 int select =rnd.nextInt(7); 116 nextColor=COLSELECT[select]; 117 COLSELECT[field[Point.x][Point.y]]=COLSELECT[select]; 118 } 119 120}

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

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

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

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

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

guest

回答1

0

ベストアンサー

問題の直接の原因は、以下の3点にあります。

  1. BlockメソッドのCOLSELECT配列を書き換えているところがありますが、この配列は書き換えてはいけないはずです。
  2. Blockメソッドのint select =rnd.nextInt(7)は、ローカル変数でなく、フィールドのselectに設定すべきでは?
  3. keyPressedVK_DOWNかつ下のブロックがBLANKでないときの処理は、fieldに設定するのはWALLではなく、selectでは?

たとえば以下のようにすると、これらのミスを防ぐことができます。

  • COLSELECT配列は、Arrays.asListなどを使って、読み取り専用のListにしておくと、誤ってCOLSELECTを変更することができなくなります。
  • nextColorフィールドは冗長なので、無い方が良いでしょう。
  • 直接は関係ありませんが、インスタンスフィールド(field変数でなく)を初期化している箇所は、次のパーツを表示する時にも同じような処理をしていますので、メソッドにまとめてinitから呼ぶようにしたほうが良いと思います。

それと、これはミスではないですが、RandomRandom#setSeedを使って毎回ランダム値が変わるようにした方が良いと思います。

他にもいくつかありますが、直接コードを見てみてください。

lang

1import java.applet.Applet; 2import java.awt.Color; 3import java.awt.Graphics; 4import java.awt.Point; 5import java.awt.event.KeyEvent; 6import java.awt.event.KeyListener; 7import java.util.Arrays; 8import java.util.List; 9import java.util.Random; 10 11public class Tetris extends Applet implements KeyListener { 12 13 public static final int HEIGHT = 23;//縦 14 public static final int WIDTH = 14;//横 15 public static final int SIZE = 30;//ブロックの大きさ 16 17 public static final int BLANK = 0; 18 public static final int WALL = 1; 19 20 // ★読取専用Listにする ★0はブランク(WHITE)用 21 public static final List<Color> COLSELECT = Arrays.asList(Color.WHITE, Color.BLACK, Color.PINK, Color.GREEN, 22 Color.YELLOW, Color.GRAY, Color.MAGENTA, Color.ORANGE);//色の選択 23 24 private int[][] field = new int[WIDTH][HEIGHT]; 25 private Random rnd = new Random(); 26 27 // ★ブロック初期化は initBlock で 28 Point Point; 29 int select; 30 31 /** 32 * 初期化処理 33 */ 34 @Override 35 public void init() { 36 addKeyListener(this); 37 for (int y = 0; y < HEIGHT; y++) { 38 for (int x = 0; x < WIDTH; x++) { 39 field[x][y] = BLANK; 40 } 41 } 42 for (int x = 0; x < WIDTH; x++) { 43 field[x][HEIGHT - 1] = WALL; 44 } 45 for (int y = 0; y < HEIGHT; y++) { 46 field[0][y] = WALL; 47 field[WIDTH - 1][y] = WALL; 48 } 49 rnd.setSeed(System.currentTimeMillis()); // Seedのセット 50 initBlock(); 51 } 52 53 private void initBlock() { 54 Point = new Point(5, 0);//初期配置座標 55 select = rnd.nextInt(7) + 1; // ★0はブランク(WHITE)用 56 } 57 58 /** 59 * @param e KeyEventオブジェクト 60 */ 61 @Override 62 public void keyPressed(KeyEvent e) { 63 int key = e.getKeyCode();//キーの情報を取得 64 if (key == KeyEvent.VK_LEFT) {// 方向キー左が押されたとき 65 if (field[Point.x - 1][Point.y] == BLANK) { 66 Point.x--; 67 repaint(); 68 } 69 70 } 71 else if (key == KeyEvent.VK_RIGHT) {// 方向キー右が押されたとき 72 if (field[Point.x + 1][Point.y] == BLANK) { 73 Point.x++; 74 repaint(); 75 } 76 } 77 else if (key == KeyEvent.VK_DOWN) {// 方向キー下が押されたとき 78 if (field[Point.x][Point.y + 1] == BLANK) { 79 Point.y++; 80 repaint(); 81 } 82 else { 83 field[Point.x][Point.y] = select; // ★WALLでなくselect 84 // Block(); 85 // Point = new Point(5, 0);// ブロック初期座標 86 // ★ブロック初期化は initBlock で 87 initBlock(); 88 repaint(); 89 } 90 } 91 } 92 93 @Override 94 public void keyReleased(KeyEvent e) { 95 } 96 97 @Override 98 public void keyTyped(KeyEvent e) { 99 } 100 101 /** 102 *@param g Graphicsオブジェクト 103 */ 104 @Override 105 public void paint(Graphics g) { 106 if (field[Point.x][Point.y] == BLANK) { 107 g.setColor(COLSELECT.get(select)); 108 g.fillRect(Point.x * SIZE, Point.y * SIZE, SIZE, SIZE); 109 } 110 // 外壁 111 for (int i = 0; i < WIDTH; i++) { 112 for (int j = 0; j < HEIGHT; j++) { 113 int v = field[i][j]; 114 if (v != BLANK) { 115 g.setColor(COLSELECT.get(v)); 116 //g.setColor(Color.red); 117 g.fillRect(i * SIZE, j * SIZE, SIZE, SIZE); 118 } 119 } 120 } 121 g.setColor(Color.black); 122 for (int i = 0; i <= HEIGHT; i++) { 123 g.drawLine(0, i * SIZE, WIDTH * SIZE, i * SIZE); 124 } 125 for (int j = 0; j <= WIDTH; j++) { 126 g.drawLine(j * SIZE, 0, j * SIZE, HEIGHT * SIZE); 127 } 128 } 129 130 // ★ブロック初期化は initBlock で 131// public void Block() { 132// Random rnd = new Random(); 133// int select =rnd.nextInt(7); 134// nextColor=COLSELECT.get(select); 135// COLSELECT[field[Point.x][Point.y]]=COLSELECT[select]; 136// } 137 138}

投稿2014/12/18 01:23

argius

総合スコア9388

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

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

hozumi_45

2014/12/18 05:20

解決できました! 回答者様のおかげでうまく処理を行うことができました。 回答者様のコードと見比べると自分のコードはかなり冗長になっており書き換えてはいけないところまで書き換えてしまい思ったとおりの処理ができていませんでした。コードを書くときは中のコードをすっきりと書けるように勉強していきます!お答えいただき誠にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問