这是程序呈现的效果图
利用AWT的位图处理,其机制是单缓存,所以会造成程序闪烁
但可以利用Swing的双缓存位图处理,其机制是双缓存,不会造成程序闪烁
下面是代码块
逐条进行了分析 和解释
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Gobang {
//定义五子棋的棋盘
JFrame jf = new JFrame("五子棋游戏");
//声明四个变量
BufferedImage table;
BufferedImage white;
BufferedImage black;
BufferedImage selected;
//声明棋盘的高和宽
final int TABLE_WIDTH=535;
final int TABLE_HEIGHT=536;
//声明棋盘横向和纵向分别可以下多少子
final int BORD_SIZE = 15;
//声明每颗棋子占用的比率
final int RATE = TABLE_WIDTH/BORD_SIZE;
//声明偏移量
final int X_OFFSET = 5;
final int Y_OFFSET = 6;
//声明一个二维数组,代表其下棋的坐标
//且如果为白棋则用1代表
//如果为黑棋则用2代表
//如果没有落棋子则用0代表
int[][] board = new int[BORD_SIZE][BORD_SIZE];
//声明红色选择框的坐标
private int selected_X = -1;
private int selected_Y = -1;
//自定义类,定义画布
class ChessBoard extends JPanel{
public void paint(Graphics g){
//绘制棋盘
g.drawImage(table,0,0,null);
//绘制棋子
for (int i = 0; i < BORD_SIZE; i++) {
for (int j = 0; j < BORD_SIZE; j++) {
//绘制白旗
if (board[i][j] == 1){
g.drawImage(white,i*RATE+X_OFFSET,j*RATE+Y_OFFSET,null);
}
//绘制黑棋
if(board[i][j] ==2){
g.drawImage(black,i*RATE+X_OFFSET,j*RATE+Y_OFFSET,null);
}
}
}
//绘制选择框,并且添加偏移量,并且当坐标大于0的时候开始绘制
if (selected_X>0&&selected_Y>0){
g.drawImage(selected,selected_X*RATE+X_OFFSET,selected_Y*RATE+Y_OFFSET,null);
}
}
}
//创建一个画布对象
ChessBoard chessBoard = new ChessBoard();
//声明一个变量,记录当前下棋的颜色
int board_type = 1;
//声明底部用到的按钮
Panel p = new Panel();
Button whiteBn = new Button("白棋");
Button blackBn = new Button("黑棋");
Button deleteBn = new Button("删除");
//封装一个刷新按钮的方法
public void refreshButtonColor(Color whiteBtn,Color blackBtn,Color deleteBtn){
whiteBn.setBackground(whiteBtn);
blackBn.setBackground(blackBtn);
deleteBn.setBackground(deleteBtn);
}
public void init()throws Exception{
//组装试图 编写逻辑
whiteBn.addActionListener(e -> {
//修改当前棋子的颜色
board_type = 1;
//修改被选中框的颜色
refreshButtonColor(Color.GREEN,Color.GRAY,Color.GRAY);
});
blackBn.addActionListener(e -> {
//修改当前棋子的颜色
board_type = 2;
//修改被选中框的颜色
refreshButtonColor(Color.GRAY,Color.GREEN,Color.GRAY);
});
deleteBn.addActionListener(e -> {
//修改当前棋子的颜色
board_type = 0;
//修改被选中框的颜色
refreshButtonColor(Color.GREEN,Color.GRAY,Color.GREEN);
});
p.add(whiteBn);
p.add(blackBn);
p.add(deleteBn);
jf.add(p,BorderLayout.SOUTH);
//初始化
table = ImageIO.read(new File("src/images/board.jpg"));
white = ImageIO.read(new File("src/images/white.gif"));
black = ImageIO.read(new File("src/images/black.gif"));
selected = ImageIO.read(new File("src/images/selected.gif"));
//处理鼠标移动
chessBoard.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {//当鼠标移动时候被调用
selected_X=(e.getX()-X_OFFSET)/RATE;
selected_Y=(e.getY()-Y_OFFSET)/RATE;
chessBoard.repaint();
}
});
//处理鼠标点击
chessBoard.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {//当鼠标点击时候会被调用
int xPos = (e.getX()-X_OFFSET)/RATE;
int yPos = (e.getY()-Y_OFFSET)/RATE;
board[xPos][yPos] = board_type;
chessBoard.repaint();
}
@Override
public void mouseExited(MouseEvent e) {
selected_X = -1;
selected_Y = -1;
chessBoard.repaint();
}
});
//组装棋盘
chessBoard.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));
jf.add(chessBoard);
//设置大小最佳
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) throws Exception{
new Gobang().init();
}
}
只是实现了GUI图形化界面
还并未对游戏进行逻辑判断
后续可用稀疏数组数据架构对游戏进行重构,优化此游戏的判断效率
如果自己想尝试的话 需要项目图片 可以私信我
后续会完善 异常抛出机制 胜利判断逻辑 以及基于数据结构对游戏进行优化
虽然程序不复杂,但是涉及的范围很广,还是很考验对基础知识的掌握
后续会更新,有兴趣的可以自己试一下