代碼如下
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; public class FiveChessFrame extends JFrame implements MouseListener, Runnable { private static final long serialVersionUID = 1L; int width = Toolkit.getDefaultToolkit().getScreenSize().width; int hight = Toolkit.getDefaultToolkit().getScreenSize().height; // 背景圖片 BufferedImage bjImage = null; // 保存棋子坐標 int x = 0; int y = 0; // 保存之前下過的棋子坐標 // 其中數據:0:表示這個點沒有棋子 1:表示黑子 2:表示白子 int[][] allChess = new int[19][19]; // 標識當前是黑棋還是白旗下下一步 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 = "無限制"; @SuppressWarnings("deprecation") public FiveChessFrame() { this.setTitle("五子棋"); this.setSize(500, 500); this.setLocation((width - 500) / 2, (hight - 500) / 2); this.addMouseListener(this); // this.setResizable(false); this.setVisible(true); t.start(); t.suspend();// 線程掛起 // 剛打開的時候刷新屏幕,防止開始游戲時無法顯示的問題 this.repaint(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try { bjImage = ImageIO.read(new File("src/background.jpg")); } catch (IOException e) { e.printStackTrace(); } } @Override public void paint(Graphics g) { // 雙緩存技術 防止屏幕閃爍 但不知道為什么,使用雙緩存技術以后,效果特不好,所以沒用,如果使用的話,下面的 g 改為 g2 就可以了 // BufferedImage bi=new // BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); // Graphics g2=bi.createGraphics(); g.drawImage(bjImage, 0, 20, this); g.setFont(new Font("黑體", Font.BOLD, 20)); g.drawString("游戲信息:" + message, 120, 60); g.setFont(new Font("宋體", 0, 14)); g.drawString("黑方時間:" + blackMessage, 30, 470); g.drawString("白方時間:" + whiteMessage, 260, 470); // 繪制棋盤 for (int i = 0; i < 19; i++) { g.drawLine(10, 70 + 20 * i, 370, 70 + 20 * i); g.drawLine(10 + 20 * i, 70, 10 + 20 * i, 430); } // 標注小圓點位 g.fillOval(68, 128, 4, 4); g.fillOval(308, 128, 4, 4); g.fillOval(308, 368, 4, 4); g.fillOval(68, 368, 4, 4); g.fillOval(188, 128, 4, 4); g.fillOval(68, 248, 4, 4); g.fillOval(188, 368, 4, 4); g.fillOval(188, 248, 4, 4); g.fillOval(308, 248, 4, 4); // //繪制棋子 // x=(x-10)/20*20+10; //是為了取得交叉點的坐標 // y=(y-70)/20*20+70; // //黑子 // g.fillOval(x-7, y-7, 14, 14); // //白子 // g.setColor(Color.BLACK); // g.fillOval(x-7, y-7, 14, 14); // g.setColor(Color.BLACK); // g.drawOval(x-7, y-7, 14, 14); // 輸出數組中所有數值 // 繪制全部棋子 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { if (allChess[i][j] == 1) { // 黑子 int tempX = i * 20 + 10; int tempY = j * 20 + 70; g.fillOval(tempX - 7, tempY - 7, 14, 14); } if (allChess[i][j] == 2) { // 白子 int tempX = i * 20 + 10; int tempY = j * 20 + 70; g.setColor(Color.WHITE); g.fillOval(tempX - 7, tempY - 7, 14, 14); g.setColor(Color.BLACK); g.drawOval(tempX - 7, tempY - 7, 14, 14); } } } } @Override public void mouseClicked(MouseEvent e) { } private boolean checkWin() { boolean flag = false; // 保存共有多少相同顏色棋子相連 int count = 1; // 判斷橫向 特點:allChess[x][y]中y值相同 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 <= 18 && y + yChange >= 0 && y + yChange <= 18 && 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 <= 18 && y - yChange >= 0 && y - yChange <= 18 && 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 mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @SuppressWarnings("deprecation") @Override public void mousePressed(MouseEvent e) { if (canPlay == true) { x = e.getX(); y = e.getY(); if (x >= 10 && x <= 370 && y >= 70 && y <= 430) { // System.out.println("在棋盤范圍內:"+x+"--"+y); x = (x - 10) / 20; // 是為了取得交叉點的坐標 y = (y - 70) / 20; if (allChess[x][y] == 0) { // 判斷當前要下的是什么棋子 if (isBlack == true) { allChess[x][y] = 1; isBlack = false; message = "輪到白方"; } else { allChess[x][y] = 2; isBlack = true; message = "輪到黑方"; } // 判斷這個棋子是否和其他棋子連成5個 boolean winFlag = this.checkWin(); if (winFlag == true) { JOptionPane.showMessageDialog(this, "游戲結束," + (allChess[x][y] == 1 ? "黑方" : "白方") + "獲勝!"); canPlay = false; } } else { JOptionPane.showMessageDialog(this, "當前位子已經有棋子,請重新落子!!!"); } this.repaint(); } } // 點擊 開始游戲 按鈕 if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 70 && e.getY() <= 100) { int result = JOptionPane.showConfirmDialog(this, "是否重新開始游戲?"); if (result == 0) { // 現在重新開始游戲 // 重新開始所要做的操作:1)把棋盤清空,allChess數組中全部數據歸0; // 2)游戲相關信息顯示初始化 // 3)將下一步下棋改為黑方 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { allChess[i][j] = 0; } } // 另一種方式 allChess=new int[19][19] message = "黑方先行"; isBlack = 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); t.resume(); } else { blackMessage = "無限制"; whiteMessage = "無限制"; } this.repaint();// 如果不重新調用,則界面不會刷新 } }// 點擊 游戲設置 按鈕 if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 120 && e.getY() <= 150) { 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) { // 現在重新開始游戲 // 重新開始所要做的操作:1)把棋盤清空,allChess數組中全部數據歸0; // 2)游戲相關信息顯示初始化 // 3)將下一步下棋改為黑方 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { allChess[i][j] = 0; } } // 另一種方式 allChess=new int[19][19] message = "黑方先行"; isBlack = true; blackTime = maxTime; whiteTime = maxTime; blackMessage = "無限制"; whiteMessage = "無限制"; this.repaint();// 如果不重新調用,則界面不會刷新 } } if (maxTime > 0) { int result = JOptionPane.showConfirmDialog(this, "設置完成,是否重新開始游戲?"); if (result == 0) { // 現在重新開始游戲 // 重新開始所要做的操作:1)把棋盤清空,allChess數組中全部數據歸0; // 2)游戲相關信息顯示初始化 // 3)將下一步下棋改為黑方 for (int i = 0; i < 19; i++) { for (int j = 0; j < 19; j++) { allChess[i][j] = 0; } } // 另一種方式 allChess=new int[19][19] message = "黑方先行"; isBlack = 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 e1) { JOptionPane.showMessageDialog(this, "請正確提示信息"); } }// 點擊 游戲說明 按鈕 if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 170 && e.getY() <= 200) { JOptionPane.showMessageDialog(this, "這是一個五子棋游戲程序,黑白雙方輪流下棋,當某一方連到五子時,游戲結束。"); }// 點擊 認輸 按鈕 if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 270 && e.getY() <= 300) { int result = JOptionPane.showConfirmDialog(this, "是否確定認輸?"); if (result == 0) { if (isBlack) { JOptionPane.showMessageDialog(this, "黑方方已經認輸,游戲結束!!!"); } else { JOptionPane.showMessageDialog(this, "白方方已經認輸,游戲結束!!!"); } canPlay = false; } }// 點擊 關於 按鈕 if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 320 && e.getY() <= 350) { JOptionPane.showMessageDialog(this, "本游戲由菜鳥阿潔制作,有相關問題,可以聯系本人QQ:474280917。"); }// 點擊 退出 按鈕 if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 370 && e.getY() <= 400) { JOptionPane.showMessageDialog(this, "游戲退出"); System.exit(0); } } @Override public void mouseReleased(MouseEvent arg0) { } @Override public void run() { // 判斷是否有時間限制 if (maxTime > 0) { while (true) { if (isBlack) { blackTime--; if (blackTime == 0) { JOptionPane.showMessageDialog(this, "黑方超時,游戲結束!"); } } else { whiteTime--; if (whiteTime == 0) { JOptionPane.showMessageDialog(this, "白方超時,游戲結束!"); } } 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(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { @SuppressWarnings("unused") FiveChessFrame mf = new FiveChessFrame(); } }
<ignore_js_op>
運行效果圖如下
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>