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

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

ただいまの
回答率

90.32%

  • Java

    14437questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 4,212

hozumi_45

score 3

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


public class Tetris extends Applet implements KeyListener{ 
    public static final int HEIGHT=23;//縦 
     
    public static final int WIDTH=14;//横 
     
    public static final int SIZE =30;//ブロックの大きさ 

    private int [][]field=new int[WIDTH][HEIGHT]; 
     
    public static final Color[] COLSELECT={Color.pink,Color.black,Color.green,Color.yellow,Color.gray,Color.MAGENTA,Color.orange};//色の選択 

    public static final int BLANK=0; 
    public static final int WALL=1; 
     
    Point Point = new Point(5,0);//初期配置座標 

    Random rnd = new Random(); 
    int select =rnd.nextInt(7); 
    Color nextColor=COLSELECT[select]; 
    /** 
     * 初期化処理 
     */ 
    @Override 
    public void init(){ 
        addKeyListener(this); 
        for(int y=0;y<HEIGHT;y++) { 
            for(int x=0;x<WIDTH; x++) { 
                field[x][y]=BLANK; 
            } 
        } 
        for (int x=0;x<WIDTH;x++) { 
            field[x][HEIGHT-1]=WALL; 
        } 
        for(int y=0;y<HEIGHT;y++) { 
            field[0][y]=WALL; 
            field[WIDTH-1][y]=WALL; 
        } 
    } 
    /** 
     * @param e KeyEventオブジェクト 
     */ 
    @Override 
    public void keyPressed(KeyEvent e){ 
        int key = e.getKeyCode();//キーの情報を取得 
        if (key==KeyEvent.VK_LEFT){// 方向キー左が押されたとき 
            if(field[Point.x-1][Point.y]==BLANK){ 
                Point.x--; 
                repaint(); 
            } 

        }else if (key==KeyEvent.VK_RIGHT){// 方向キー右が押されたとき  
            if(field[Point.x+1][Point.y]==BLANK){ 
                Point.x++ ;
                repaint(); 
            } 
        }else if (key==KeyEvent.VK_DOWN){// 方向キー下が押されたとき  
            if(field[Point.x][Point.y+1]==BLANK){ 
                Point.y++ ;
                repaint(); 
            }else{ 
                field[Point.x][Point.y]=WALL; 
                Block(); 
                Point = new Point(5,0);// ブロック初期座標 
                repaint(); 
            } 
        } 
    } 
    @Override 
    public void keyReleased(KeyEvent e){ 
    } 

    @Override 
    public void keyTyped(KeyEvent e){ 
    } 
    /** 
     *@param g Graphicsオブジェクト 
     */ 
    @Override 
    public void paint(Graphics g){ 
        if(field[Point.x][Point.y]==BLANK){ 
            g.setColor(nextColor); 
            g.fillRect(Point.x*SIZE,Point.y*SIZE,SIZE,SIZE); 
        } 
        // 外壁 
        for(int i = 0;i <WIDTH;i++){ 
            for(int j = 0;j <HEIGHT;j++){ 
                if(field[i][j]!=BLANK){ 
                    g.setColor(COLSELECT[field[i][j]]); 
                 //g.setColor(Color.red); 
                g.fillRect(i*SIZE,j*SIZE,SIZE,SIZE); 
                } 
            } 
        } 
        g.setColor(Color.black); 
        for(int i=0;i<=HEIGHT;i++){ 
            g.drawLine(0,i*SIZE,WIDTH*SIZE,i*SIZE); 
        } 
        for(int j=0;j<=WIDTH;j++){ 
            g.drawLine(j*SIZE,0,j*SIZE,HEIGHT*SIZE); 
        } 
    } 
    public void Block(){ 
        Random rnd = new Random(); 
        int select =rnd.nextInt(7); 
        nextColor=COLSELECT[select]; 
        COLSELECT[field[Point.x][Point.y]]=COLSELECT[select]; 
    } 
     



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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

問題の直接の原因は、以下の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を使って毎回ランダム値が変わるようにした方が良いと思います。


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

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Tetris extends Applet implements KeyListener {

    public static final int HEIGHT = 23;//縦
    public static final int WIDTH = 14;//横
    public static final int SIZE = 30;//ブロックの大きさ

    public static final int BLANK = 0;
    public static final int WALL = 1;

    // ★読取専用Listにする ★0はブランク(WHITE)用
    public static final List<Color> COLSELECT = Arrays.asList(Color.WHITE, Color.BLACK, Color.PINK, Color.GREEN,
            Color.YELLOW, Color.GRAY, Color.MAGENTA, Color.ORANGE);//色の選択

    private int[][] field = new int[WIDTH][HEIGHT];
    private Random rnd = new Random();

    // ★ブロック初期化は initBlock で
    Point Point;
    int select;

    /**
     * 初期化処理
     */
    @Override
    public void init() {
        addKeyListener(this);
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                field[x][y] = BLANK;
            }
        }
        for (int x = 0; x < WIDTH; x++) {
            field[x][HEIGHT - 1] = WALL;
        }
        for (int y = 0; y < HEIGHT; y++) {
            field[0][y] = WALL;
            field[WIDTH - 1][y] = WALL;
        }
        rnd.setSeed(System.currentTimeMillis()); // Seedのセット
        initBlock();
    }

    private void initBlock() {
        Point = new Point(5, 0);//初期配置座標
        select = rnd.nextInt(7) + 1; // ★0はブランク(WHITE)用
    }

    /**
     * @param e KeyEventオブジェクト
     */
    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();//キーの情報を取得
        if (key == KeyEvent.VK_LEFT) {// 方向キー左が押されたとき
            if (field[Point.x - 1][Point.y] == BLANK) {
                Point.x--;
                repaint();
            }

        }
        else if (key == KeyEvent.VK_RIGHT) {// 方向キー右が押されたとき
            if (field[Point.x + 1][Point.y] == BLANK) {
                Point.x++;
                repaint();
            }
        }
        else if (key == KeyEvent.VK_DOWN) {// 方向キー下が押されたとき
            if (field[Point.x][Point.y + 1] == BLANK) {
                Point.y++;
                repaint();
            }
            else {
                field[Point.x][Point.y] = select; // ★WALLでなくselect
                // Block();
                // Point = new Point(5, 0);// ブロック初期座標
                // ★ブロック初期化は initBlock で
                initBlock();
                repaint();
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    /**
     *@param g Graphicsオブジェクト
     */
    @Override
    public void paint(Graphics g) {
        if (field[Point.x][Point.y] == BLANK) {
            g.setColor(COLSELECT.get(select));
            g.fillRect(Point.x * SIZE, Point.y * SIZE, SIZE, SIZE);
        }
        // 外壁
        for (int i = 0; i < WIDTH; i++) {
            for (int j = 0; j < HEIGHT; j++) {
                int v = field[i][j];
                if (v != BLANK) {
                    g.setColor(COLSELECT.get(v));
                    //g.setColor(Color.red);
                    g.fillRect(i * SIZE, j * SIZE, SIZE, SIZE);
                }
            }
        }
        g.setColor(Color.black);
        for (int i = 0; i <= HEIGHT; i++) {
            g.drawLine(0, i * SIZE, WIDTH * SIZE, i * SIZE);
        }
        for (int j = 0; j <= WIDTH; j++) {
            g.drawLine(j * SIZE, 0, j * SIZE, HEIGHT * SIZE);
        }
    }

    // ★ブロック初期化は initBlock で
//    public void Block() {
//        Random rnd = new Random();
//        int select =rnd.nextInt(7);
//        nextColor=COLSELECT.get(select);
//        COLSELECT[field[Point.x][Point.y]]=COLSELECT[select];
//    }

}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2014/12/18 14:20

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

    キャンセル

同じタグがついた質問を見る

  • Java

    14437questions

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

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