java实现俄罗斯方块游戏(swing练习)

修改自GITHUB的代码
在这里插入图片描述
在这里插入图片描述

使用idea
完整也可以在这下载:
https://yadi.sk/d/iKnQi4EtXF4pBw

在这里插入图片描述
Block .java
记录各种形状的方块

package com.company;

public class Block {
    static final boolean[][][] Shape = {
            // I
            {
                    { false, false, false, false },
                    { true, true, true, true },
                    { false, false, false, false },
                    { false, false, false, false }
            },
            // J
            {
                    { true, false, false },
                    { true, true, true },
                    { false, false, false }
            },
            // L
            {
                    { false, false, true },
                    { true, true, true },
                    { false, false, false }
            },
            // O
            {
                    { true, true },
                    { true, true }
            },
            // S
            {
                    { false, true, true },
                    { true, true, false },
                    { false, false, false }
            },
            // T
            {
                    { false, true, false },
                    { true, true, true },
                    { false, false, false }
            },
            // Z
            {
                    { true, true, false },
                    { false, true, true },
                    { false, false, false }
            }
    };
}


Tetris .java 从JPanel继承而来,实现主要功能

package com.company;

import com.sun.corba.se.spi.servicecontext.ServiceContextRegistry;
import sun.misc.Cleaner;

import javax.swing.*;
import java.awt.*;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.sql.Time;
import java.util.concurrent.BlockingDeque;

public class Tetris extends JPanel {
    private static final int BlockSize = 10;//方块大小
    private static final int BlockWidth = 16;//地图宽度
    private static final int BlockHeight = 26;
    private static final int TimeDelay = 1000;//刷新时间
    private static final String[] AuthorInfo = {
        "Author:","TEST"
    };
    private boolean[][] BlockMap = new boolean[BlockHeight][BlockWidth];
    private int Score = 0;
    private boolean IsPause = false;
    static boolean[][][] Shape = Block.Shape;
    private Point NowBlockPos;//记录下落方块位置
    //注意Pos坐标是以左上角为零点,y为纵轴,x为横轴
    private  boolean[][] NowBlockMap,NextBlockMap;
    private int NowBlockState,NextBlockState;
    private Timer timer;

    public Tetris() {
        this.Init();
        timer = new Timer(Tetris.TimeDelay,this.TimerListener);
        timer.start();
        this.addKeyListener(this.KeyAdapter);
    }

    private void getNextBlock() {
        this.NowBlockState = this.NextBlockState;
        this.NowBlockMap = this.NextBlockMap;
        this.NextBlockState = this.CreateNewBlockState();
        this.NextBlockMap = this.getBlockMap(NextBlockState);
        this.NowBlockPos = this.CalNewBlockInitPos();
    }

    /**
     *
     * @param SrcNextBlockMap
     * @param SrcNextBlockPos
     * @return
     */
   private boolean IsTouch(boolean[][] SrcNextBlockMap,Point SrcNextBlockPos) {
       for (int i = 0; i < SrcNextBlockMap.length; i++) {
           for (int j = 0; j < SrcNextBlockMap[i].length; j++) {
               if (SrcNextBlockMap[i][j])  {
                   if (SrcNextBlockPos.y+i>=BlockHeight || SrcNextBlockPos.x+j>=BlockWidth || SrcNextBlockPos.x+j<0) {
                       return true;
                   } else {
                       if (SrcNextBlockPos.y+i<0) continue;
                       else if (this.BlockMap[SrcNextBlockPos.y+i][SrcNextBlockPos.x+j])
                           return true;
                   }
               }
           }
       }
       return false;
   }
    /**
     * 固定方块到地图
     */
   private boolean FixBlock() {
       for (int i = 0; i < NowBlockMap.length; i++) {
           for (int j = 0; j < NowBlockMap[i].length; j++) {
               if (NowBlockMap[i][j]) {
                   //System.out.println(""+i+" "+j+"\n");
                   if (NowBlockPos.y+i < 0) {
                       return false;
                   } else {
                       BlockMap[NowBlockPos.y+i][NowBlockPos.x+j] = true;
                   }
               }
           }
       }
       return true;
   }

   private Point CalNewBlockInitPos() {
       return new Point(BlockWidth/2-NowBlockMap[0].length/2,-NowBlockMap.length);
   }

    /**
     * 初始化地图
     */
    public void Init() {
        for (int i = 0 ; i < BlockMap.length; i++)
            for (int j = 0; j < BlockMap[i].length; j++)
                BlockMap[i][j] = false;
        Score = 0;

        NowBlockState = CreateNewBlockState();
        NowBlockMap = getBlockMap(NowBlockState);
        NextBlockState = CreateNewBlockState();
        NextBlockMap = getBlockMap(NextBlockState);
        NowBlockPos = CalNewBlockInitPos();
        repaint();
    }

    public void SetPause(boolean value) {
        IsPause = value;
        if (IsPause) {
            timer.stop();
        } else {
            timer.restart();
        }
        this.repaint();
    }
    boolean GetPause() {
        return this.IsPause;
    }
    private int CreateNewBlockState() {
        int Sum = Shape.length*4;//一共有lenght种方块,每个方块通过旋转有四种状态
        return (int) (Math.random()*1000)%Sum;
    }

    private boolean[][] getBlockMap(int BlockState) {
        return RotateBlock(Shape[BlockState/4],BlockState%4);
    }

    private boolean[][] RotateBlock(boolean[][] shape,int time) {
        time = (time%4+4)%4;
        if (time == 0) {
            return shape;
        }
        int height = shape[0].length;
        int width = shape.length;
        boolean[][] NextShape = new boolean[height][width];
        for (int i = 0; i < height; i++)
          for (int j = 0; j < width; j++)
              NextShape[i][j] = shape[width-1-j][i];
        return RotateBlock(NextShape,time-1);
    }

    /**
     * 图形部分
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        //边界
        for (int i = 0; i < BlockHeight+1; i++) {
            g.drawRect(0,i*BlockSize,BlockSize,BlockSize);
            g.drawRect((BlockWidth+1)*BlockSize,i*BlockSize,BlockSize,BlockSize);
        }
        for (int i = 0; i < BlockWidth; i++) {
            g.drawRect((i + 1) * BlockSize, BlockHeight * BlockSize, BlockSize, BlockSize);
        }
        //fangkuan
        for (int i = 0; i < NowBlockMap.length; i++) {
            for (int j = 0; j < NowBlockMap[i].length; j++) {
                if (NowBlockMap[i][j]) {
                    g.fillRect((1+NowBlockPos.x+j)*BlockSize,(NowBlockPos.y+i)*BlockSize,BlockSize,BlockSize);
                    System.out.println(""+i+" "+j+"\n");
                }
            }
        }
        for (int i = 0; i < BlockHeight; i++)
            for (int j = 0; j < BlockWidth; j++)
                if (BlockMap[i][j])
                    g.fillRect((1+j)*BlockSize,i*BlockSize,BlockSize,BlockSize);
        for (int i = 0; i < NextBlockMap.length; i++) {
            for (int j = 0; j < NextBlockMap[i].length; j++) {
                if (NextBlockMap[i][j])
                    //g.fillRect((NextBlockPos.x+j)*BlockSize,(NowBlockPos.y+i)*BlockSize,BlockSize,BlockSize);
                    g.fillRect(190+j*Tetris.BlockSize, 30+i*BlockSize, BlockSize, BlockSize);
            }
        }
        g.drawString("Score"+Score,190,10);
        for (int i = 0; i < AuthorInfo.length; i++) {
            g.drawString(AuthorInfo[i],190,100+i*20);
        }
        if (IsPause) {
            g.setColor(Color.WHITE);
            g.fillRect(70,100,50,20);
            g.setColor(Color.BLACK);
            g.drawString("PAUSE",75,113);
        }
    }

    /**
     * @return
     */
    private int ClearLines() {
        int lines = 0;
        for (int i = 0; i < BlockMap.length; i++) {
            boolean IsLine = true;
            for (int j = 0; j < BlockMap[i].length; j++) {
                if (!BlockMap[i][j]) {
                    IsLine = false;
                    break;
                }
            }
            if (IsLine) {
                for (int k = i; k > 0; k--) {
                    BlockMap[k] = BlockMap[k-1];
                }
                BlockMap[0] = new boolean[BlockWidth];
                lines++;
            }
        }
     return lines;
   }

    //
    ActionListener TimerListener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (IsTouch(NowBlockMap,new Point(NowBlockPos.x,NowBlockPos.y+1))) {
                if (FixBlock()) {
                    Score += ClearLines();
                    getNextBlock();
                } else {
                    JOptionPane.showMessageDialog(Tetris.this.getParent(),"GAME OVER");
                    Init();
                }
            } else {
                NowBlockPos.y++;
            }
            repaint();
        }
    };
/*
按键操作
**/
    void UpAction() {
        boolean [][] DesBlockMap = RotateBlock(NowBlockMap,1);
        if (!IsTouch(DesBlockMap,NowBlockPos)) {
            NowBlockMap = DesBlockMap;
        }
        repaint();
    }
    void LeftAction() {
        Point DesPoint;
        DesPoint = new Point(NowBlockPos.x-1,NowBlockPos.y);
        if (!IsTouch(NowBlockMap,DesPoint)) {
            NowBlockPos = DesPoint;
        }
        repaint();
    }
    void RightAction() {
        Point DesPoint;
        DesPoint = new Point(NowBlockPos.x+1,NowBlockPos.y);
        if (!IsTouch(NowBlockMap,DesPoint)) {
            NowBlockPos = DesPoint;
        }
        repaint();
    }
    java.awt.event.KeyAdapter KeyAdapter = new java.awt.event.KeyAdapter() {
        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println("GREGEGERG");

            if (IsPause) {
                return;
            }
            switch (e.getKeyCode()) {
                case KeyEvent.VK_DOWN:
                    Point DesPoint;
                    DesPoint = new Point(NowBlockPos.x,NowBlockPos.y+1);
                    while (!IsTouch(NowBlockMap,DesPoint)) {
                        NowBlockPos = DesPoint;
                        DesPoint = new Point(NowBlockPos.x,NowBlockPos.y+1);
                    }
                    repaint();
                    break;
                case KeyEvent.VK_UP:
                    UpAction();
                    break;
                case KeyEvent.VK_LEFT:
                    LeftAction();
                    break;
                case KeyEvent.VK_RIGHT:
                    RightAction();
                    break;
            }
        }
    };
}



Main.java 主界面
updata:解决按键失效问题

package com.company;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.*;

class TetrisApp {
    JFrame frame;
    Tetris tetris;
    JMenuBar menuBar;
    JMenu gameMenu,helpMenu;
    JMenuItem newGameItem,pauseItem,continueItem,exitItem;
    JButton pauseButton,newGameButton;
    TetrisApp() {
        frame = new JFrame("Tetris Game");
        menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        tetris = new Tetris();
        tetris.setFocusable(true);
        frame.add(tetris,BorderLayout.CENTER);
        gameMenu = new JMenu("GAME");
        newGameItem = new JMenuItem("新游戏");
        pauseItem = new JMenuItem("暂停");
        continueItem = new JMenuItem("继续");
        exitItem = new JMenuItem("退出");
        newGameItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tetris.Init();
            }
        });
        pauseItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tetris.SetPause(true);
            }
        });
        continueItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tetris.SetPause(false);
            }
        });
        exitItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        gameMenu.add(newGameItem);
        gameMenu.add(pauseItem);
        gameMenu.add(continueItem);
        gameMenu.add(exitItem);
        menuBar.add(gameMenu);
       // menuBar.add(pauseItem);
        helpMenu = new JMenu("帮助");
        JMenuItem helpItem = new JMenuItem("HELP");
        helpItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(frame,"上:旋转 \n左右键:移动位置 \n下:加速","游戏帮助", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        helpMenu.add(helpItem);
        menuBar.add(helpMenu);

        JPanel panel = new JPanel();
        newGameButton = new JButton("新游戏");
        newGameButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tetris.Init();
                tetris.requestFocus();
            }
        });
        pauseButton = new JButton("暂停");
        pauseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                boolean isPause = tetris.GetPause();
                if (isPause) {
                  //  System.out.println("开开开开");
                    pauseButton.setText("暂停");
                    tetris.SetPause(false);
                } else {
                  //  System.out.println("停停停停停");
                    pauseButton.setText("开始");
                    tetris.SetPause(true);
                }
                tetris.requestFocus();
            }
        });
        JButton upButton,rightButton,leftButton;
        upButton = new JButton("旋转");
        leftButton = new JButton("<-");
        rightButton = new JButton("->");
        upButton.addActionListener(e -> {tetris.UpAction();tetris.requestFocus();});
        leftButton.addActionListener(e -> {tetris.LeftAction();tetris.requestFocus();});
        rightButton.addActionListener(e -> {tetris.RightAction();tetris.requestFocus();});
        panel.add(upButton);
        panel.add(leftButton);
        panel.add(rightButton);
        panel.add(newGameButton);
        panel.add(pauseButton);
        frame.add(panel,BorderLayout.SOUTH);
        frame.setSize(320,370);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

public class Main {
    public static void main(String[] args) {
        new TetrisApp();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33831360/article/details/103283304