21xrx.com
2024-12-27 06:52:26 Friday
登录
文章检索 我的文章 写文章
使用Java编写简单的拼图游戏代码
2023-06-15 20:27:36 深夜i     --     --
Java编程 拼图游戏 图像处理

Java是一种广泛使用的编程语言,可以用于创建各种类型的应用程序,包括游戏。在这篇文章中,我们将介绍如何使用Java编写一个简单的拼图游戏,让玩家在拖动拼图块的过程中重现原始图像。让我们来看一下该游戏的完整代码:

```

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Point;

import java.awt.Rectangle;

import java.awt.Toolkit;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.net.URL;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import javax.imageio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JPanel;

public class PuzzleGame extends JPanel {

  private static final long serialVersionUID = 1L;

  private static final int NUM_OF_COLUMNS = 4;

  private static final int NUM_OF_ROWS = 3;

  private static final int NUM_OF_TILES = NUM_OF_COLUMNS * NUM_OF_ROWS;

  private static final int MARGIN = 5;

  private static final int GRID_WIDTH = PuzzlePiece.WIDTH * NUM_OF_COLUMNS;

  private static final int GRID_HEIGHT = PuzzlePiece.HEIGHT * NUM_OF_ROWS;

  private static final int BOARD_WIDTH = GRID_WIDTH + MARGIN * 2;

  private static final int BOARD_HEIGHT = GRID_HEIGHT + MARGIN * 2;

  private static final int PIECE_WIDTH = 80;

  private static final int PIECE_HEIGHT = 80;

  private static final int IMAGE_WIDTH = PIECE_WIDTH * NUM_OF_COLUMNS;

  private static final int IMAGE_HEIGHT = PIECE_HEIGHT * NUM_OF_ROWS;

  private static BufferedImage source;

  private List pieces;

  private Point puzzlePiece;

  private int width;

  private int height;

  private BufferedImage resized;

  private PuzzlePiece draggedPiece;

  public PuzzleGame() {

    init();

  }

  private void init() {

    pieces = new ArrayList<>();

    puzzlePiece = new Point();

    addMouseListener(new MouseAdapter() {

      @Override

      public void mousePressed(MouseEvent e) {

        if (e.getButton() == MouseEvent.BUTTON1) {

          int x = e.getX();

          int y = e.getY();

          if (x >= MARGIN && x < MARGIN + GRID_WIDTH && y >= MARGIN && y < MARGIN + GRID_HEIGHT) {

            int col = (x - MARGIN) / PuzzlePiece.WIDTH;

            int row = (y - MARGIN) / PuzzlePiece.HEIGHT;

            PuzzlePiece piece = getPiece(col, row);

            if (piece != null) {

              puzzlePiece.x = x - piece.getX();

              puzzlePiece.y = y - piece.getY();

              draggedPiece = piece;

            }

          }

        }

      }

      @Override

      public void mouseReleased(MouseEvent e) {

        if (draggedPiece != null) {

          int x = getGridX(draggedPiece.getX());

          int y = getGridY(draggedPiece.getY());

          PuzzlePiece piece = getPiece(x, y);

          if (piece == null) {

            draggedPiece.setX(getX(x));

            draggedPiece.setY(getY(y));

          } else {

            swapPieces(draggedPiece, piece);

          }

        }

        draggedPiece = null;

        repaint();

      }

    });

    addMouseMotionListener(new MouseAdapter() {

      @Override

      public void mouseDragged(MouseEvent e) {

        if (draggedPiece != null) {

          int x = e.getX() - puzzlePiece.x;

          int y = e.getY() - puzzlePiece.y;

          draggedPiece.setX(x);

          draggedPiece.setY(y);

          repaint();

        }

      }

    });

    setPreferredSize(new Dimension(BOARD_WIDTH, BOARD_HEIGHT));

    try {

      source = getImage("hedgehog.jpg");

      resized = resizeImage(source, IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_ARGB);

      width = resized.getWidth();

      height = resized.getHeight();

      addPieces();

    } catch (IOException ex) {

      ex.printStackTrace();

    }

    setBorder(null);

    setBackground(Color.BLACK);

  }

  private void addPieces() {

    int id = 0;

    BufferedImage image = resized;

    for (int row = 0; row < NUM_OF_ROWS; row++) {

      for (int col = 0; col < NUM_OF_COLUMNS; col++) {

        id++;

        int x = getX(col);

        int y = getY(row);

        BufferedImage pieceImage = image.getSubimage(col * PIECE_WIDTH, row * PIECE_HEIGHT, PIECE_WIDTH, PIECE_HEIGHT);

        PuzzlePiece piece = new PuzzlePiece(pieceImage, new Point(x, y), id);

        pieces.add(piece);

      }

    }

    Collections.shuffle(pieces);

  }

  private int getX(int col) {

    return MARGIN + col * PuzzlePiece.WIDTH;

  }

  private int getY(int row) {

    return MARGIN + row * PuzzlePiece.HEIGHT;

  }

  private int getGridX(int x) {

    return (x - MARGIN) / PuzzlePiece.WIDTH;

  }

  private int getGridY(int y) {

    return (y - MARGIN) / PuzzlePiece.HEIGHT;

  }

  private BufferedImage getImage(String path) throws IOException {

    URL url = getClass().getResource(path);

    BufferedImage image = ImageIO.read(url);

    return image;

  }

  private BufferedImage resizeImage(BufferedImage originalImage, int width, int height, int type) throws IOException {

    BufferedImage resizedImage = new BufferedImage(width, height, type);

    Graphics g = resizedImage.createGraphics();

    g.drawImage(originalImage, 0, 0, width, height, null);

    g.dispose();

    return resizedImage;

  }

  private PuzzlePiece getPiece(int col, int row) {

    for (PuzzlePiece piece : pieces) {

      if (piece.getCol() == col && piece.getRow() == row)

        return piece;

    }

    return null;

  }

  private void swapPieces(PuzzlePiece p1, PuzzlePiece p2) {

    int tempCol = p1.getCol();

    int tempRow = p1.getRow();

    Point tempLoc = p1.getLocation();

    p1.setCol(p2.getCol());

    p1.setRow(p2.getRow());

    p1.setLocation(p2.getLocation());

    p2.setCol(tempCol);

    p2.setRow(tempRow);

    p2.setLocation(tempLoc);

  }

  @Override

  protected void paintComponent(Graphics g) {

    super.paintComponent(g);

    g.drawImage(resized, MARGIN, MARGIN, null);

    for (PuzzlePiece piece : pieces) {

      piece.draw(g, this);

    }

  }

  public static void main(String[] args) {

    JFrame frame = new JFrame();

    PuzzleGame game = new PuzzleGame();

    frame.add(game);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.pack();

    frame.setLocationRelativeTo(null);

    frame.setVisible(true);

    frame.setResizable(false);

  }

}

class PuzzlePiece {

  public static final int WIDTH = 80;

  public static final int HEIGHT = 80;

  private BufferedImage image;

  private Point location;

  private int col;

  private int row;

  public PuzzlePiece(BufferedImage image, Point location, int id) {

    this.image = image;

    this.location = location;

    this.col = id % PuzzleGame.NUM_OF_COLUMNS;

    if (this.col == 0)

      this.col = PuzzleGame.NUM_OF_COLUMNS;

    this.row = (int) Math.ceil((double) id / (double) PuzzleGame.NUM_OF_COLUMNS);

  }

  public void draw(Graphics g, PuzzleGame game) {

    g.drawImage(image, location.x, location.y, null);

    g.setColor(Color.WHITE);

    g.drawRoundRect(location.x, location.y, WIDTH, HEIGHT, 10, 10);

    g.setColor(Color.BLACK);

    g.fillRoundRect(location.x + 3, location.y + 3, WIDTH - 6, HEIGHT - 6, 10, 10);

  }

  public int getX()

    return location.x;

  public void setX(int x)

    location.x = x;

  public int getY()

    return location.y;

  public void setY(int y)

    location.y = y;

  public int getCol()

    return col - 1;

  public void setCol(int col) {

    this.col = col + 1;

  }

  public int getRow()

    return row - 1;

  public void setRow(int row) {

    this.row = row + 1;

  }

  public Point getLocation()

    return location;

  public void setLocation(Point location)

    this.location = location;

  public Rectangle getBounds() {

    return new Rectangle(location.x, location.y, WIDTH, HEIGHT);

  }

}

在这个简单的拼图游戏中,我们将图像分成一系列的碎片,玩家需要将它们重新排列以恢复原始图像。与数字拼图游戏不同,每个碎片都是一个图像的一部分,因此玩家需要依靠图像本身来确定每个碎片的位置。

首先,我们声明了一些静态常量来定义游戏的基本特征,例如拼图的行列数、每个拼图块的宽度和高度等。我们还定义了一个引用到包含原始图像的BufferedImage对象,以及一个List对象,用于存储所有PuzzlePiece对象(每个拼图碎片)。

init()方法初始化游戏,并产生了一个MouseListener和MouseMotionListener,以便玩家可以拖动和释放拼图碎片。init()还定义了最初的碎片位置(location)、id和每一块的图像(image)。位置(location)用于定义拼图碎片的X和Y坐标,而id则是一个整数,代表了每个拼图碎片的位置。

addPieces()方法用于生成所有的PuzzlePiece对象,将原始图像分割成碎片,并随机化它们的位置列表。

getX()和getY()方法根据拼图块的列和行数返回X和Y坐标。

getGridX()和getGridY()方法根据拼图块的坐标返回X和Y轴上的网格索引。

getImage()方法用于读取原始图像文件。

resizeImage()方法根据指定的宽度和高度重塑大小。

getPiece()方法返回指定位置上的拼图碎片。

swapPieces()方法实现了拼图碎片的相互交换。我们在PuzzleGame类中使用了一些基础的图形绘制命令(例如drawImage()、drawRoundRect()和fillRoundRect()),以提供界面元素。最后,我们使用JFrame显示游戏界面。这个简单的Java拼图游戏,可以让你学到一些基本的Java界面编程技巧。

  
  
下一篇: 如何学好Java

评论区

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