美文网首页java自学Web前端之路程序员
综合练习——简易俄罗斯方块

综合练习——简易俄罗斯方块

作者: 孙浩j | 来源:发表于2017-11-20 15:40 被阅读33次

    需求分析:类1.图形类(父类图形和子类的具体图形)2.屏幕类

    • 图形类,这个类可以被具体的图形所继承
    • 图形是由多个点组成的,每个点有它的位置,点的位置决定了图形位置
    • 所以建立点类,把点放到数组中,用多点的组合位置表示图形
    • 图形类具有的功能
    • 1.左移
    • 2.右移
    • 3.下移
    • 4.顺时针旋转
    • 5.判断是否越界
      *屏幕类核心功能
      *1.消行
      *(1)判断最后一行是不是满的
      *(2)消除最后一行
      *2.保存图形
      *(1)保存正在移动的图形
      *(2)保存已经到底不能再移动的图形

    *3.打印图形
    *(1)打印的图形包括正在移动的图形和被存的图形

    *4.判断正在移动的图形和被存的图形坐标是否冲和
    */

    点类

    public class Spot {
        private int row;   //定义行坐标
        private int col;   //定义列坐标
        
        public Spot(int row, int col) {
            super();
            this.row = row;
            this.col = col;
        }
        
        public Spot() {
            super();
        }
    
        public int getRow() {
            return row;
        }
        public void setRow(int row) {
            this.row = row;
        }
        public int getCol() {
            return col;
        }
        public void setCol(int col) {
            this.col = col;
        }
        //图形的移动功能是根据点移动的
        public void left(){
            col=col-1;
        }
        public void right(){
            col=col+1;
        }
        public void bottom(){
            row=row+1;
        }           
    }
    
    
    public abstract class Graph {
      private Spot[]sp=new Spot[4];  //建立一个用于构成图形的数组
        public Graph(){
            
        }
        public Spot[] getSp() {   
            return sp;
        }
        public void setSp(Spot[] sp) {
            this.sp = sp;
        }
        public void leftG(){   //图形左移,将数组里每一个点左边都进行改变
            for(int i=0;i<sp.length;i++){
                sp[i].setCol(sp[i].getCol()-1);
            }
            
        }
        public void rightG(){   //图形右移
            for(int i=0;i<sp.length;i++){
                sp[i].setCol(sp[i].getCol()+1);
            }   
        }
        public void bottomG(){   //图形下移
            for(int i=0;i<sp.length;i++){
                sp[i].setRow(sp[i].getRow()+1);
            }
            
        }
        
        
        public void topG(){   //图形上移
            for(int i=0;i<sp.length;i++){
                sp[i].setRow(sp[i].getRow()-1);
            }
            
        }
        public boolean judgeLeft(){  //判断左侧是否越界,越界为true
            for(int i=0;i<sp.length;i++){
                if(sp[i].getCol()<1){
                    return true;
                }
            }
            return false; 
            
        }
        public boolean judgeRight(){  //判断右侧是否越界,越界为true
            for(int i=0;i<sp.length;i++){
                if(sp[i].getCol()>12){
                    return true;
                }
            }
            return false; 
            
        }
        public boolean judgeBottom(){  //判断下侧是否越界,越界为true
            for(int i=0;i<sp.length;i++){
                if(sp[i].getRow()>15){
                    return true;
                }
            }
            return false; 
            
        }
        public abstract void rotate();//y-q+p, p-x+q
            //定义一个抽象的旋转的方法,由子类决定怎么旋转
        
    }
    
    

    具体图形类T型(该类继承了抽象类图形,自动具备了非抽象方法)

    public class T extends Graph { 
    
        public T(int row,int col){   //子类调用父类方法要使用super.方法
            super.getSp()[0]=new Spot(row,col-1);  //通过确定中心点坐标找到其它点和其关系,确定了图形形状
            super.getSp()[1]=new Spot(row,col);
            super.getSp()[2]=new Spot(row,col+1);
            super.getSp()[3]=new Spot(row+1,col);
        }
        
        public void rotate() {//y-q+p, p-x+q
            Spot[] sp=new Spot[4]; 
      //建一个新数组用于接收旋转后的图形,用原数组,旋转后坐标和原坐标有影响
            for(int i=0;i<super.getSp().length;i++){
                sp[i]=new Spot(super.getSp()[i].getCol()
                        -super.getSp()[1].getCol()
                        +super.getSp()[1].getRow(),
                        super.getSp()[1].getRow()
                        -super.getSp()[i].getRow()
                        +super.getSp()[1].getCol());
    
            }
            super.setSp(sp);    //把这个旋转后的坐标位置传给图形
            
        }
        public void rotate1() {//y-q+p, p-x+q   //逆时针旋转
            Spot[] sp=new Spot[4];
            for(int i=0;i<super.getSp().length;i++){
                sp[i]=new Spot(-super.getSp()[i].getCol()
                        +super.getSp()[1].getCol()
                        +super.getSp()[1].getRow(),
                        -super.getSp()[1].getRow()
                        +super.getSp()[i].getRow()
                        +super.getSp()[1].getCol());
    
            }
            super.setSp(sp);    
        }
    }
    
    

    屏幕类

    public class Screen {
        private String[][] s=new String[15][12];//保存当前图形
        private String[][] s1=new String[15][12]; //用于存已有图形
        public Screen(){
            for(int i=0;i<s1.length;i++){
                for(int j=0;j<s1[i].length;j++){
                    s1[i][j]="*";
                }
            }
        }
        
        public void setS(Graph g){
            //把图形存到屏幕中图形坐标的位置里。
            for(int i=0;i<s.length;i++){   //屏幕的行
                for(int j=0;j<s[i].length;j++){        //屏幕的列
                    boolean b=false;
                    for(int k=0;k<g.getSp().length;k++){   //
                        if((g.getSp()[k].getRow()==(i+1)&&
                                g.getSp()[k].getCol()==(j+1))){
                            b=true;
                        }
                    }
                    if(b){
                        s[i][j]="~";
                     
                    }else{
                        s[i][j]="*";  //在不满足的地方存星,是为了防止图形位置改变时,原有位置还存在
                    
                    }   
                }
                }       
            }
        public void setS1(){ //   用于存不再受控制移动的图形
          for(int i=0;i<s.length;i++){
              for(int j=0;j<s[i].length;j++){
                  if(s[i][j]=="~"){
                      s1[i][j]=s[i][j];
                  }
              }
          }
        }
            
        
        public void print(){     //打印出的屏幕是不受控制的图形+正在受控制移动的图形
            for(int i=0;i<s.length;i++){
                for(int j=0;j<s[i].length;j++){
                    if(s1[i][j]=="~"){
                    System.out.print(s1[i][j]);
                }else{
                    System.out.print(s[i][j]);
                
                }
                }
                System.out.println();
            }
            
        }
        public String[][] getS() {
            return s;
        }
        public boolean have(){  //判断正在移动的图形和已经被存起来的图形是否重合
            for(int i=0;i<s.length;i++){
                for(int j=0;j<s[i].length;j++){
                    if(s[i][j]==s1[i][j]&&s[i][j]=="~"){ //在相同的且等于~就是图形重合
                        return true;
                    }
                }
            }
            return false;
            
        }
        public boolean full(){//判断最后一行是不是满的
            boolean a=true;
            for(int i=0;i<s1[14].length;i++){
                if(s1[14][i]=="*"){
                    a=false;
                    break;
                    
                }else{
                    a=true;
                }
            }
            return a;
        }
    
        public void delete(){  //删除最后一行
                for(int i=s1.length-1;i>0;i--){
                    for(int j=0;j<s1[i].length;j++){
                        s1[i][j]=s1[i-1][j];
                        
                    }       
            }
        }
      
    }
    
    
    

    测试类

    import java.util.*;
    public class Demo1 {
        public static void main(String[]args) throws InterruptedException{  
            Scanner in=new Scanner(System.in);
            Screen s=new Screen();
            while(true){
                T t=new T(3,3); 
            s.setS(t);  
            //s.print();
            out:while(true){  //不断移动
    
            System.out.println("1表示左移,2表示右移,3表示下移,4表示旋转");
            int a=in.nextInt(); 
            if(a==1){
                if(!t.judgeLeft()){  //如何没到达左侧边界,图形左移。
                    t.leftG(); 
                    s.setS(t);}   //存到屏幕对象的正在移动图形的数组里
                if(t.judgeLeft()){
                    t.rightG();  //但是左移后不一定到没到边界,这时要判断一下,到了边界之外右移回来
                    s.setS(t);
                }        
                    s.print(); //打印屏幕
                
            }else if(a==2){     //如何没到达右侧边界,图形左移被存到屏幕对象的正在移动图形的数组里
                if(!t.judgeRight()){
                    t.rightG();
                    s.setS(t);}
                if(t.judgeRight()){
                    t.leftG();  
                    s.setS(t);
                }
                    s.print();//打印屏幕
        
            }else if(a==3){
                if(!t.judgeBottom()&&!s.have()){   //没到底边界,并且没跟已有图形重合,下移
                    t.bottomG();
                    s.setS(t);}
                if(t.judgeBottom()||s.have()){   //如果下移后出了底边界,就上上移一下
                    t.topG();                       //并且把上移后的图形存到 到达地步的屏幕数组里
                    s.setS(t);
                    s.setS1();
                    while(true){
                        if(s.full()){ //如果最后一行满了
                            s.delete();   //消除最后一行
                        }else{              
                    s.print();   //打印出屏幕
                    break out;   //这时不断移动的循环接收,重新进入一个图形开始移动
                        }
                    }
                }
                    
                    s.print();    
                    
    
            }else if(a==4){     
                if(!t.judgeBottom()&&!t.judgeLeft()&&!t.judgeRight())//没到边界进行顺时针旋转
                {
                t.rotate();
                s.setS(t);
                }
                if(t.judgeBottom()||t.judgeLeft()||t.judgeRight()){   //旋转后出了边界进行逆时针旋转
                    t.rotate1();
                    s.setS(t);
                }
                s.print();      打印屏幕
            }
            }
    }
    }
    }
    
    
    

    相关文章

      网友评论

        本文标题:综合练习——简易俄罗斯方块

        本文链接:https://www.haomeiwen.com/subject/sarrvxtx.html