awt绘图_五子棋
自己PS了需要用到的图片素材,略显粗糙请见谅。这里只是负责下棋操作,没有判断胜负的逻辑,不过当个棋盘其实也能
xxxxxxxxxx
package ch29;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
public class a_10_0awt_绘图_五子棋 {
private Frame f = new Frame("五子棋游戏");
//声明四个BufferedImage对象,分别记录四张照片
BufferedImage table;
BufferedImage black;
BufferedImage white;
BufferedImage selected;
//声明棋盘的宽和高。看自己的素材即棋盘背景图片的大小而定
final int TABLE_WIDTH = 534;
final int TABLE_HEIGHT = 534;
//声明棋盘横向和纵向分别可以下多少子,它们的值都为15。看自己的素材即棋盘背景图片的横列和竖列而定
final int BOARD_SIZE = 15;
//声明每个棋子占用棋盘的比率
final int RATE = TABLE_WIDTH / BOARD_SIZE;
//声明变量,记录棋子对于x方向和y方向的偏移量。因为棋子并没有紧贴棋盘边缘,而是有一个空隙,叫偏移量
final int X_OFFSET = 5;
final int Y_OFFSET = 5;
//声明一个二维数组,记录棋子,0代表没有棋子,1代表白棋,2代表黑棋。作用是方便知道那个点需要绘制棋子,那个点不需要绘制棋子
int[][] board = new int[BOARD_SIZE][BOARD_SIZE];
//声明红色选择框的坐标。该坐标其实就是二维数组board中的索引。这个红色选择框是我们的素材图片哦
int selected_X = -1;
int selected_Y = -1;
//自定义类,继承Canvas。作用是把棋盘绘制在画布上
private class ChessBoard extends Canvas {
public void paint(Graphics g) {
//绘图如下
//绘制棋盘
g.drawImage(table, 0, 0, null);
//绘制红色选择框
if (selected_X > 0 && selected_Y > 0) {//当鼠标在棋盘内部才绘制红色选择框
g.drawImage(selected, selected_X * RATE + X_OFFSET, selected_Y * RATE + Y_OFFSET, null);
}
//绘制棋子
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
//绘制黑棋
if (board[i][j] == 2) {//判断是否是黑棋,当是2的时候就认为是黑棋
g.drawImage(black, i * RATE + X_OFFSET, j * RATE + Y_OFFSET, null);
}
//绘制白棋
if (board[i][j] == 1) {//判断是否是白棋,当是1的时候就认为是白棋
g.drawImage(white, i * RATE + X_OFFSET, j * RATE + Y_OFFSET, null);
}
}
}
}
}
ChessBoard chessBoard = new ChessBoard();//这个是我们的画布对象
//声明变量,记录当前下棋的颜色
int board_type = 2; //默认黑棋
//底部需要用到的按钮组件
Panel p = new Panel();
Button whiteBtn = new Button("白棋");
Button blackBtn = new Button("黑棋");
Button deleteBtn = new Button("删除");
//刷新上面那三个按钮的颜色
public void refreshColor(Color whiteBtnColor, Color blackBtnColor, Color deleteBtnColor) {
whiteBtn.setBackground(whiteBtnColor);//setBackground设置按钮的颜色
blackBtn.setBackground(blackBtnColor);
deleteBtn.setBackground(deleteBtnColor);
}
public void init() throws Exception {
//点击事件,白旗按钮
whiteBtn.addActionListener(e ->
{
//修改当前要下的棋子的标志为1
board_type = 1;
//刷新按钮的颜色。因为按下按钮,按钮会变色
//因为每次都要刷新,所以封装为一个方法
refreshColor(Color.GREEN, Color.GRAY, Color.GRAY);
});
//点击事件,黑色按钮
blackBtn.addActionListener(e ->
{
//修改当前要下的棋子的标志为2
board_type = 2;
//刷新按钮的颜色——因为按下按钮,按钮会变色
//因为每次都要刷新,所以封装为一个方法
refreshColor(Color.GRAY, Color.GREEN, Color.GRAY);
});
//点击事件,删除按钮
deleteBtn.addActionListener(e ->
{
//修改当前要下的棋子的标志为0,因为0代表没有棋子
board_type = 0;
//刷新按钮的颜色——因为按下按钮,按钮会变色
//因为每次都要刷新,所以封装为一个方法
refreshColor(Color.GRAY, Color.GRAY, Color.GREEN);
});
//把上面的三个按钮放到Panel容器里面
p.add(whiteBtn);
p.add(blackBtn);
p.add(deleteBtn);
//把Panel容器放到Frame容器的南部
f.add(p, BorderLayout.SOUTH);
//上面的哪些代码组装好了3个,下面的代码就按钮组装棋盘,如下
//对图片进行初始化
table = ImageIO.read(new File("src\\img\\table.jpg"));
white = ImageIO.read(new File("src\\img\\white.gif"));
black = ImageIO.read(new File("src\\img\\black.gif"));
selected = ImageIO.read(new File("src\\img\\selected.gif"));
//注册鼠标移动事件,作用是让红色选择框随鼠标移动
chessBoard.addMouseMotionListener(new MouseMotionAdapter() {
//当鼠标移动时会调用mouseMoved方法
public void mouseMoved(MouseEvent e) {
//接着将获取的位置转换成棋盘中正确的索引坐标
selected_X = (e.getX() - X_OFFSET) / RATE;//e.getX是当前鼠标移动到的坐标。难点:让红色选择框准确落到棋盘的小方格
selected_Y = (e.getY() - Y_OFFSET) / RATE;
//重绘界面
//chessBoard.repaint();//这行建议注释掉,不然每次连鼠标移动都刷新界面,就会造成闪烁。当然也可以不注释
}
});
//注册鼠标点击事件
chessBoard.addMouseListener(new MouseAdapter() {
//当鼠标点击后,会调用这个方法
public void mouseClicked(MouseEvent e) {
int xPos = (e.getX() - X_OFFSET) / RATE; //e.getX是当前鼠标点击到的坐标
int yPos = (e.getY() - Y_OFFSET) / RATE;
board[xPos][yPos] = board_type;
//重绘界面
chessBoard.repaint();
}
//当我们的鼠标移除界面的时候,取消红色选择框的显示
public void mouseExited(MouseEvent e) {
selected_X = -1;
selected_Y = -1;
//重绘界面
chessBoard.repaint();
}
});
//给Frame设置WindowListener监听器,监听用户点击右上角X的动作,则关闭窗口
f.addWindowListener(new WindowAdapter() {
//采用Java通过的适配器设计模式,我们只需要重写自己需要的方法,例如windowClosing方法,如下
public void windowClosing(WindowEvent e) {
System.exit(0);//原理:退出JVM虚拟机,即退出当前运行的Java程序
}
});
//把chessBoard组件放到Frame里面
chessBoard.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));
f.add(chessBoard);//不写参数默认就会放在中部区域
//设置最佳大小并可以见
f.pack();
f.setVisible(true);
}
public static void main(String[] args) throws Exception {
new a_10_0awt_绘图_五子棋().init();
}
}