用java写的俄罗斯方块小程序

这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢。

发在这里跟大家交流学习一下。

如需要完整工程文件、说明文档以及可运行jar文件,下载地址:点击打开链接


RussianBlocksGame.java

package RussiaBlocksGame;


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;


/**
 * 游戏主类,继承自JFrame类,负责游戏的全局控制。 内含: 1.一个GameCanvas画布类的实例对象,
 * 2.一个保存当前活动块(RussiaBlock)实例的对象; 3.一个保存当前控制面板(ControlPanel)实例的对象;
 */
public class RussiaBlocksGame extends JFrame {


private static final long serialVersionUID = -7332245439279674749L;
/**
     * 每填满一行计多少分
     */
    public final static int PER_LINE_SCORE = 100;
    /**
     * 积多少分以后能升级
     */
    public final static int PER_LEVEL_SCORE = PER_LINE_SCORE * 20;
    /**
     * 最大级数是10级
     */
    public final static int MAX_LEVEL = 10;
    /**
     * 默认级数是2
     */
    public final static int DEFAULT_LEVEL = 2;
    private GameCanvas canvas;
    private ErsBlock block;
    private boolean playing = false;
    private ControlPanel ctrlPanel;
    //初始化菜单栏
    private JMenuBar bar = new JMenuBar();
    private JMenu mGame = new JMenu(" 游戏"),
            mControl = new JMenu(" 控制"),
            mInfo = new JMenu("帮助");
    private JMenuItem miNewGame = new JMenuItem("新游戏"),
            miSetBlockColor = new JMenuItem("设置方块颜色..."),
            miSetBackColor = new JMenuItem("设置背景颜色..."),
            miTurnHarder = new JMenuItem("升高游戏难度"),
            miTurnEasier = new JMenuItem("降低游戏难度"),
            miExit = new JMenuItem("退出"),
            miPlay = new JMenuItem("开始"),
            miPause = new JMenuItem("暂停"),
            miResume = new JMenuItem("恢复"),
            miStop = new JMenuItem("终止游戏"),
            miRule = new JMenuItem("游戏规则"),
            miAuthor = new JMenuItem("关于本游戏");
    
    
    /**
     * 建立并设置窗口菜单
     */
    private void creatMenu() {
        bar.add(mGame);
        bar.add(mControl);
        bar.add(mInfo);
        mGame.add(miNewGame);
        mGame.addSeparator();//在菜单中加水平分割线
        mGame.add(miSetBlockColor);
        mGame.add(miSetBackColor);
        mGame.addSeparator();//在菜单中加水平分割线
        mGame.add(miTurnHarder);
        mGame.add(miTurnEasier);
        mGame.addSeparator();//在菜单中加水平分割线
        mGame.add(miExit);
        mControl.add(miPlay);
        miPlay.setEnabled(true);
        mControl.add(miPause);
        miPause.setEnabled(false);
        mControl.add(miResume);
        miResume.setEnabled(false);
        mControl.add(miStop);
        miStop.setEnabled(false);
        mInfo.add(miRule);
        mInfo.add(miAuthor);
        setJMenuBar(bar);


        miNewGame.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                stopGame();
                reset();
                setLevel(DEFAULT_LEVEL);
            }
        });
        
        //设置方块颜色
        miSetBlockColor.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Color newFrontColor =
                        JColorChooser.showDialog(RussiaBlocksGame.this, "设置方块颜色", canvas.getBlockColor());
                if (newFrontColor != null) {
                    canvas.setBlockColor(newFrontColor);
                }
            }
        });
        
        //设置背景颜色
        miSetBackColor.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Color newBackColor =
                        JColorChooser.showDialog(RussiaBlocksGame.this, "设置背景颜色", canvas.getBackgroundColor());
                if (newBackColor != null) {
                    canvas.setBackgroundColor(newBackColor);
                }
            }
        });
        
        //定义菜单栏"关于"的功能,弹出确认框。
        miAuthor.addActionListener(new ActionListener() {                        
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "软件工程(4)班\n3115005372\n杨宇杰\n©一切解释权归杨宇杰所有", "关于俄罗斯方块 - 2016", 1);
            }
        });
        
        //游戏规则说明
        miRule.addActionListener(new ActionListener() {                        
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "由小方块组成的不同形状的板块陆续从屏幕上方落下来,\n玩家通过调整板块的位置和方向,使它们在屏幕底部拼\n出完整的一条或几条。这些完整的横条会随即消失,给新\n落下来的板块腾出空间,与此同时,玩家得到分数奖励。\n没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,\n玩家便告输,游戏结束。", "游戏规则", 1);
            }
        });
        
        //增加难度
        miTurnHarder.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int curLevel = getLevel();
                if (!playing && curLevel < MAX_LEVEL) {
                    setLevel(curLevel + 1);
                }
            }
        });
        
        //减少难度
        miTurnEasier.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int curLevel = getLevel();
                if (!playing && curLevel > 1) {
                    setLevel(curLevel - 1);
                }
            }
        });
        
        //退出按钮动作响应
        miExit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });


    }
    
    /**
     * 主游戏类的构造方法
     *
     * @param title String ,窗口标题
     */
    public RussiaBlocksGame(String title) {
        super(title);                                          //设置标题
        setSize(500, 600);                                     //设置窗口大小                  
        setLocationRelativeTo(null);                             //设置窗口居中


        creatMenu();
        Container container = getContentPane();  //创建菜单栏
        container.setLayout(new BorderLayout(6, 0));              //设置窗口的布局管理器
        canvas = new GameCanvas(20, 15);                          //新建游戏画布
        ctrlPanel = new ControlPanel(this);                        //新建控制面板
        container.add(canvas, BorderLayout.CENTER);                //左边加上画布
        container.add(ctrlPanel, BorderLayout.EAST);               //右边加上控制面板


        //注册窗口事件。当点击关闭按钮时,结束游戏,系统退出。
        addWindowListener(new WindowAdapter() {                    
            @Override
            public void windowClosing(WindowEvent we) {
                stopGame();
                System.exit(0);
            }
        });
        
        //根据窗口大小,自动调节方格的尺寸
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent ce) {
                canvas.adjust();
            }
        });


        setVisible(true);
        canvas.adjust();
    }


    /**
     * 让游戏复位
     */
    public void reset() {                            //画布复位,控制面板复位
        ctrlPanel.setPlayButtonEnable(true);
        ctrlPanel.setPauseButtonEnable(false);
        ctrlPanel.setPauseButtonLabel(true);
        ctrlPanel.setStopButtonEnable(false);
        ctrlPanel.setTurnLevelDownButtonEnable(true);
        ctrlPanel.setTurnLevelUpButtonEnable(true);
        miPlay.setEnabled(true);
        miPause.setEnabled(false);
        miResume.setEnabled(false);
        miStop.setEnabled(false);
        ctrlPanel.reset();
        canvas.reset();
    }


    /**
     * 判断游戏是否还在进行
     *
     * @return boolean,true -还在运行,false-已经停止
     */
    public boolean isPlaying() {
        return playing;
    }


    /**
     * 得到当前活动的块
     *
     * @return ErsBlock,当前活动块的引用
     */
    public ErsBlock getCurBlock() {
        return block;
    }


    /**
     * 得到当前画布
     *
     * @return GameCanvas,当前画布的引用
     */
    public GameCanvas getCanvas() {
        return canvas;
   
  • 11
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
好的,我可以为您提供一个简单的 Java 俄罗斯方块小程序的示例代码。这个程序基于 Java Swing 库,使用了 JFrame、JPanel、JLabel、JButton 等组件,实现了一个简单的俄罗斯方块游戏。 以下是示例代码,您可以将其保存为 Tetris.java 并运行: ```java import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Random; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Tetris extends JPanel implements ActionListener { private static final long serialVersionUID = 1L; private static final int WIDTH = 300; private static final int HEIGHT = 600; private static final int BLOCK_SIZE = 30; private static final int BOARD_WIDTH = 10; private static final int BOARD_HEIGHT = 20; private static final int DELAY = 500; private static final Color[] COLORS = { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.PINK, Color.ORANGE, Color.CYAN }; private JFrame frame; private JPanel board; private JLabel scoreLabel; private JButton startButton; private int[][] blocks; private Point[] currentBlock; private Color currentColor; private int currentX; private int currentY; private boolean isRunning; private int score; public Tetris() { frame = new JFrame("Tetris"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); board = new JPanel() { private static final long serialVersionUID = 1L; @Override public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < BOARD_HEIGHT; i++) { for (int j = 0; j < BOARD_WIDTH; j++) { if (blocks[i][j] != 0) { g.setColor(COLORS[blocks[i][j] - 1]); g.fillRect(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } } } for (Point p : currentBlock) { g.setColor(currentColor); g.fillRect((currentX + p.x) * BLOCK_SIZE, (currentY + p.y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } } }; board.setPreferredSize(new Dimension(BLOCK_SIZE * BOARD_WIDTH, BLOCK_SIZE * BOARD_HEIGHT)); frame.add(board, BorderLayout.CENTER); JPanel bottomPanel = new JPanel(); scoreLabel = new JLabel("Score: 0"); bottomPanel.add(scoreLabel); startButton = new JButton("Start"); startButton.addActionListener(this); bottomPanel.add(startButton); frame.add(bottomPanel, BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } private void init() { blocks = new int[BOARD_HEIGHT][BOARD_WIDTH]; currentBlock = new Point[4]; generateBlock(); currentX = BOARD_WIDTH / 2 - 1; currentY = 0; isRunning = true; score = 0; scoreLabel.setText("Score: " + score); } private void generateBlock() { Random rand = new Random(); int type = rand.nextInt(7) + 1; switch (type) { case 1: // I currentBlock[0] = new Point(0, 0); currentBlock[1] = new Point(0, 1); currentBlock[2] = new Point(0, 2); currentBlock[3] = new Point(0, 3); break; case 2: // J currentBlock[0] = new Point(0, 0); currentBlock[1] = new Point(1, 0); currentBlock[2] = new Point(1, 1); currentBlock[3] = new Point(1, 2); break; case 3: // L currentBlock[0] = new Point(0, 2); currentBlock[1] = new Point(1, 0); currentBlock[2] = new Point(1, 1); currentBlock[3] = new Point(1, 2); break; case 4: // O currentBlock[0] = new Point(0, 0); currentBlock[1] = new Point(0, 1); currentBlock[2] = new Point(1, 0); currentBlock[3] = new Point(1, 1); break; case 5: // S currentBlock[0] = new Point(0, 1); currentBlock[1] = new Point(0, 2); currentBlock[2] = new Point(1, 0); currentBlock[3] = new Point(1, 1); break; case 6: // T currentBlock[0] = new Point(0, 1); currentBlock[1] = new Point(1, 0); currentBlock[2] = new Point(1, 1); currentBlock[3] = new Point(1, 2); break; case 7: // Z currentBlock[0] = new Point(0, 0); currentBlock[1] = new Point(0, 1); currentBlock[2] = new Point(1, 1); currentBlock[3] = new Point(1, 2); break; } currentColor = COLORS[rand.nextInt(COLORS.length)]; } private void moveDown() { if (canMove(currentX, currentY + 1, currentBlock)) { currentY++; } else { addBlock(currentX, currentY, currentBlock, currentColor); checkRows(); generateBlock(); currentX = BOARD_WIDTH / 2 - 1; currentY = 0; if (!canMove(currentX, currentY, currentBlock)) { isRunning = false; } } } private void moveLeft() { if (canMove(currentX - 1, currentY, currentBlock)) { currentX--; } } private void moveRight() { if (canMove(currentX + 1, currentY, currentBlock)) { currentX++; } } private void rotate() { Point[] newBlock = new Point[4]; for (int i = 0; i < 4; i++) { newBlock[i] = new Point(currentBlock[i].y, -currentBlock[i].x); } if (canMove(currentX, currentY, newBlock)) { currentBlock = newBlock; } } private boolean canMove(int x, int y, Point[] block) { for (Point p : block) { int newX = x + p.x; int newY = y + p.y; if (newX < 0 || newX >= BOARD_WIDTH || newY < 0 || newY >= BOARD_HEIGHT || blocks[newY][newX] != 0) { return false; } } return true; } private void addBlock(int x, int y, Point[] block, Color color) { for (Point p : block) { blocks[y + p.y][x + p.x] = COLORS.length + 1; } for (Point p : block) { blocks[y + p.y][x + p.x] = COLORS.length + 1 - colorIndex(color); } } private int colorIndex(Color color) { for (int i = 0; i < COLORS.length; i++) { if (color.equals(COLORS[i])) { return i; } } return -1; } private void checkRows() { ArrayList<Integer> fullRows = new ArrayList<Integer>(); for (int i = 0; i < BOARD_HEIGHT; i++) { boolean full = true; for (int j = 0; j < BOARD_WIDTH; j++) { if (blocks[i][j] == 0) { full = false; break; } } if (full) { fullRows.add(i); } } if (fullRows.size() > 0) { for (int i : fullRows) { for (int j = i; j > 0; j--) { for (int k = 0; k < BOARD_WIDTH; k++) { blocks[j][k] = blocks[j - 1][k]; } } } score += fullRows.size() * 100; scoreLabel.setText("Score: " + score); } } private void gameLoop() { while (isRunning) { moveDown(); board.repaint(); try { Thread.sleep(DELAY); } catch (InterruptedException e) { e.printStackTrace(); } } } public void actionPerformed(ActionEvent e) { if (e.getSource() == startButton) { init(); gameLoop(); } } public static void main(String[] args) { new Tetris(); } } ``` 该程序使用一个二维数组来表示游戏区域,每个格子可以被染上不同的颜色。在游戏中,程序会随机生成一个俄罗斯方块,玩家需要使用键盘控制方块的移动和旋转,让方块落到最底部或者尽可能占据更多的空间。当一行满了格子时,该行会被消除,并且玩家可以获得一定的分数。当方块无法继续下落时,游戏结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值