先初始化JFrame定义一下MouseListerner,Runnable
public class test1 extends JFrame implements MouseListener, Runnable { BufferedImage bgImage = null; int x = 0; int y = 0; int[][] allChess = new int[15][15]; boolean isBlack = true; //表示当前游戏是否继续 boolean canPlay = true; //保存显示的提示信息 String message = "黑方先行"; //保存最多拥有的时间 int maxTime = 0; //做倒计时的线程类 Thread t = new Thread(this); //保存黑方与白方的剩余时间 int blackTime = 0; int whiteTime = 0; //保存上方剩余时间的显示信息 String blackMessage = "无限制"; String whiteMessage = "无限制";
绘制棋盘的方法
public test1() { //标题设置为五子棋 this.setTitle("五子棋"); //程序窗口的大小 this.setSize(900, 700); //让窗口大小不可调整(若可以调整会有bug) this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addMouseListener(this); //获取屏幕大小(以便让窗口直接出现在屏幕中心) int width = Toolkit.getDefaultToolkit().getScreenSize().width; int height = Toolkit.getDefaultToolkit().getScreenSize().height; this.setLocation((width - 900) / 2, (height - 700) / 2); //显示程序窗口(必须放到最后) this.setVisible(true); t.start(); t.suspend(); //刷新屏幕 this.repaint(); } public void paint (Graphics g){ //放置图片,并让图片处在合适的位置 g.drawImage(bgImage, 0, 30, this); g.setFont(new Font("隶书", 0, 25)); g.drawString("游戏信息:" + message, 50, 50); g.setFont(new Font("隶书", 0, 25)); g.drawString("黑方时间:" + blackMessage, 50, 660); g.drawString("白方时间:" + whiteMessage, 450, 660); g.setFont(new Font("隶书", Font.BOLD, 25)); g.drawString("开始游戏", 710, 88); g.drawString("游戏设置", 710, 172); g.drawString("认输", 730, 254); //画棋盘,我是15*15的棋盘 for (int i = 0; i < 15; i++) { g.drawLine(31, 57 + 40 * i, 591, 57 + 40 * i); g.drawLine(31 + 40 * i, 57, 31 + 40 * i, 617); } //画棋子,黑棋子是一个实心黑圆,白棋子是实心白圆加一个黑圆圈 for (int i = 0; i < 15; i++) for (int j = 0; j < 15; j++) { if (allChess[i][j] == 1) { int tempX = i * 40 + 31; int tempY = j * 40 + 57; g.fillOval(tempX - 15, tempY - 15, 30, 30); } if (allChess[i][j] == 2) { int tempX = i * 40 + 31; int tempY = j * 40 + 57; g.setColor(Color.WHITE); g.fillOval(tempX - 15, tempY - 15, 30, 30); g.setColor(Color.BLACK); g.drawOval(tempX - 15, tempY - 15, 30, 30); } } }
如果不知道怎么找坐标的话可以在mousePressed方法中添加如下代码,这样鼠标点击一下即可知道当前位置坐标了。
if (canPlay == true) { //获取鼠标点击位置的坐标 x = e.getX(); y = e.getY(); //只有鼠标点击棋盘内时才能画棋子 if (x >= 31 && x <= 591 && y >= 57 && y <= 617) { //棋子只能绘制在交叉点初,所以需要一个算法 //如果(鼠标点击的坐标-初始点坐标)%间隔>1/2间隔,那么里这个鼠标点击的坐标最近的交叉点应当是下一个交叉点 if ((x - 31) % 40 > 20) { x = (x - 31) / 40 + 1; } else { x = (x - 31) / 40; } if ((y - 57) % 40 > 20) { y = (y - 57) / 40 + 1; } else { y = (y - 57) / 40; } //下棋的地方不能有棋子 if (allChess[x][y] == 0) { //第一个是黑棋,下完变白棋 if (isBlack == true) { allChess[x][y] = 1; isBlack = false; message = "轮到白方"; } else { allChess[x][y] = 2; isBlack = true; message = "轮到黑方"; } //判断输赢,看周围相连是否有五个 boolean winFlag = this.checkWin(); if (winFlag == true) { JOptionPane.showMessageDialog(this, "Game Over," + (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜!"); canPlay = false; } } //判断输赢,看周围相连是否有五个 this.repaint(); } }
这样可以成功编写棋盘并交替下棋,还能判断是否某方获胜。
如下为完整代码:
test2.java:
package text; public class test2 { public static void main(String[] args) { test1 ff = new test1(); } }
test1.java:
package text; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JOptionPane; //00点31 57 间隔40 public class test1 extends JFrame implements MouseListener, Runnable { BufferedImage bgImage = null; int x = 0; int y = 0; int[][] allChess = new int[15][15]; boolean isBlack = true; //表示当前游戏是否继续 boolean canPlay = true; //保存显示的提示信息 String message = "黑方先行"; //保存最多拥有的时间 int maxTime = 0; //做倒计时的线程类 Thread t = new Thread(this); //保存黑方与白方的剩余时间 int blackTime = 0; int whiteTime = 0; //保存上方剩余时间的显示信息 String blackMessage = "无限制"; String whiteMessage = "无限制"; public test1() { //标题设置为五子棋 this.setTitle("五子棋"); //程序窗口的大小 this.setSize(900, 700); //让窗口大小不可调整(若可以调整会有bug) this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addMouseListener(this); //获取屏幕大小(以便让窗口直接出现在屏幕中心) int width = Toolkit.getDefaultToolkit().getScreenSize().width; int height = Toolkit.getDefaultToolkit().getScreenSize().height; this.setLocation((width - 900) / 2, (height - 700) / 2); //显示程序窗口(必须放到最后) this.setVisible(true); t.start(); t.suspend(); //刷新屏幕 this.repaint(); } public void paint (Graphics g){ //放置图片,并让图片处在合适的位置 g.drawImage(bgImage, 0, 30, this); g.setFont(new Font("隶书", 0, 25)); g.drawString("游戏信息:" + message, 50, 50); g.setFont(new Font("隶书", 0, 25)); g.drawString("黑方时间:" + blackMessage, 50, 660); g.drawString("白方时间:" + whiteMessage, 450, 660); g.setFont(new Font("隶书", Font.BOLD, 25)); g.drawString("开始游戏", 710, 88); g.drawString("游戏设置", 710, 172); g.drawString("认输", 730, 254); //画棋盘,我是15*15的棋盘 for (int i = 0; i < 15; i++) { g.drawLine(31, 57 + 40 * i, 591, 57 + 40 * i); g.drawLine(31 + 40 * i, 57, 31 + 40 * i, 617); } //画棋子,黑棋子是一个实心黑圆,白棋子是实心白圆加一个黑圆圈 for (int i = 0; i < 15; i++) for (int j = 0; j < 15; j++) { if (allChess[i][j] == 1) { int tempX = i * 40 + 31; int tempY = j * 40 + 57; g.fillOval(tempX - 15, tempY - 15, 30, 30); } if (allChess[i][j] == 2) { int tempX = i * 40 + 31; int tempY = j * 40 + 57; g.setColor(Color.WHITE); g.fillOval(tempX - 15, tempY - 15, 30, 30); g.setColor(Color.BLACK); g.drawOval(tempX - 15, tempY - 15, 30, 30); } } } @Override public void mouseClicked (MouseEvent e){ // TODO 自动生成的方法存根 } @Override public void mousePressed (MouseEvent e){ // TODO 自动生成的方法存根 if (canPlay == true) { //获取鼠标点击位置的坐标 x = e.getX(); y = e.getY(); //只有鼠标点击棋盘内时才能画棋子 if (x >= 31 && x <= 591 && y >= 57 && y <= 617) { //棋子只能绘制在交叉点初,所以需要一个算法 //如果(鼠标点击的坐标-初始点坐标)%间隔>1/2间隔,那么里这个鼠标点击的坐标最近的交叉点应当是下一个交叉点 if ((x - 31) % 40 > 20) { x = (x - 31) / 40 + 1; } else { x = (x - 31) / 40; } if ((y - 57) % 40 > 20) { y = (y - 57) / 40 + 1; } else { y = (y - 57) / 40; } //下棋的地方不能有棋子 if (allChess[x][y] == 0) { //第一个是黑棋,下完变白棋 if (isBlack == true) { allChess[x][y] = 1; isBlack = false; message = "轮到白方"; } else { allChess[x][y] = 2; isBlack = true; message = "轮到黑方"; } //判断输赢,看周围相连是否有五个 boolean winFlag = this.checkWin(); if (winFlag == true) { JOptionPane.showMessageDialog(this, "Game Over," + (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜!"); canPlay = false; } } //判断输赢,看周围相连是否有五个 this.repaint(); } } if (e.getX() >= 678 && e.getX() <= 838 && e.getY() >= 50 && e.getY() <= 115) { int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?"); if (result == 0) { allChess = new int[15][15]; isBlack = true; canPlay = true; blackTime = maxTime; whiteTime = maxTime; if (maxTime > 0) { blackMessage = maxTime / 3600 + ":" + (maxTime / 60 - maxTime / 3600 * 60) + ":" + (maxTime - maxTime / 60 * 60); whiteMessage = maxTime / 3600 + ":" + (maxTime / 60 - maxTime / 3600 * 60) + ":" + (maxTime - maxTime / 60 * 60); } else { blackMessage = "无限制"; whiteMessage = "无限制"; } t.resume(); this.repaint(); } } if (e.getX() >= 678 && e.getX() <= 838 && e.getY() >= 134 && e.getY() <= 194) { String input = JOptionPane.showInputDialog("请输入最大游戏时间(分钟),如果输入0则表示没有时间限制:"); try { maxTime = Integer.parseInt(input) * 60; if (maxTime < 0) { JOptionPane.showMessageDialog(this, "请输入正确信息,不允许时负数!"); } if (maxTime == 0) { int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?"); if (result == 0) { allChess = new int[15][15]; isBlack = true; canPlay = true; blackTime = maxTime; whiteTime = maxTime; blackMessage = "无限制"; whiteMessage = "无限制"; t.stop(); this.repaint(); } } if (maxTime > 0) { int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?"); if (result == 0) { allChess = new int[15][15]; isBlack = true; canPlay = true; blackTime = maxTime; whiteTime = maxTime; blackMessage = maxTime / 3600 + ":" + (maxTime / 60 - maxTime / 3600 * 60) + ":" + (maxTime - maxTime / 60 * 60); whiteMessage = maxTime / 3600 + ":" + (maxTime / 60 - maxTime / 3600 * 60) + ":" + (maxTime - maxTime / 60 * 60); t.resume(); this.repaint(); } } } catch (NumberFormatException el) { JOptionPane.showMessageDialog(this, "请输入正确信息!"); } } if (e.getX() >= 678 && e.getX() <= 838 && e.getY() >= 215 && e.getY() <= 274) { int result = JOptionPane.showConfirmDialog(this, "是否确认 认输?"); if (result == 0) { if (isBlack) { JOptionPane.showMessageDialog(this, "黑方已经认输,游戏结束!"); canPlay = false; } else { JOptionPane.showMessageDialog(this, "白方已经认输,游戏结束!"); canPlay = false; } JOptionPane.showMessageDialog(this, "请重新开始游戏"); } } } @Override public void mouseReleased (MouseEvent e){ // TODO 自动生成的方法存根 } @Override public void mouseEntered (MouseEvent e){ // TODO 自动生成的方法存根 } @Override public void mouseExited (MouseEvent e){ // TODO 自动生成的方法存根 } public boolean checkWin () { boolean flag = false; // 保存共有相同颜色多少棋子相连 int count = 1; int color = allChess[x][y]; count = this.checkCount(1, 0, color); if (count >= 5) { flag = true; } else { count = this.checkCount(0, 1, color); if (count >= 5) { flag = true; } else { count = this.checkCount(1, -1, color); if (count >= 5) { flag = true; } else { count = this.checkCount(1, 1, color); if (count >= 5) { flag = true; } } } } return flag; } private int checkCount ( int xChange, int yChange, int color){ int count = 1; int tempX = xChange; int tempY = yChange; while (x + xChange >= 0 && x + xChange <= 14 && y + yChange >= 0 && y + yChange <= 14 && color == allChess[x + xChange][y + yChange]) { count++; if (xChange != 0) xChange++; if (yChange != 0) { if (yChange > 0) yChange++; else { yChange--; } } } xChange = tempX; yChange = tempY; while (x - xChange >= 0 && x - xChange <= 14 && y - yChange >= 0 && y - yChange <= 14 && color == allChess[x - xChange][y - yChange]) { count++; if (xChange != 0) xChange++; if (yChange != 0) { if (yChange > 0) yChange++; else { yChange--; } } } return count; } @Override public void run () { // TODO 自动生成的方法存根 //判断是否有时间限制 if (maxTime > 0) { while (true) { if (isBlack) { blackTime--; if (blackTime == 0) { JOptionPane.showMessageDialog(this, "黑方超时,游戏结束"); canPlay = false; t.stop(); } } else { whiteTime--; if (whiteTime == 0) { JOptionPane.showMessageDialog(this, "白方超时,游戏结束"); canPlay = false; t.stop(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } blackMessage = blackTime / 3600 + ":" + (blackTime / 60 - blackTime / 3600 * 60) + ":" + (blackTime - blackTime / 60 * 60); whiteMessage = whiteTime / 3600 + ":" + (whiteTime / 60 - whiteTime / 3600 * 60) + ":" + (whiteTime - whiteTime / 60 * 60); this.repaint(); } } } }