JAVA实践(二)————五子棋

来源:互联网 发布:linux 如何把3改为5 编辑:程序博客网 时间:2024/05/09 16:20

一、实践目标:

       1.掌握JavaGUI界面设计

       2.掌握鼠标事件的监听(MouseListener,MouseMotionListener)

二、实践内容:

      设计一个简单的五子棋程序,能够实现五子棋下棋过程。如下图所示

 

五子棋运行界面

      1.五子棋棋盘类

[java] view plaincopyprint?
  1. package cn.edu.ouc.fiveChess;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Cursor;  
  5. import java.awt.Dimension;  
  6. import java.awt.Graphics;  
  7. import java.awt.Graphics2D;  
  8. import java.awt.Image;  
  9. import java.awt.RadialGradientPaint;  
  10. import java.awt.RenderingHints;  
  11. import java.awt.Toolkit;  
  12. import java.awt.event.MouseEvent;  
  13. import java.awt.event.MouseListener;  
  14. import java.awt.event.MouseMotionListener;  
  15. import java.awt.geom.Ellipse2D;  
  16.   
  17. import javax.swing.*;  
  18. /** 
  19.  * 五子棋--棋盘类  
  20.  */  
  21.   
  22. public class ChessBoard extends JPanel implements MouseListener {  
  23.    public static final int MARGIN=30;//边距  
  24.    public static final int GRID_SPAN=35;//网格间距  
  25.    public static final int ROWS=15;//棋盘行数  
  26.    public static final int COLS=15;//棋盘列数  
  27.      
  28.    Point[] chessList=new Point[(ROWS+1)*(COLS+1)];//初始每个数组元素为null  
  29.    boolean isBlack=true;//默认开始是黑棋先  
  30.    boolean gameOver=false;//游戏是否结束  
  31.    int chessCount;//当前棋盘棋子的个数  
  32.    int xIndex,yIndex;//当前刚下棋子的索引  
  33.      
  34.    Image img;  
  35.    Image shadows;  
  36.    Color colortemp;  
  37.    public ChessBoard(){  
  38.         
  39.       // setBackground(Color.blue);//设置背景色为橘黄色  
  40.        img=Toolkit.getDefaultToolkit().getImage("board.jpg");  
  41.        shadows=Toolkit.getDefaultToolkit().getImage("shadows.jpg");  
  42.        addMouseListener(this);  
  43.        addMouseMotionListener(new MouseMotionListener(){  
  44.            public void mouseDragged(MouseEvent e){  
  45.                  
  46.            }  
  47.              
  48.            public void mouseMoved(MouseEvent e){  
  49.              int x1=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
  50.              //将鼠标点击的坐标位置转成网格索引  
  51.              int y1=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
  52.              //游戏已经结束不能下  
  53.              //落在棋盘外不能下  
  54.              //x,y位置已经有棋子存在,不能下  
  55.              if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1))  
  56.                  setCursor(new Cursor(Cursor.DEFAULT_CURSOR));  
  57.              //设置成默认状态  
  58.              else setCursor(new Cursor(Cursor.HAND_CURSOR));  
  59.                
  60.            }  
  61.        });  
  62.    }   
  63.      
  64.     
  65.   
  66. //绘制  
  67.    public void paintComponent(Graphics g){  
  68.        
  69.        super.paintComponent(g);//画棋盘  
  70.        
  71.        int imgWidth= img.getWidth(this);  
  72.        int imgHeight=img.getHeight(this);//获得图片的宽度与高度  
  73.        int FWidth=getWidth();  
  74.        int FHeight=getHeight();//获得窗口的宽度与高度  
  75.        int x=(FWidth-imgWidth)/2;  
  76.        int y=(FHeight-imgHeight)/2;  
  77.        g.drawImage(img, x, y, null);  
  78.       
  79.          
  80.        for(int i=0;i<=ROWS;i++){//画横线  
  81.            g.drawLine(MARGIN, MARGIN+i*GRID_SPAN, MARGIN+COLS*GRID_SPAN, MARGIN+i*GRID_SPAN);  
  82.        }  
  83.        for(int i=0;i<=COLS;i++){//画竖线  
  84.            g.drawLine(MARGIN+i*GRID_SPAN, MARGIN, MARGIN+i*GRID_SPAN, MARGIN+ROWS*GRID_SPAN);  
  85.              
  86.        }  
  87.          
  88.        //画棋子  
  89.        for(int i=0;i<chessCount;i++){  
  90.            //网格交叉点x,y坐标  
  91.            int xPos=chessList[i].getX()*GRID_SPAN+MARGIN;  
  92.            int yPos=chessList[i].getY()*GRID_SPAN+MARGIN;  
  93.            g.setColor(chessList[i].getColor());//设置颜色  
  94.           // g.fillOval(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,  
  95.                            //Point.DIAMETER, Point.DIAMETER);  
  96.            //g.drawImage(shadows, xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, Point.DIAMETER, Point.DIAMETER, null);  
  97.            colortemp=chessList[i].getColor();  
  98.            if(colortemp==Color.black){  
  99.                RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/2+25, yPos-Point.DIAMETER/2+1020new float[]{0f, 1f}  
  100.                , new Color[]{Color.WHITE, Color.BLACK});  
  101.                ((Graphics2D) g).setPaint(paint);  
  102.                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
  103.                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);  
  104.   
  105.            }  
  106.            else if(colortemp==Color.white){  
  107.                RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/2+25, yPos-Point.DIAMETER/2+1070new float[]{0f, 1f}  
  108.                , new Color[]{Color.WHITE, Color.BLACK});  
  109.                ((Graphics2D) g).setPaint(paint);  
  110.                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
  111.                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);  
  112.   
  113.            }  
  114.            
  115.            Ellipse2D e = new Ellipse2D.Float(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/23435);  
  116.            ((Graphics2D) g).fill(e);  
  117.            //标记最后一个棋子的红矩形框  
  118.              
  119.            if(i==chessCount-1){//如果是最后一个棋子  
  120.                g.setColor(Color.red);  
  121.                g.drawRect(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,  
  122.                            3435);  
  123.            }  
  124.        }  
  125.    }  
  126.      
  127.    public void mousePressed(MouseEvent e){//鼠标在组件上按下时调用  
  128.          
  129.        //游戏结束时,不再能下  
  130.        if(gameOver) return;  
  131.          
  132.        String colorName=isBlack?"黑棋":"白棋";  
  133.          
  134.        //将鼠标点击的坐标位置转换成网格索引  
  135.        xIndex=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
  136.        yIndex=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;  
  137.          
  138.        //落在棋盘外不能下  
  139.        if(xIndex<0||xIndex>ROWS||yIndex<0||yIndex>COLS)  
  140.            return;  
  141.          
  142.        //如果x,y位置已经有棋子存在,不能下  
  143.        if(findChess(xIndex,yIndex))return;  
  144.          
  145.        //可以进行时的处理  
  146.        Point ch=new Point(xIndex,yIndex,isBlack?Color.black:Color.white);  
  147.        chessList[chessCount++]=ch;  
  148.         repaint();//通知系统重新绘制  
  149.         
  150.          
  151.        //如果胜出则给出提示信息,不能继续下棋  
  152.          
  153.        if(isWin()){  
  154.            String msg=String.format("恭喜,%s赢了!", colorName);  
  155.            JOptionPane.showMessageDialog(this, msg);  
  156.            gameOver=true;  
  157.        }  
  158.        isBlack=!isBlack;  
  159.      }  
  160.    //覆盖mouseListener的方法  
  161.    public void mouseClicked(MouseEvent e){  
  162.        //鼠标按键在组件上单击时调用  
  163.    }  
  164.      
  165.    public void mouseEntered(MouseEvent e){  
  166.        //鼠标进入到组件上时调用  
  167.    }  
  168.    public void mouseExited(MouseEvent e){  
  169.        //鼠标离开组件时调用  
  170.    }  
  171.    public void mouseReleased(MouseEvent e){  
  172.        //鼠标按钮在组件上释放时调用  
  173.    }  
  174.    //在棋子数组中查找是否有索引为x,y的棋子存在  
  175.    private boolean findChess(int x,int y){  
  176.        for(Point c:chessList){  
  177.            if(c!=null&&c.getX()==x&&c.getY()==y)  
  178.                return true;  
  179.        }  
  180.        return false;  
  181.    }  
  182.      
  183.      
  184.    private boolean isWin(){  
  185.        int continueCount=1;//连续棋子的个数  
  186.         
  187.        //横向向西寻找  
  188.        for(int x=xIndex-1;x>=0;x--){  
  189.            Color c=isBlack?Color.black:Color.white;  
  190.            if(getChess(x,yIndex,c)!=null){  
  191.                continueCount++;  
  192.            }else  
  193.                break;  
  194.        }  
  195.       //横向向东寻找  
  196.        for(int x=xIndex+1;x<=COLS;x++){  
  197.           Color c=isBlack?Color.black:Color.white;  
  198.           if(getChess(x,yIndex,c)!=null){  
  199.              continueCount++;  
  200.           }else  
  201.              break;  
  202.        }  
  203.        if(continueCount>=5){  
  204.              return true;  
  205.        }else   
  206.        continueCount=1;  
  207.          
  208.        //继续另一种搜索纵向  
  209.        //向上搜索  
  210.        for(int y=yIndex-1;y>=0;y--){  
  211.            Color c=isBlack?Color.black:Color.white;  
  212.            if(getChess(xIndex,y,c)!=null){  
  213.                continueCount++;  
  214.            }else  
  215.                break;  
  216.        }  
  217.        //纵向向下寻找  
  218.        for(int y=yIndex+1;y<=ROWS;y++){  
  219.            Color c=isBlack?Color.black:Color.white;  
  220.            if(getChess(xIndex,y,c)!=null)  
  221.                continueCount++;  
  222.            else  
  223.               break;  
  224.          
  225.        }  
  226.        if(continueCount>=5)  
  227.            return true;  
  228.        else  
  229.            continueCount=1;  
  230.          
  231.          
  232.        //继续另一种情况的搜索:斜向  
  233.        //东北寻找  
  234.        for(int x=xIndex+1,y=yIndex-1;y>=0&&x<=COLS;x++,y--){  
  235.            Color c=isBlack?Color.black:Color.white;  
  236.            if(getChess(x,y,c)!=null){  
  237.                continueCount++;  
  238.            }  
  239.            else break;  
  240.        }  
  241.        //西南寻找  
  242.        for(int x=xIndex-1,y=yIndex+1;x>=0&&y<=ROWS;x--,y++){  
  243.            Color c=isBlack?Color.black:Color.white;  
  244.            if(getChess(x,y,c)!=null){  
  245.                continueCount++;  
  246.            }  
  247.            else break;  
  248.        }  
  249.        if(continueCount>=5)  
  250.            return true;  
  251.        else continueCount=1;  
  252.          
  253.          
  254.        //继续另一种情况的搜索:斜向  
  255.        //西北寻找  
  256.        for(int x=xIndex-1,y=yIndex-1;x>=0&&y>=0;x--,y--){  
  257.            Color c=isBlack?Color.black:Color.white;  
  258.            if(getChess(x,y,c)!=null)  
  259.                continueCount++;  
  260.            else break;  
  261.        }  
  262.        //东南寻找  
  263.        for(int x=xIndex+1,y=yIndex+1;x<=COLS&&y<=ROWS;x++,y++){  
  264.            Color c=isBlack?Color.black:Color.white;  
  265.            if(getChess(x,y,c)!=null)  
  266.                continueCount++;  
  267.            else break;  
  268.        }  
  269.        if(continueCount>=5)  
  270.            return true;  
  271.        else continueCount=1;  
  272.          
  273.        return false;  
  274.      }  
  275.      
  276.      
  277.    private Point getChess(int xIndex,int yIndex,Color color){  
  278.        for(Point p:chessList){  
  279.            if(p!=null&&p.getX()==xIndex&&p.getY()==yIndex  
  280.                    &&p.getColor()==color)  
  281.                return p;  
  282.        }  
  283.        return null;  
  284.    }  
  285.      
  286.      
  287.    public void restartGame(){  
  288.        //清除棋子  
  289.        for(int i=0;i<chessList.length;i++){  
  290.            chessList[i]=null;  
  291.        }  
  292.        //恢复游戏相关的变量值  
  293.        isBlack=true;  
  294.        gameOver=false//游戏是否结束  
  295.        chessCount =0//当前棋盘棋子个数  
  296.        repaint();  
  297.    }  
  298.      
  299.    //悔棋  
  300.    public void goback(){  
  301.        if(chessCount==0)  
  302.            return ;  
  303.        chessList[chessCount-1]=null;  
  304.        chessCount--;  
  305.        if(chessCount>0){  
  306.            xIndex=chessList[chessCount-1].getX();  
  307.            yIndex=chessList[chessCount-1].getY();  
  308.        }  
  309.        isBlack=!isBlack;  
  310.        repaint();  
  311.    }  
  312.      
  313.    //矩形Dimension  
  314.   
  315.    public Dimension getPreferredSize(){  
  316.        return new Dimension(MARGIN*2+GRID_SPAN*COLS,MARGIN*2  
  317.                             +GRID_SPAN*ROWS);  
  318.    }  
  319.      
  320.      
  321.      
  322. }  


 

      2.棋子类

[java] view plaincopyprint?
  1. package cn.edu.ouc.fiveChess;  
  2.   
  3. import java.awt.Color;  
  4. /** 
  5.  * 棋子类 
  6.  */  
  7. public class Point {  
  8.   private int x;//棋盘中的x索引  
  9.   private int y;//棋盘中的y索引  
  10.   private Color color;//颜色  
  11.   public static final int DIAMETER=30;//直径  
  12.     
  13.   public Point(int x,int y,Color color){  
  14.       this.x=x;  
  15.       this.y=y;  
  16.       this.color=color;  
  17.   }   
  18.     
  19.   public int getX(){//拿到棋盘中x的索引  
  20.       return x;  
  21.   }  
  22.   public int getY(){  
  23.       return y;  
  24.   }  
  25.   public Color getColor(){//获得棋子的颜色  
  26.       return color;  
  27.   }  
  28. }  


 

      3.五子棋主框架类

[java] view plaincopyprint?
  1. package cn.edu.ouc.fiveChess;  
  2. import java.awt.event.*;  
  3. import java.awt.*;  
  4.   
  5. import javax.swing.*;  
  6. /* 
  7.  五子棋主框架類,程序啟動類 
  8.  */  
  9. public class StartChessJFrame extends JFrame {  
  10.   private ChessBoard chessBoard;  
  11.   private JPanel toolbar;  
  12.   private JButton startButton,backButton,exitButton;  
  13.     
  14.   private JMenuBar menuBar;  
  15.   private JMenu sysMenu;  
  16.   private JMenuItem startMenuItem,exitMenuItem,backMenuItem;  
  17.   //重新开始,退出,和悔棋菜单项  
  18.   public StartChessJFrame(){  
  19.       setTitle("单机版五子棋");//设置标题  
  20.       chessBoard=new ChessBoard();  
  21.       
  22.         
  23.       Container contentPane=getContentPane();  
  24.       contentPane.add(chessBoard);  
  25.       chessBoard.setOpaque(true);  
  26.         
  27.         
  28.       //创建和添加菜单  
  29.       menuBar =new JMenuBar();//初始化菜单栏  
  30.       sysMenu=new JMenu("系统");//初始化菜单  
  31.       //初始化菜单项  
  32.       startMenuItem=new JMenuItem("重新开始");  
  33.       exitMenuItem =new JMenuItem("退出");  
  34.       backMenuItem =new JMenuItem("悔棋");  
  35.       //将三个菜单项添加到菜单上  
  36.       sysMenu.add(startMenuItem);  
  37.       sysMenu.add(exitMenuItem);  
  38.       sysMenu.add(backMenuItem);  
  39.       //初始化按钮事件监听器内部类  
  40.       MyItemListener lis=new MyItemListener();  
  41.       //将三个菜单注册到事件监听器上  
  42.       this.startMenuItem.addActionListener(lis);  
  43.       backMenuItem.addActionListener(lis);  
  44.       exitMenuItem.addActionListener(lis);  
  45.       menuBar.add(sysMenu);//将系统菜单添加到菜单栏上  
  46.       setJMenuBar(menuBar);//将menuBar设置为菜单栏  
  47.         
  48.       toolbar=new JPanel();//工具面板实例化  
  49.       //三个按钮初始化  
  50.       startButton=new JButton("重新开始");  
  51.       exitButton=new JButton("退出");  
  52.       backButton=new JButton("悔棋");  
  53.       //将工具面板按钮用FlowLayout布局  
  54.       toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));  
  55.       //将三个按钮添加到工具面板  
  56.       toolbar.add(startButton);  
  57.       toolbar.add(exitButton);  
  58.       toolbar.add(backButton);  
  59.       //将三个按钮注册监听事件  
  60.       startButton.addActionListener(lis);  
  61.       exitButton.addActionListener(lis);  
  62.       backButton.addActionListener(lis);  
  63.       //将工具面板布局到界面”南方“也就是下方  
  64.       add(toolbar,BorderLayout.SOUTH);  
  65.       add(chessBoard);//将面板对象添加到窗体上  
  66.       //设置界面关闭事件  
  67.       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  68.       //setSize(800,800);  
  69.       pack();//自适应大小  
  70.         
  71.   }  
  72.     
  73.   private class MyItemListener implements ActionListener{  
  74.       public void actionPerformed(ActionEvent e){  
  75.           Object obj=e.getSource();//获得事件源  
  76.           if(obj==StartChessJFrame.this.startMenuItem||obj==startButton){  
  77.               //重新开始  
  78.               //JFiveFrame.this内部类引用外部类  
  79.               System.out.println("重新开始");  
  80.               chessBoard.restartGame();  
  81.           }  
  82.           else if (obj==exitMenuItem||obj==exitButton)  
  83.               System.exit(0);  
  84.           else if (obj==backMenuItem||obj==backButton){  
  85.               System.out.println("悔棋...");  
  86.               chessBoard.goback();  
  87.           }  
  88.       }  
  89.   }  
  90.     
  91.     
  92.     
  93.   public static void main(String[] args){  
  94.       StartChessJFrame f=new StartChessJFrame();//创建主框架  
  95.       f.setVisible(true);//显示主框架  
  96.         
  97.   }  
  98. }  
0 0
原创粉丝点击