第一步:写一个接口(GoBangDataConfig)
对于棋盘来说,棋盘的起始点,棋子以及网格的大小,有几行有几列,这些都是固定的,那么接下来我们在写界面类的时候就可以让类去继承这个接口。
public interface GoBangDataConfig {
//五子棋基本属性
//棋盘
/**
* 棋盘起始点坐标
*/
static final int X = 50;
static final int Y = 50;
/**
* 棋子以及网格大小
*/
static final int SIZE = 50;
/**
* 行列值
*/
static final int C = 10;
static final int R = 10;
}
第二步:画棋盘UI
a、简单写一个界面,继承JFrame,去使用它的一些组件(标题,尺寸大小,关闭进程,可视化)
b、重写JFrame的paint(Graphics g)方法,在其中画出棋盘。
import java.awt.Graphics;
import javax.swing.JFrame;
public class GoBangUI extends JFrame implements GoBangDataConfig {
public static void main(String[] args) {
GoBangUI gui = new GoBangUI();
gui.initGobangUI();
}
public void initGobangUI() {
setTitle("AI Gobang");
setSize(900,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//鼠标下棋监听器
GoBangListeners gl = new GoBangListeners();
addMouseListener(gl);
//获取Graphics g
Graphics g = getGraphics();
//传入监听器中
gl.g = g;
}
//重写paint方法 刷新界面的时候 出来棋盘
//自动调用
public void paint(Graphics g) {
super.paint(g);
for (int i = 0;i<=C;i++) {
g.drawLine(X, Y+i*SIZE, C*SIZE+X, Y+i*SIZE);
g.drawLine(X+i*SIZE, Y, X+i*SIZE, R*SIZE+Y);
}
}
}
ps.如果不在paint里面把棋盘画好的话,那么运行的开始你是看不到棋盘的,再就是如果你窗口最小化再打开的话,棋盘是会不见的,所以就决定了在paint方法里面画出这个棋盘,并且里面还有一部分就是画棋子。
第三步:实现鼠标监听器,当按下鼠标时,画一个棋子,确定其位置,并且实现3D棋子的效果。
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class GoBangListeners implements MouseListener,GoBangDataConfig{
Graphics g;
int flag = 0;
public void mouseClicked(MouseEvent e) {
}
/**
* Invoked when a mouse button has been pressed on a component.
*/
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
//限定下棋的范围
if(x>(SIZE*C+X)||y>(SIZE*R+Y)) {
return;
}
//计算坐标值 行列值
int chessC = (x-X+SIZE/2)/SIZE;//间距一致--int 整数 取出浮点数部分
int chessR = (y-Y+SIZE/2)/SIZE;
//轮流下棋 坐标值
int chessX = chessC*SIZE+X;
int chessY = chessR*SIZE+Y;
if(flag == 0) {
draw3DChess(chessX-SIZE/2, chessY-SIZE/2, SIZE, "黑棋");
flag++;
}else if(flag == 1) {
draw3DChess(chessX-SIZE/2, chessY-SIZE/2, SIZE, "白棋");
flag = 0;
}
/**
* 3D棋子
*/
}
/**
* Invoked when a mouse button has been released on a component.
*/
public void mouseReleased(MouseEvent e) {
}
/**
* Invoked when the mouse enters a component.
*/
public void mouseEntered(MouseEvent e) {
}
/**
* Invoked when the mouse exits a component.
*/
public void mouseExited(MouseEvent e) {
}
我们要实现棋子下在直线与直线的焦点上,而不是随意的任何地方,所以首先我们要计算行列值,就是你点击的坐标最靠近几行几列,我们从棋盘的起始点开始算
我们先来计算列值,就要用到x坐标,起始点的x坐标为50,当我们去点击x坐标为165时它的列值就要是2,点击x坐标为185时它的列值就要是3,只需要加上格子的一半再除以格子的SIZE就好了
int chessC = (x-X+SIZE/2)/SIZE,行值以此类推。
有了行列值,再去计算坐标值。
接下来,我们完成3D棋子的方法:draw3DChess
五子棋的3D只是多个棋子叠加起来,由大而变小
public void draw3DChess(int x,int y,int SIZE,String chessType) {
for(int i = 0;i<SIZE;i++) {
if(chessType.equals("黑棋")) {
Color color = new Color(i*5,i*5,i*5);
g.setColor(color);
}else if(chessType.equals("白棋")) {
Color color = new Color(155+i*2,155+i*2,155+i*2);
g.setColor(color);
}
g.fillOval(x+i/2, y+i/2, SIZE-i, SIZE-i);
}
}
这里用到RGB三原色,三原色的数值范围0-255,黑色:(0,0,0)白色(255,255,255)
红色(255,0,0)绿色(0,255,0)蓝色(0,0,255)
所以要画黑棋,数值就越小,且3色数值要相等,白色也是同理。
好了,后续我们会完成棋子的保存,还有悔棋重绘棋子以及判断输赢,或者更多的扩展功能。