Java 移除自制俄罗斯方块游戏中的闪烁

Java 移除自制俄罗斯方块游戏中的闪烁,java,swing,awt,paint,game-engine,Java,Swing,Awt,Paint,Game Engine,我已经做了一个俄罗斯方块游戏,使用了一些来自互联网和一些书籍的帮助,它看起来几乎像我想要的那样工作。唯一的问题是,当我运行它时,当块下降时,屏幕会可怕地闪烁 我是AWT和swing的新手,因此我经常倾向于使用试错法(我知道这不好)来获得我想要的东西。这一次,我很不确定是哪一部分的程序造成的 这是我的密码。对不起,我的代码有点长,我真的不知道问题出在哪里。(但大多数情况下,它将出现在paint()方法或计时器中。至少我是这样认为的。) import java.awt.*; 导入java.awt.e

我已经做了一个俄罗斯方块游戏,使用了一些来自互联网和一些书籍的帮助,它看起来几乎像我想要的那样工作。唯一的问题是,当我运行它时,当块下降时,屏幕会可怕地闪烁

我是AWT和swing的新手,因此我经常倾向于使用试错法(我知道这不好)来获得我想要的东西。这一次,我很不确定是哪一部分的程序造成的

这是我的密码。对不起,我的代码有点长,我真的不知道问题出在哪里。(但大多数情况下,它将出现在paint()方法或计时器中。至少我是这样认为的。)

import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入java.applet.*;
导入java.io.*;
导入sun.audio.*;
公共类MatrixBoard扩展框架实现ActionListener{
内板高度=20;
int boardWidth=10;
智力得分=0;
int curX=0,curY=0;
整数平方宽度;
整数平方高度;
定时器;
int睡眠时间=300;
形状凝块;
形状.Tetromino[]板;
布尔值isFallingFinished=false;
布尔值isStarted=false;
布尔值isPaused=false;
公共静态void main(字符串[]args){
播放音频(“C:\\doak.wav”);
MatrixBoard b=新的MatrixBoard();
}
公共静态无效播放音频(字符串文件名)
{
InputStream in=null;
AudioStream as=null;
试一试{
in=新文件输入流(文件名);
as=新音频流(in);
}
捕获(例外e){
System.out.println(“错误!!!”;
}
AudioPlayer.player.start(as);
}
矩阵板(){
片名(“俄罗斯方块:新游戏”);
设置聚焦(真);
设置大小(200400);
setVisible(真);
挫折背景(颜色:黑色);
定时器=新定时器(400,本);
定时器。设置初始延迟(10);
squareWidth=(getWidth())/boardWidth;
squareHeight=(getHeight())/boardHeight;
凝块=新形状();
板=新形状。Tetromino[板宽][板高];
addKeyListener(新的KeyHandler());
透明板();
timer.start();
showMessageDialog(空,“按Enter开始!!!”;
start();
System.out.println(“MatrixBoard()成功!”);
}
公共空白结算板(){
对于(int i=0;i=板宽| | y<0 | | y>=板高){
System.out.println(“FALSE1”);
返回false;
}
if(board[x][y]!=Shape.Tetromino.NoShape){
System.out.println(“FALSE2”);
返回false;
}
}
凝块=新块;
curX=newX;
curY=newY;
System.out.println(“curX=“+curX+”curY=“+curY”);
System.out.println(“尝试移动成功!”);
返回true;
}
私有无效下拉列表(){
int newY=curY;
睡眠时间=300;
System.out.println(“newY=“+newY”);
while(newYimport java.awt.*;
import java.awt.event.*;    
import javax.swing.*;    
import java.applet.*;
import java.io.*;
import sun.audio.*;

public class MatrixBoard extends Frame implements ActionListener{

    int boardHeight = 20;
    int boardWidth  = 10;
    int score = 0;
    int curX = 0, curY = 0;
    int squareWidth;
    int squareHeight;
    Timer timer;
    int sleepTime = 300;
    Shape curPiece;
    Shape.Tetromino[][] board;
    boolean isFallingFinished = false;
    boolean isStarted = false;
    boolean isPaused = false;

    public static void main(String [] args){
        playAudio("C:\\doak.wav");
        MatrixBoard b = new MatrixBoard();
    }

    public static void playAudio(String filename)
    {
        InputStream in = null;
        AudioStream as = null;
        try{
            in = new FileInputStream(filename);
            as = new AudioStream(in);
        }
        catch(Exception e){
            System.out.println("Error!!!");
        }
        AudioPlayer.player.start(as);
    }

    MatrixBoard(){
        setTitle("TETRIS: NEW GAME");
        setFocusable(true);
        setSize(200, 400);
        setVisible(true);
        setBackground(Color.BLACK);
        timer = new Timer(400, this);
        timer.setInitialDelay(10);
        squareWidth = (getWidth())/ boardWidth;
        squareHeight = (getHeight()) / boardHeight;
        curPiece = new Shape();
        board = new Shape.Tetromino[boardWidth][boardHeight];
        addKeyListener(new KeyHandler());
        clearBoard();
        timer.start();
        JOptionPane.showMessageDialog(null, "Press Enter to Start!!!");
        start();
        System.out.println("MatrixBoard() Success!");
    }

    public void clearBoard(){
        for(int i = 0; i < boardWidth; ++i)
            for(int j = 0; j < boardHeight; ++j)
                board[i][j] = Shape.Tetromino.NoShape;
    }

    public void start()
    {
        if (isPaused)
            return;
        clearBoard();
        timer.start();
        timer = new Timer(400, this);
        timer.setInitialDelay(100);
        isStarted = true;
        isFallingFinished = false;
        score = 0;
        repaint();
        newPiece();
        System.out.println("START SUCCESS!");
    }

    private void newPiece(){
        if(!isStarted) return;
        curPiece.generateShape();
        curX = boardWidth / 2;
        curY = 1;

        if(!tryMove(curPiece, curX, curY)){
            curPiece.selectPiece(Shape.Tetromino.NoShape);
            isStarted = false;
            JOptionPane.showMessageDialog(null, "Game Over! Score : " + score);
            isStarted = false;
            int opt = JOptionPane.showConfirmDialog(null, "Try Again?", "Again?", JOptionPane.YES_NO_OPTION);
            if(opt == JOptionPane.YES_NO_OPTION){
                start();
            }
            dispose();
            System.exit(0);
            //new Tetris();
            return;
        }
        dropDown();
        System.out.println("NEW PIECE SUCCESS!");
    }

    private boolean tryMove(Shape newPiece, int newX, int newY){
        for(int i = 0; i < 4; i++){
            int x = newX + newPiece.coords[i][0]; 
            int y = newY + newPiece.coords[i][1]; 
            if(x < 0 || x >= boardWidth || y < 0 || y >= boardHeight){
                System.out.println("FALSE1");
                return false;
            }
            if(board[x][y] != Shape.Tetromino.NoShape){
                System.out.println("FALSE2");
                return false;
            }
        }
        curPiece = newPiece;
        curX = newX;
        curY = newY;
        System.out.println("curX = " + curX + " curY = " + curY);
        System.out.println("TRY MOVE SUCCESS!");
        return true;
    }

    private void dropDown(){
        int newY = curY;
        sleepTime = 300;
        System.out.println("newY = " + newY);
        while(newY < boardHeight){
            if(!tryMove(curPiece, curX, newY+1)){ break;}
            ++newY;
            repaint();
            try {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        pieceDropped();
        System.out.println("DROPDOWN SUCCESS!");
    }

    private void pieceDropped(){

        for(int i = 0; i < 4; i++){
            int x = curX + curPiece.coords[i][0];
            int y = curY + curPiece.coords[i][1];
            board[x][y] = curPiece.retShape();
            System.out.println("PIECE: at X = " + x + " Y = " + y + "is " + curPiece.retShape().ordinal());
        }
        removeFullLines();
        if(!isFallingFinished) newPiece();
        System.out.println("PIECE DROPPED SUCCESS!");

    }

    public void paint(Graphics g){ 

        Dimension size = getSize();
        int boardTop = (int) size.getHeight() - boardHeight * squareHeight;

        for (int i = 0; i < boardWidth; ++i) {
            for (int j = 0; j < boardHeight; ++j) {
                Shape.Tetromino shape = board[i][j];
                if (shape != Shape.Tetromino.NoShape)
                    drawSquare(g, i * squareWidth,
                               boardTop + j * squareHeight, shape);
            }
        }

        if (curPiece.retShape() != Shape.Tetromino.NoShape) {
           for (int i = 0; i < 4; ++i) {
               int x = curX + curPiece.coords[i][0];
               int y = curY + curPiece.coords[i][1];
               drawSquare(g, x * squareWidth,
                          boardTop + (y - 1) * squareHeight,
                          curPiece.retShape());
           }
       }
   }

    private void drawSquare(Graphics g, int x, int y, Shape.Tetromino shape)
    {
        Color colors[] = { new Color(0, 0, 0), new Color(204, 102, 102), 
            new Color(102, 204, 102), new Color(102, 102, 204), 
            new Color(204, 204, 102), new Color(204, 102, 204), 
            new Color(102, 204, 204), new Color(218, 170, 0)
        };

        Color color = colors[shape.ordinal()];

        g.setColor(color);
        g.fillRect(x + 1, y + 1, squareWidth - 2, squareHeight - 2);

        g.setColor(color.brighter());
        g.drawLine(x, y + squareHeight - 1, x, y);
        g.drawLine(x, y, x + squareWidth - 1, y);

        g.setColor(color.darker());
        g.drawLine(x + 1, y + squareHeight - 1,
                         x + squareWidth - 1, y + squareHeight - 1);
        g.drawLine(x + squareWidth - 1, y + squareHeight - 1,
                         x + squareWidth - 1, y + 1);

    }

    private void removeFullLines(){

        int numLines = 0;

        for(int i = 0; i < boardHeight; i++){
            boolean isLineFull = true;
            for(int j = 0; j < boardWidth; j++){
                System.out.println("i = " + i + " j = " + j);
                if(board[j][i] == Shape.Tetromino.NoShape){
                    System.out.println("Found No Shape here!");
                    isLineFull = false;
                    break;
                }
            }

            System.out.println("IIIIIIIIS LINE : " + isLineFull);

            if(isLineFull){
                numLines++;
                for(int k = i; k > 0; k--){
                    for(int j = 0; j < boardWidth; ++j){
                        board[j][k] = board[j][k-1]; 
                    }
                }
            }
        }

        if(numLines > 0){
            score += numLines;
            repaint();
            newPiece();
        }

    }

    class KeyHandler extends KeyAdapter{
        public void keyPressed(KeyEvent e){
            if(!isStarted || curPiece.retShape() == Shape.Tetromino.NoShape){
                return;
            }
            int keyCode = e.getKeyCode();

            switch(keyCode){
            case KeyEvent.VK_LEFT:
                tryMove(curPiece, curX - 1, curY);
                break;
            case KeyEvent.VK_RIGHT:
                tryMove(curPiece, curX + 1, curY);
                break;
            case KeyEvent.VK_DOWN:
                sleepTime = 10;
                break;
            case KeyEvent.VK_E:
                int opt = JOptionPane.showConfirmDialog(null,"Are you sure?", "Exit", JOptionPane.YES_NO_OPTION);
                if(opt == JOptionPane.YES_OPTION){
                    System.exit(0);
                }
                break;
            case KeyEvent.VK_SPACE:
                tryMove(curPiece.rotateLeft(), curX, curY);
                break;
            default:
                break;
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (isFallingFinished) {
            isFallingFinished = false;
            newPiece();
        } 
    }

}