package FiveChessDome; 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 FiveChessFream extends JFrame implements MouseListener,Runnable{ int width=Toolkit.getDefaultToolkit().getScreenSize().width; int higth=Toolkit.getDefaultToolkit().getScreenSize().height; //背景图片 BufferedImage bgImage= 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= "无限制" ; public FiveChessFream() { //标题 this .setTitle( "五子棋" ); //窗体大小 this .setSize( 626 , 625 ); //窗体在屏幕的位置 this .setLocation((width- 500 )/ 2 ,(higth- 500 )/ 2 ); //窗体不可变 this .setResizable( false ); //窗体关闭 this .setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //为窗体加入监听器 this .addMouseListener( this ); //窗体显示 this .setVisible( true ); //启动线程 t.start(); t.suspend(); //刷新屏幕,防止开始游戏时无法显示屏幕的情况 this .repaint(); //背景图的导入 try { bgImage=ImageIO.read( new File( "d:/桌面/五子棋2.png" )); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void paint(Graphics g) { //双缓冲技术防止屏幕闪烁 BufferedImage bi= new BufferedImage( 626 , 625 , BufferedImage.TYPE_INT_ARGB); Graphics g2=bi.createGraphics(); //绘制背景 g.drawImage(bgImage, 3 , 20 , this ); //输出标题信息 g.setFont( new Font( "黑体" ,Font.BOLD, 20 )); g.drawString( "游戏信息:" +message, 100 , 60 ); //输出时间信息 g.setFont( new Font( "宋体" , 10 , 14 )); g.drawString( "黑色的时间:" +blackMessage, 40 , 585 ); g.drawString( "白色的时间:" +whiteMessage, 330 , 585 ); //绘制棋盘 for ( int i= 0 ;i< 19 ;i++) { //横轴 g.drawLine( 17 , 89 + 25 *i, 467 , 89 + 25 *i); //竖轴 g.drawLine( 17 + 25 *i, 89 , 17 + 25 *i, 538 ); } //标志点位,四个点 g.fillOval( 90 , 162 , 4 , 4 ); g.fillOval( 90 , 462 , 4 , 4 ); g.fillOval( 390 , 162 , 4 , 4 ); g.fillOval( 390 , 462 , 4 , 4 ); //绘制全部旗子 for ( int i= 0 ;i< 19 ;i++) { for ( int j= 0 ;j< 19 ;j++) { if (allChess[i][j]== 1 ) { //黑子 int tempx=i* 25 + 17 ; int tempy=j* 25 + 89 ; g.fillOval(tempx- 7 ,tempy- 7 , 14 , 14 ); } if (allChess[i][j]== 2 ) { //白子 int tempx=i* 25 + 17 ; int tempy=j* 25 + 89 ; 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) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { if (canPlay== true ) { x=e.getX(); y=e.getY(); //判断旗子落在棋盘上 if (x> 17 &&x<= 467 && y> 89 &&y<= 538 ) { x=(x- 17 )/ 25 ; y=(y- 89 )/ 25 ; 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 , "游戏结束" +(allChess[x][y]== 1 ? "黑色" : "白色" )+ "获胜" ); canPlay= false ; } } else { JOptionPane.showMessageDialog( this , "当前位置已经有棋子,请重新落子!" ); } this .repaint(); } } //System.out.println(e.getX()+"`````"+e.getY()); //点击 游戏开始 按钮 if (e.getX()>= 508 && e.getX()<= 595 &&e.getY()>= 90 &&e.getY()<= 125 ) { int r1=JOptionPane.showConfirmDialog( this , "是否重新开始游戏?" ); if (r1== 0 ) { //重新开始游戏1、棋盘清空;allChess==0;2、将游戏信息的显示改到开始位置;3、将下一步要下棋的改为黑方 allChess= new int [ 19 ][ 19 ]; message= "黑方先行" ; isBlack= true ; //重新绘制棋盘 this .repaint(); } } //点击 游戏设置 按钮 if (e.getX()>= 508 && e.getX()<= 595 &&e.getY()>= 154 &&e.getY()<= 190 ) { String input=JOptionPane.showInputDialog( "请输入游戏的最大时间(分钟),输入0表示没有时间限制" ); try { maxTime=Integer.parseInt(input)* 60 ; if (maxTime< 0 ) { JOptionPane.showMessageDialog( this , "不允许输入负数" ); } if (maxTime> 0 ){ int r1=JOptionPane.showConfirmDialog( this , "是否重新开始游戏?" ); if (r1== 0 ) { //重新开始游戏1、棋盘清空;allChess==0;2、将游戏信息的显示改到开始位置;3、将下一步要下棋的改为黑方 allChess= new int [ 19 ][ 19 ]; message= "黑方先行" ; 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 ); isBlack= true ; t.resume(); //重新绘制棋盘 this .repaint(); } } } catch (NumberFormatException e1){ JOptionPane.showMessageDialog( this , "请正确输入信息" ); } } //点击 游戏说明 按钮 if (e.getX()>= 508 && e.getX()<= 595 &&e.getY()>= 214 &&e.getY()<= 248 ) { JOptionPane.showMessageDialog( this , " 这是一个五子棋游戏,黑白双方轮流下" ); } //点击 认输 按钮 if (e.getX()>= 508 && e.getX()<= 595 &&e.getY()>= 344 &&e.getY()<= 378 ) { int result=JOptionPane.showConfirmDialog( this , "是否确认认输?" ); if (result== 0 ) { if (isBlack) { JOptionPane.showMessageDialog( this , "黑方认输" ); } else { JOptionPane.showMessageDialog( this , "白方认输" ); } } } //点击 关于 按钮 if (e.getX()>= 508 && e.getX()<= 595 &&e.getY()>= 406 &&e.getY()<= 438 ) { JOptionPane.showMessageDialog( this , "本游戏由@JiaHao制作,视频地址https://www.bilibili." + "com/video/BV1kJ411s7zf?p=10&share_source=copy_web" ); } //点击 退出 按钮 if (e.getX()>= 508 && e.getX()<= 595 &&e.getY()>= 466 &&e.getY()<= 501 ) { JOptionPane.showMessageDialog( this , "退出" ); System.exit( 0 ); } } //判断什么棋子赢 public boolean checKwin() { boolean flag= false ; //判断横向的是否有五个棋子,特点 纵坐标是相同的即allChess[X][Y]中Y值是相同的 int color=allChess[x][y]; //保存共有多少相同颜色的棋子 int count= 1 ; //判断横向 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 ; } 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=tempY; yChange=tempX; while (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 mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void run() { // TODO Auto-generated method stub //判断是否有时间限制 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) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } |