21xrx.com
2024-12-23 05:08:53 Monday
登录
文章检索 我的文章 写文章
“好玩Java游戏”:使用Swing实现一个简单的俄罗斯方块
2023-06-14 11:57:17 深夜i     --     --

“好玩Java游戏”:使用Swing实现一个简单的俄罗斯方块

俄罗斯方块一直是一款备受欢迎的游戏,我们可以使用Java编写一个简单的俄罗斯方块游戏。在本文中,我们将使用Swing编写游戏界面,然后使用Java代码实现游戏逻辑。通过这个案例,你将了解如何使用Java Swing构建游戏界面并实现简单的游戏逻辑。

首先,让我们看一下Swing是什么。Swing是Java提供的GUI工具包,可以用来构建各种类型的桌面应用程序。Swing提供了许多组件,包括标签、按钮、文本框、表格等。我们将使用Swing来构建游戏的界面。

接下来,让我们看一下如何使用Swing来构建游戏界面。我们可以使用JFrame类创建游戏窗口,然后使用JPanel类创建游戏区域。最后,我们可以将游戏区域添加到游戏窗口中。代码如下:


import javax.swing.*;

public class Tetris extends JFrame {

  public Tetris() {

    setTitle("Tetris");

    setSize(200, 400);

    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setVisible(true);

    JPanel panel = new JPanel();

    panel.setSize(200, 400);

    add(panel);

  }

  public static void main(String[] args) {

    new Tetris();

  }

}

在这个例子中,我们创建了一个Tetris类,它继承自JFrame。在构造函数中,我们设置了窗口标题,窗口大小,关闭操作和可见性。然后,我们创建了一个JPanel对象,设置了它的大小,并将它添加到Tetris窗口中。

我们需要在游戏区域中绘制俄罗斯方块。为此,我们需要自定义一个JPanel组件,然后在JPanel组件上绘制俄罗斯方块。


import javax.swing.*;

import java.awt.*;

public class GamePanel extends JPanel {

  public GamePanel() {

    setPreferredSize(new Dimension(200, 400));

  }

  @Override

  public void paintComponent(Graphics g) {

    super.paintComponent(g);

    g.setColor(Color.BLACK);

    g.drawRect(10, 10, 180, 360);

    g.drawString("Hello, Java!", 20, 20);

  }

  public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    frame.add(new GamePanel());

    frame.pack();

    frame.setVisible(true);

  }

}

在这个例子中,我们自定义了一个GamePanel类,它继承自JPanel。在构造函数中,我们设置了游戏区域的首选大小。在paintComponent()方法中,我们在游戏区域中绘制了一个方框和一个字符串。

现在,我们可以将这个GamePanel添加到我们之前创建的Tetris窗口中。让我们修改Tetris类的代码。


import javax.swing.*;

public class Tetris extends JFrame {

  public Tetris() {

    setTitle("Tetris");

    setSize(200, 400);

    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setVisible(true);

    GamePanel panel = new GamePanel();

    add(panel);

  }

  public static void main(String[] args) {

    new Tetris();

  }

}

在这个例子中,我们创建了一个GamePanel对象,然后将它添加到Tetris窗口中。运行代码,你将看到一个包含方框和字符串的游戏窗口。

现在,让我们看一下如何实现俄罗斯方块游戏的逻辑。我们需要实现以下功能:

1. 随机生成方块;

2. 控制方块下落;

3. 检查方块是否到达底部;

4. 将方块固定在游戏区域中。

为了实现这些功能,我们需要创建以下类:

1. Block:方块类,用于表示俄罗斯方块;

2. GameManager:游戏管理类,负责生成方块并控制方块的下落;

3. GameBoard:游戏面板类,用于表示游戏区域,并提供方块放置功能。

请记住,这只是一个简单的实现,有很多改进的地方。让我们看一下每个类的代码。


import java.awt.*;

public class Block {

  private int[][] shape;

  private Color color;

  private int row;

  private int col;

  public Block(int[][] shape, Color color)

    this.shape = shape;

    this.color = color;

    this.row = 0;

    this.col = 5;

  

  public int[][] getShape()

    return shape;

  

  public Color getColor()

    return color;

  

  public int getRow()

    return row;

  

  public void setRow(int row)

    this.row = row;

  

  public int getCol()

    return col;

  

  public void setCol(int col)

    this.col = col;

  

  public void rotateCW() {

    int[][] rotatedShape = new int[shape[0].length][shape.length];

    for (int i = 0; i < shape[0].length; i++) {

      for (int j = 0; j < shape.length; j++) {

        rotatedShape[i][j] = shape[shape.length - j - 1][i];

      }

    }

    shape = rotatedShape;

  }

  public void rotateCCW() {

    int[][] rotatedShape = new int[shape[0].length][shape.length];

    for (int i = 0; i < shape[0].length; i++) {

      for (int j = 0; j < shape.length; j++) {

        rotatedShape[i][j] = shape[j][shape[0].length - i - 1];

      }

    }

    shape = rotatedShape;

  }

}

在这个例子中,我们创建了一个Block类,用于表示一个俄罗斯方块。Block类包含方块形状、颜色、所在行列以及旋转方法。在旋转方法中,我们使用矩阵旋转算法来将方块旋转90度。


import java.awt.*;

public class GameManager {

  private GameBoard board;

  private Block currentBlock;

  private Block nextBlock;

  public GameManager(GameBoard board) {

    this.board = board;

    this.currentBlock = generateBlock();

    this.nextBlock = generateBlock();

  }

  public void update() {

    if (board.canMoveDown(currentBlock)) {

      currentBlock.setRow(currentBlock.getRow() + 1);

    } else {

      board.placeBlock(currentBlock);

      currentBlock = nextBlock;

      nextBlock = generateBlock();

    }

  }

  private Block generateBlock() {

    int[][] shape;

    Color color;

    switch ((int) (Math.random() * 7)) {

      case 0:

        shape = new int[][]{0, 1};

        color = Color.RED;

        break;

      case 1:

        shape = new int[][]{ 1, 1};

        color = Color.GREEN;

        break;

      case 2:

        shape = new int[][]{ 0, 0};

        color = Color.BLUE;

        break;

      case 3:

        shape = new int[][]{0, 0};

        color = Color.YELLOW;

        break;

      case 4:

        shape = new int[][]{1, 0};

        color = Color.PINK;

        break;

      case 5:

        shape = new int[][]{ 1, 0};

        color = Color.ORANGE;

        break;

      case 6:

        shape = new int[][]{1};

        color = Color.CYAN;

        break;

      default:

        shape = new int[0][0];

        color = Color.BLACK;

    }

    return new Block(shape, color);

  }

  public Block getCurrentBlock()

    return currentBlock;

  

  public Block getNextBlock()

    return nextBlock;

  

}

在这个例子中,我们创建了一个GameManager类,用于控制游戏的逻辑。GameManager类包含GameBoard对象、当前方块和下一个方块。在update()方法中,我们检查当前方块是否可以向下移动。如果可以,我们将当前方块的行数加1。否则,我们将当前方块放置在游戏区域中,并创建一个新的当前方块和下一个方块。

在generateBlock()方法中,我们随机生成一个方块并返回。在这个例子中,我们生成了7种不同类型的方块,并使用不同的颜色表示它们。


import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

public class GameBoard extends JPanel {

  private GameManager manager;

  private Timer timer;

  public GameBoard() {

    setPreferredSize(new Dimension(200, 400));

    setBackground(Color.WHITE);

    manager = new GameManager(this);

    timer = new Timer(1000, new ActionListener() {

      @Override

      public void actionPerformed(ActionEvent e) {

        update();

      }

    });

    timer.start();

  }

  @Override

  public void paintComponent(Graphics g) {

    super.paintComponent(g);

    Block currentBlock = manager.getCurrentBlock();

    Block nextBlock = manager.getNextBlock();

    for (int i = 0; i < 20; i++) {

      for (int j = 0; j < 10; j++) {

        Block block = getBlockAt(i, j);

        if (block != null) {

          paintBlock(g, block, j * 20, i * 20);

        }

      }

    }

    paintBlock(g, currentBlock, currentBlock.getCol() * 20, currentBlock.getRow() * 20);

    g.setColor(Color.BLACK);

    g.drawString("Next Block", 120, 20);

    paintBlock(g, nextBlock, 120, 30);

  }

  private void paintBlock(Graphics g, Block block, int x, int y) {

    int[][] shape = block.getShape();

    int size = 20;

    g.setColor(block.getColor());

    for (int i = 0; i < shape.length; i++) {

      for (int j = 0; j < shape[0].length; j++) {

        if (shape[i][j] == 1) {

          g.fillRect(x + j * size, y + i * size, size, size);

        }

      }

    }

  }

  private Block getBlockAt(int row, int col) {

    Block[][] blocks = manager.getBlocks();

    if (row < 0 || row >= 20 || col < 0 || col >= 10)

      return null;

    

    return blocks[row][col];

  }

  private void update() {

    manager.update();

    repaint();

  }

  public boolean canMoveLeft(Block block) {

    int[][] shape = block.getShape();

    int row = block.getRow();

    int col = block.getCol();

    Block[][] blocks = manager.getBlocks();

    for (int i = 0; i < shape.length; i++) {

      for (int j = 0; j < shape[0].length; j++) {

        if (shape[i][j] == 1) {

          if (col + j <= 0 || blocks[row + i][col + j - 1] != null)

            return false;

          

        }

      }

    }

    return true;

  }

  public boolean canMoveRight(Block block) {

    int[][] shape = block.getShape();

    int row = block.getRow();

    int col = block.getCol();

    Block[][] blocks = manager.getBlocks();

    for (int i = 0; i < shape.length; i++) {

      for (int j = 0; j < shape[0].length; j++) {

        if (shape[i][j] == 1) {

          if (col + j >= 9 || blocks[row + i][col + j + 1] != null)

            return false;

          

        }

      }

    }

    return true;

  }

  public boolean canMoveDown(Block block) {

    int[][] shape = block.getShape();

    int row = block.getRow();

    int col = block.getCol();

    Block[][] blocks = manager.getBlocks();

    for (int i = 0; i < shape.length; i++) {

      for (int j = 0; j < shape[0].length; j++) {

        if (shape[i][j] == 1) {

          if (row + i >= 19 || blocks[row + i + 1][col + j] != null)

            return false;

          

        }

      }

    }

    return true;

  }

  public void placeBlock(Block block) {

    int[][] shape = block.getShape();

    int row = block.getRow();

    int col = block.getCol();

    Block[][] blocks = manager.getBlocks();

    for (int i = 0; i < shape.length; i++) {

      for (int j = 0; j < shape[0].length; j++) {

        if (shape[i][j] == 1) {

          blocks[row + i][col + j] = block;

        }

      }

    }

  }

  public Block[][] getBlocks() {

    Block[][] blocks = new Block[20][10];

    for (int i = 0; i < 20; i++) {

      for (int j = 0; j < 10; j++) {

        Block block = getBlockAt(i, j);

        if (block != null) {

          blocks[i][j] = block;

        }

      }

    }

    return blocks;

  }

  public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    frame.add(new GameBoard());

    frame.pack();

    frame.setVisible(true);

  }

}

在这个例子中,我们创建了一个GameBoard类,用于表示游戏区域。GameBoard类包含GameManager对象、定时器和绘图方法。在paintComponent()方法中,我们绘制游戏区域、当前方块和下一个方块。在paintBlock()方法中,我们绘制一个方块。在update()方法中,我们调用GameManager的update()方法。在canMoveLeft()、canMoveRight()和canMoveDown()方法中,我们检查方块是否可以向左、向右或向下移动。在placeBlock()方法中,我们将方块放置在游戏区域中。

在GameManager中,我们需要获取GameBoard对象并设置方块的位置,所以我们需要在GameBoard中添加一个getBlocks()方法。

现在,我们可以将GameBoard添加到Tetris窗口中。让我们修改Tetris的代码。


import javax.swing.*;

public class Tetris extends JFrame {

  public Tetris() {

    setTitle("Tetris");

    setSize(240, 440);

    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setVisible(true);

    GameBoard board = new GameBoard();

    add(board);

  }

  public static void main(String[] args) {

    new Tetris();

  }

}

在这个例子中,我们创建了一个GameBoard对象,然后将它添加到Tetris窗口中。运行代码,你将看到一个包含游戏区域和下一个方块的游戏窗口。

好玩Java游戏,代码案例,Swing

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复