zoukankan      html  css  js  c++  java
  • 结对实践项目——“五子棋”小游戏

    之前与小组同学合作过一起写代码,那时老师分工明确,写两部分代码,一人负责一部分,剩下一个人做测试代码,在老师详尽的分工下,我们顺利的完成了那次任务。

    这次从无范围自主选题,到熟练运用GUI,实现了人人对战。

    【功能分析】

    (1)程序在设计初就定义黑棋先行,白棋随后。一个玩家通过w,a,s,d键控制落子位置,按Space落子,另一个玩家通过控制方向键up,down,left,right控制位置,按Enter落子,从第一个棋子开始开始相互顺 序落子。  

    (2)通过坐标索引算出最先在棋盘的横向、竖向、斜向形成连续的相同色五棋子的一方为胜利。 

    (3)初始界面洁净无子设为游戏固定界面。 

    (4)在游戏过程中单击重新开局按钮或下完时可选择重新开始。 

    (5)游戏结束,会出现赢家对话框提示。 

    (6)游戏实现了基本的人人对战。

    【分工情况】

    芦畅:GUI设计及代码规范

    苏正生:棋子胜负判断

    【代码链接】

    队友苏正生的报告:http://www.cnblogs.com/suzhengsheng/p/4549516.html

    源代码链接:http://git.shiyanlou.com/szs20135333/shiyanlou_cs212

    【总体设计】

    主要包括的类有四个:GameFrame、GamePanel、ChessMan、Player

    1、  GamePanel类  

     GamePanel类是java版五子棋的主框架,程序的启动类。 

    其中包括游戏界面的创建、按钮的设置、相关的事件监听器设置、游戏的启动  

    2、GameFrame类  

     GameFrame类主要实现的是棋盘的绘制、创建数组存放棋子的坐标、设置只能在棋盘内可以落子、实现判断黑白棋的输赢、实现重新游戏。  

    3、ChessMan类  

     Point类主要就是实现棋子的功能

    4、Player类

    Player类主要实验玩家的功能

    【过程分析】

    这次实验,我主要负责

    这次我主要负责的是GUI设计以及代码规范,我来大概说下GUI。

    GUI编程规范总结:

    1、首先就是建立菜单栏。在GUI控件使用时所有的控件都是层层嵌套的,就是控件依托,最终整合到面板上,进而再添加事件监听器,已响应事件的发生;

    ①首先要建立主框架:GamePanel Gpanel=new GamePanel();

    ②取得框架的内容窗格 

    ③在制作复杂的用户界面时,常常需要使用多个JPanel将复杂的界面分解为先对建大的子界面,然后再对每个JPanel进行布局:

    package WuZiGame;
    
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    
    class GameFrame extends JFrame {
    
        private static final int Width=570;
        private static final int Height=470;
        
        GameFrame(){
            setTitle("五子棋游戏");
            CenteredFrame();
            setSize(Width,Height);        
            GamePanel Gpanel=new GamePanel();
            add(Gpanel);       
        }
        
        void CenteredFrame(){
            Toolkit kit=Toolkit.getDefaultToolkit();
            Dimension screenSize=kit.getScreenSize();
            int screenHeight=screenSize.height;
            int screenWidth=screenSize.width;
            
            int Xposition=(screenWidth-Width)/2;
            int Yposition=(screenHeight-Height)/2;
            setLocation(Xposition,Yposition);
        }
    }

    ⑤处理控件的依赖关系,及消息的定义,各种细节的设计

    ⑥控件的逐级加入

    ⑦将面板加入到框架的内容窗格中

    package WuZiGame;
    
    import javax.swing.*;
    
    
    public class Game {
    
        
        public static void main(String[] args) {
            
            GameFrame GFrame=new GameFrame();
            GFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            GFrame.setVisible(true);
        }
    
    }
    package WuZiGame;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    
    
    
    class GamePanel extends JPanel {
    
        private Point cursor=new Point(40,60); //棋盘坐标
        private int[][] ChessState=new int[18][18];//棋盘状态    
        private int i=0;//横坐标   
        private int j=0;//纵坐标
        private final static int testnum=5;//五子棋的规定棋子数
        private Player Black=new Player(1,Color.BLACK,"黑方");//黑方棋子
        private Player White=new Player(2,Color.WHITE,"白方");//白方棋子
        private Player Cplayer=null;//当前用户的引用
        private JTextField textBlack=new JTextField("",5);//黑方文本提示框对象和文本长度设置
        private JTextField textWhite=new JTextField("",5);//白方文本提示框对象和文本长度设置
        private String Nothing="";
        private String textblack="请黑方下子";//黑方提示文本
        private String textwhite="请白方下子";//白方提示文本
        
        
        GamePanel(){
            setLayout(null);
            Initialization();
            setFocusable(true);
            
             JButton Rutton=new JButton("重新开局");
            Rutton.setBounds(20,14,100,26);
            RestartListener restart=new RestartListener();
            Rutton.addActionListener(restart);
            add(Rutton);
            
            
            textBlack.setHorizontalAlignment(JTextField.CENTER);
            textBlack.setBounds(150,14,110,26);
            textBlack.setEditable(false);
            add(textBlack);
           
    
            textWhite.setHorizontalAlignment(JTextField.CENTER);
            textWhite.setBounds(290,14,110,26);
            textWhite.setEditable(false);
            add(textWhite);
            
            JTextArea gInstruction=new JTextArea();
            gInstruction.setSelectedTextColor(new Color(238,238,238));
            String gSInstruction=
            "Play1(黑方) Key 
    up--------W 
    down----S 
    left--------A   
    right------D 
    
    "+
            "Play2(白方) Key 
    up--------up 
    down----down 
    left--------left 
    right------right 
    
    "+
            "Exit game: 
    Press Esc";
             gInstruction.setText(gSInstruction);
             gInstruction.setEditable(false);
             gInstruction.setBounds(440,60,100,340);
             add(gInstruction);
            
            ChessManPerformListener Perform=new ChessManPerformListener();
            addKeyListener(Perform);
            
        }
        
    //    设置第一个JTextField输出"请黑方下棋",坐标为(40,60)
         void Initialization(){        
            for(int i=0,j;i<18;i++)
                for(j=0;j<18;j++){
                    ChessState[i][j]=0;                
                 }
            cursor.setLocation(40,60);
            Cplayer=Black;
            textBlack.setText(textblack);
            textWhite.setText(Nothing);
        }
        
        
        //画棋盘和初始化棋局状态
        protected void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2=(Graphics2D) g;
             
            for(int i=60;i<=400;i+=20){
                g2.drawLine(40,i,380,i);
            }
            for(int j=40;j<=380;j+=20){
                g2.drawLine(j,60,j,400);
            }
            g2.drawString("_",cursor.x-6,cursor.y);
            g2.drawString("_",cursor.x,cursor.y);
            
            for(i=0;i<18;i++)
                for(j=0;j<18;j++){
                    if(ChessState[i][j]!=0){
                    if(ChessState[i][j]==1){
                        g2.setPaint(Black.getplayerChessManColor());        
                }
                    if(ChessState[i][j]==2){
                    g2.setPaint(White.getplayerChessManColor());
                }
                g2.fillOval(j*20+40-10, i*20+60-10, ChessMan.getChessManSize(), ChessMan.getChessManSize());
                }
            }
        }
        
       
        
        //判断棋盘的当前位置是否已有棋子
        boolean isChessState(){ 
            this.j=(cursor.x-40)/20;
            this.i=(cursor.y-60)/20;
            if(ChessState[this.i][this.j]!=0)
                return true;
            else
                return false;        
        }
        
        
        
           
        //记录落子后棋盘的当前位置的状态
         void RecordChessState(){
             this.j=(cursor.x-40)/20;
            this.i=(cursor.y-60)/20;
            ChessState[this.i][this.j]=Cplayer.getCurrentIdentify();
        }
        
        
         
         
         
         
        //判断当前玩家落子后是否赢了
        void JudgeWin(){
            for(int i=0;i<4;i++)
                if(JudgeWinLine(i)){
                //提示当前玩家已经获得胜利
                    try{
                        String Ginformation="GameInformation";
                        String Message="恭喜玩家"+Cplayer.getsIdentify()+"获胜!"+"
    "+"继续游戏还是退出游戏?";
                        String[] options = {"继续","退出"};
                        int selection=JOptionPane.showOptionDialog(null,Message,Ginformation,
                             JOptionPane.YES_NO_OPTION,JOptionPane.INFORMATION_MESSAGE ,null,options,options[0]);//throws HeadlessException
                        if(selection==JOptionPane.OK_OPTION){                    
                               Initialization();
                               repaint();
                               return;
                          }
                        if(selection==JOptionPane.NO_OPTION){
                              System.exit(0);//退出程序
                         }
                    
                      }catch(HeadlessException e){
                     e.printStackTrace();
                 }
                    }
            //如果当前方没有赢棋则双方轮换
            ChangeCurrentPlayer();
        }
         
         
         
        
        
        //在当前方向上是否有连续的五只棋子
        boolean JudgeWinLine(int direction){
            int i,j,di,dj,count;
            i=j=di=dj=count=0;
            switch(direction){
            case 0:
                j=this.j-(testnum-1);
                i=this.i;
                dj=1;
                di=0;
                break;
            case 1:
                j=this.j;
                i=this.i-(testnum-1);
                dj=0;
                di=1;
                break;
            case 2:
                j=this.j-(testnum-1);
                i=this.i+(testnum-1);
                dj=1;
                di=-1;
                break;
            case 3:
                j=this.j-(testnum-1);
                i=this.i-(testnum-1);
                dj=1;
                di=1;
                break;
            }
            
           for(int k=0;k<testnum*2+1;k++){
               if(j>=0&&j<18&&i>=0&&i<18){
                   if(ChessState[i][j]==Cplayer.getCurrentIdentify()){
                       count++;
                       if(count>=testnum)
                           return true;
                   }
                   else
                       count=0;
               }
               j+=dj;
               i+=di;
          } 
           return false;
    }
        
        
        
        
        //更换当前玩家
        void ChangeCurrentPlayer(){
            if(Cplayer==Black){
                Cplayer=White;
                textBlack.setText(Nothing);
                textWhite.setText(textwhite);
            }
            else{
                Cplayer=Black;
                textBlack.setText(textblack);
                textWhite.setText(Nothing);
            }
        }
        
        
        
        
        
        
        //重新开局监听器
    private class RestartListener implements ActionListener{
    
            public void actionPerformed(ActionEvent arg0) {
                
                Initialization();
                repaint();
                requestFocus();
            } 
           }
        
    
           
           
           
           
           //棋盘、棋局状态监听器
    private class ChessManPerformListener implements KeyListener{
    
          
          //玩家2的按键
               public void keyPressed(KeyEvent event) {
                   int keyCode=event.getKeyCode();
                      if(keyCode==KeyEvent.VK_ESCAPE)
                            System.exit(0);
                      if(Cplayer.getCurrentIdentify()==2){//判别当前玩家
                           if(keyCode==KeyEvent.VK_LEFT){
                              if(cursor.x>40)
                                cursor.x-=20;
                           }
                       else if(keyCode==KeyEvent.VK_RIGHT){
                           if(cursor.x<380)
                               cursor.x+=20;
                           }
                       else if(keyCode==KeyEvent.VK_UP){
                           if(cursor.y>60)
                               cursor.y-=20;
                           }
                       else if(keyCode==KeyEvent.VK_DOWN){
                           if(cursor.y<400)
                                cursor.y+=20;
                           }
                       else if(keyCode==KeyEvent.VK_ENTER){
                                if(!isChessState()){
                             Cplayer.PerformChessMan();
                             RecordChessState();
                             repaint();
                             JudgeWin();//判定当前落子后是否赢棋
                             
                             }
                            
                   }                      
                         repaint();                    
                 }
           }
    
               
               
              
    
               
               
               public void keyReleased(KeyEvent event) {}
    
               
               
               
              //玩家1的按键
               public void keyTyped(KeyEvent event) {
                   
                   char keyChar=event.getKeyChar();
                   if(Cplayer.getCurrentIdentify()==1){//判别当前玩家
                   if(keyChar=='a'){
                       if(cursor.x>40)//对移动光标超界现象做判别
                            cursor.x-=20;
                       }
                   else if(keyChar=='d'){
                       if(cursor.x<380)            
                           cursor.x+=20;
                       }
                   else if(keyChar=='w'){
                       if(cursor.y>60)
                            cursor.y-=20;
                       }
                   else if(keyChar=='s'){
                       if(cursor.y<400)
                            cursor.y+=20;
                       }    
                   else if(keyChar==' '){
                       if(!isChessState()){      //落子前先判断当前位置上是否已有棋子
                           Cplayer.PerformChessMan();//落子                     
                           RecordChessState();//记录当前落子后棋盘状态
                           repaint();
                              JudgeWin();//判定当前落子后是否赢棋
                           
                           } 
                    }
                
            }
                   repaint();    
               }
    
            }
              
    }
    package WuZiGame;
    
    
    import java.awt.Color;
    
    class ChessMan {
    
        private static final int ChessManSize=20;
        private Color ChessManColor;
        
        ChessMan(Color c){
            ChessManColor=c;
        }
    
        
        
        static int getChessManSize(){
            return ChessManSize;
        }
    
        
        Color getChessManColor(){
            return ChessManColor;
        }
        
        
    }
    package WuZiGame;
    
    import java.awt.Color;
    
    
    class Player {
    
        private int identify;
        private ChessMan pChessMan;
        private String PlayerStringIdentify;
    
        
        Player(int identify,Color c,String sIdentify){
            this.identify=identify;
            pChessMan=new ChessMan(c);
            this.PlayerStringIdentify=sIdentify;
        }
       
    
        
        int getCurrentIdentify(){
            return identify;
        }
    
        
        
        String getsIdentify(){
            return PlayerStringIdentify;
        }
    
        
        void PerformChessMan(){}
       
    
        
        Color getplayerChessManColor(){
            return pChessMan.getChessManColor();
        }
    }

    【设计结果】

    初始界面

    下棋中

    结束界面

    【统计时间】

    步骤

    耗时

    百分比

    需求分析

      1.5h

     13.6%

    设计

     2h  18.2%

    代码实现

     3h  27.3%

    测试

     2h  18.2%

    分析总结

     2.5h  22.7%

    【实验心得】

    通过这次对Java的学习,让我渐渐体会到了Java的博大精深。以及怎么学习Java,怎么学习计算机语言,怎样对问题进行解决和运用Java GUI,查找的使用都用了更进一步的理解。而且这次两人团队工作,也让我体会到合作的重要意义,两个人的想法经过商讨,研究总会比一个人的好很多,两个人事先做好分工工作再汇总整合也大大提高了效率。刚开始学习Java时我并不是非常的理解,知道就如何做能实现相应的功能,并没有很深刻的去理解它为什么要这么做。这次实验使我明白,真正的用Java去做一个东西不理解它是不行的,而且这个游戏涉及到了Java 中许多的知识点,如Java图形用户界面设计、Java的异常处理机制、Java中的多线程程序设计、Java输入输出流,要应用这些东西更要求我去好好理解Java的这些规则。这次实验,我还是收获良多。虽然界面也不是很美观,有点功能间的连接做的也不是特别的好,但是我能认识到自己的不足,并且在跟队友的交流中也学到了一些的设计思路,也知道今后要加强哪些方面的知识。

  • 相关阅读:
    快速登录机器&数据库
    质量报告之我见
    一些 ssh 小技巧
    virtualenv简介以及一个比较折腾的scrapy安装方法
    用scrapy数据抓取实践
    即将到来的5G,我们该做些什么准备?
    浅谈由管理者角色引出的B端产品设计思考点
    CodeForces 707C Pythagorean Triples (数论)
    UVaLive 6625 Diagrams & Tableaux (状压DP 或者 DFS暴力)
    CodeForces 707B Bakery (水题,暴力,贪心)
  • 原文地址:https://www.cnblogs.com/bonjourvivi/p/4550714.html
Copyright © 2011-2022 走看看