awt绘图_五子棋
自己PS了需要用到的图片素材,略显粗糙请见谅。这里只是负责下棋操作,没有判断胜负的逻辑,不过当个棋盘其实也能
xxxxxxxxxxpackage 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(); }
}