ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 22-09-20_python
    main 2022. 9. 20. 11:16

    --

    네트워크로 접속한 다른 사람의 테트리스 화면 그려주기 + 이기면 alert 띄워주기

     

    <html>
    <head>
    <title>테트리스</title>
    <style type="text/css">
       td{
          width: 20px;
          height: 20px;
       }
    z
    
    </style>
    <script type="text/javascript">
    class Block {
       constructor() {
          this.type = 2;
          this.status = 1;      //공통값이 1이..default니까..
                            //이번에 i가 회전 중심점
          this.i =2;
          this.j =2;
       }
    }
    
    //게임 진행여부 true면 진행하도록, false면 진행하지 않도록
    var flagIng = false;
    var b = new Block();
    
    var block2D =[
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0]
          
    ];
    
    var stack2D =[
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [1,0,0,0,0, 0,0,0,0,0],
          
          [1,1,0,0,0, 0,0,0,0,0],
          [1,1,1,1,1, 1,1,1,1,0],
          [1,1,1,1,1, 1,1,1,1,0],
          [1,1,1,1,1, 1,1,1,1,0],
          [1,1,1,1,1, 1,1,1,1,0]
          
    ];
    
    var scrin2D =[
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0]
          
    ];
    
    
    function setBlock2DFromBlock(){
       
       //시작하면서 초기화 해 줌 : 블럭을 이동할 때 마다 새로 그리니까, 이전 흔적이 남지 않음
       //지나간 흔적을 기본배경색으로 바꾸는 역할
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             block2D[i][j] = 0;
          }
       }
       
       //1번도형
       if(b.type ==1){
          block2D[b.i      ][b.j   ] = b.type;
          block2D[b.i      ][b.j+1   ] = b.type;
          block2D[b.i+1   ][b.j   ] = b.type;
          block2D[b.i+1   ][b.j+1   ] = b.type;
       }
       //2번도형
       if(b.type ==2){
          if(b.status ==1){      //가로 1자
             block2D[b.i   ][b.j-1   ] = b.type;
             block2D[b.i   ][b.j   ] = b.type;
             block2D[b.i   ][b.j+1   ] = b.type;
             block2D[b.i   ][b.j+2   ] = b.type;
          }
          if(b.status ==2){      //세로 1자
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+2   ][b.j   ] = b.type;
          }
       }
       //3번도형
       if(b.type ==3){
          if(b.status ==1){      
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j-1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
       }
       //4번도형
       if(b.type ==4){
          if(b.status ==1){      
             block2D   [b.i   ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i-1   ][b.j+1   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
       }
       //5번도형
       if(b.type ==5){
          if(b.status ==1){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i-1   ][b.j+1   ] = b.type;
          }
          if(b.status ==3){      
             block2D[b.i-1   ][b.j-1   ] = b.type;
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
          if(b.status ==4){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j-1   ] = b.type;
          }
       }
       //6번도형
       if(b.type ==6){
          if(b.status ==1){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i   ][b.j   ] = b.type;
             block2D[b.i+1      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j-1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
          if(b.status ==3){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i-1   ][b.j+1   ] = b.type;
          }
          if(b.status ==4){      
             block2D[b.i-1   ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
          }
          
       }
       //7번도형
       if(b.type ==7){
          if(b.status ==1){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
          }
          if(b.status ==3){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
          if(b.status ==4){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
       }
    }
    
    function setScrin2D(){
       //시작하면서 초기화 해 줌 : 블럭을 이동할 때 마다 새로 그리니까, 이전 흔적이 남지 않음
       //지나간 흔적을 기본배경색으로 바꾸는 역할
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             scrin2D[i][j] = 0;
          }
       }
       
       //block2D와 stack2D에 i,j값이 0보다 큰 경우에는 0이 아닌 값을 scrin2D에 넣어주기, 반복문
       //block의 것을 scrin에
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(block2D[i][j]>0){
                scrin2D[i][j] =block2D[i][j];
             }
          }
       }
       //stack의 것을 scrin에
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(stack2D[i][j]>0){
                scrin2D[i][j] =stack2D[i][j];
             }
          }
       }   
    }
    
    function myrender(){
    //tds를 불러와서 10진수를 이용하는 방법1, 이걸 선호
    //td2D를 만들어서 만들어 주는 방법2
    //색은 0, 1~7(살아있는 도형), 11~17(stack된 도형)
    
       var tds  = document.querySelectorAll(".mydisp");
    
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(scrin2D[i][j] == 0){
                
                      
                tds[i*10+j].style.backgroundColor = "white";
             }
             
             //살아있는 도형 색상
             if(scrin2D[i][j] == 1){
                tds[i*10+j].style.backgroundColor = "#2E9AFE";
             }      
             if(scrin2D[i][j] == 2){
                tds[i*10+j].style.backgroundColor = "#9F81F7";
             }      
             if(scrin2D[i][j] == 3){
                tds[i*10+j].style.backgroundColor = "#81F781";
             }      
             if(scrin2D[i][j] == 4){
                tds[i*10+j].style.backgroundColor = "#F5DA81";
             }      
             if(scrin2D[i][j] == 5){
                tds[i*10+j].style.backgroundColor = "#FE2E2E";
             }      
             if(scrin2D[i][j] == 6){
                tds[i*10+j].style.backgroundColor = "#FA58AC";
             }      
             if(scrin2D[i][j] == 7){
                tds[i*10+j].style.backgroundColor = "#FFFF00";
             }   
             
             //쌓인 도형 색상
             if(scrin2D[i][j] == 11){
                tds[i*10+j].style.backgroundColor = "#0040FF";
             }      
             if(scrin2D[i][j] == 12){
                tds[i*10+j].style.backgroundColor = "#9A2EFE";
             }      
             if(scrin2D[i][j] == 13){
                tds[i*10+j].style.backgroundColor = "#81F781";
             }      
             if(scrin2D[i][j] == 14){
                tds[i*10+j].style.backgroundColor = "#FFBF00";
             }      
             if(scrin2D[i][j] == 15){
                tds[i*10+j].style.backgroundColor = "#B40404";
             }      
             if(scrin2D[i][j] == 16){
                tds[i*10+j].style.backgroundColor = "#8A0868";
             }      
             if(scrin2D[i][j] == 17){
                tds[i*10+j].style.backgroundColor = "#AEB404";
             }      
    
          }
       }
    
    }
    
    window.addEventListener("keydown", (e) => 
    {   
       //키를 누르면 호출
       myclick(e);
    }
    );
    
    
    function isCrushWall(){
       //for문 돌려서 블럭의 갯수가 4개면 false ==충돌하지 않았다, 
       //4개가 아니면 true ==충돌했다 반환하는 거 짜보기
       //2중for문돌려서, 0보다 크면 false, 4보다 작으면 false
       
       var cnt = 0;
       
       //2중for문돌려서, 0보다 크면, count증가
          for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(block2D[i][j]>0){
                cnt++;
                   }
                }
             }
       if(cnt==4){ //for문 돌려서 블럭의 갯수가 4개면 false ==충돌하지 않았다, 
          return false; 
       }else{ //4개가 아니면 true ==충돌했다 반환하는 거 짜보기
          return true;
       }
       
    }
    
    function isCrushStack(){
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             //한 칸이 stack 값과 block값을 동시에 갖는 경우 ==충돌한 경우 
             if(block2D[i][j]>0 && stack2D[i][j]>0){
                return true;   //충돌했다
                   }
                }
             }
       return false;   //두개의 값을 동시에 갖지 않으면 ==충돌하지 않았다.
    }
    
    
    function moveBlock2DToStack2D(){
       //stack으로 이동하면서 색도 바꿔줘야 하고
       //stack으로 block을 이동도 시켜줘야함..
       
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
              
             //0보다 크면 i,j에 있는걸 이동시켜준다..
             if(block2D[i][j]>0){
                stack2D[i][j] = block2D[i][j]+10;
                   }
                }
             }
       
    }
    
    
    function myclick(e){
       console.log(e);
       if(!flagIng)
          return ;
       
       var bakType       = b.type;
       var bakStatus    = b.status;
       var baki        = b.i;
       var bakj        = b.j;
             
       flagDown = false;
       
       //The function of the Using direction key
       if (e.code == 'ArrowUp') {
           changeStatus();
        }
        if (e.code == 'ArrowDown') {
           b.i++;
           flagDown = true;
        }
        if (e.code == 'ArrowLeft') {
           b.j--;
        }
        if (e.code == 'ArrowRight') {
           b.j++;
        }
       
       //바닥과 부딛히는 경우의 변수 설정
       var flagUnder =false;
        
    //call functions
       //바닥을 뚫고 나가면 에러가 나니까 try-catch처리하고, error시 충돌했다는 true반환
       try {
          setBlock2DFromBlock();
       } catch (error){
          flagUnder = true;
       }
       
       
    //   console.log(block2D);
       setScrin2D();
    //   console.log(scrin2D);
    
       //벽과 충돌하는 경우를 정의하자, 충돌 안하는 경우가 많으니 기본값 false
       var flagWall = isCrushWall();
       // stack과 충돌하는 경우를 정의해보자
       var flagStack = isCrushStack();
       
       //충돌을 하나로 합침
       var flagCrush = flagWall || flagStack || flagUnder;
       
    //   console.log("flagCrush",flagCrush);
    
       //flagCrush가 true인 경우에 실행됨.
       if(flagCrush){
           b.type   = bakType;
           b.status = bakStatus;    
           b.i      = baki;
           b.j      = bakj;
           
          setBlock2DFromBlock();
          setScrin2D();
          
       }
       if(flagCrush && flagDown){
          moveBlock2DToStack2D();
          //stack2D의 5라인에 닿으면 게임종료되게
          //블럭이 천장까지 쌓이면 종료
          if(
             stack2D[5][0]>0   ||
             stack2D[5][1]>0   ||
             stack2D[5][2]>0   ||
             stack2D[5][3]>0   ||
             stack2D[5][4]>0   ||
             
             stack2D[5][5]>0   ||
             stack2D[5][6]>0   ||
             stack2D[5][7]>0   ||
             stack2D[5][8]>0   ||
             stack2D[5][9]>0   
          ){
             alert("게임에서 졌습니다.");
             flagIng = false;
          }
          
          
          //10개짜리인거 없애주겠습니다..
          
          //10개짜리가 몇개 있는지
          var cnt10 = getCnt10();
          
          var obj = document.querySelector("#my_mission");
          var int_mission = parseInt(obj.innerText);
          int_mission = int_mission - cnt10;
          obj.innerText = int_mission;
          if(int_mission<1){
             alert("게임에서 이겼습니다.");
             fn_win();
             flagIng = false;
          }
          
          
          remove10(cnt10);
          console.log("cnt10",cnt10)
          
          //b.type 하고 set...
           b.type   = parseInt(Math.random()*7)+1;
           b.status = 1;    
           b.i      = 1;
           b.j      = 5;
           setBlock2DFromBlock();
          setScrin2D();
       }
       //버튼 클릭할 때 마다 나의 상태가 변하는데, 그 나의 스크린을 보여 주어야 함. 
       //배열로 만들어 주는데, 문자열을 더해주면 ( +"") 문자열로 변함
       //몇 번째 캔버스인지 찾아서 그림그려주면 되져
       //함수에서 문자열 더해줘서, 2차원X, 1차원 배열로 넘어옴
       fn_myscreen();
       myrender();
       console.log(stack2D);
    }
    
    function remove10(cnt10){
       //stack2D비슷한거니까 s2D라고 명명해봅시다
       var s2D =[];
       for(var i=0; i<25; i++){          
          if(
                stack2D[i][0]>0   &&
                stack2D[i][1]>0   &&
                stack2D[i][2]>0   &&
                stack2D[i][3]>0   &&
                stack2D[i][4]>0   &&
                
                stack2D[i][5]>0   &&
                stack2D[i][6]>0   &&
                stack2D[i][7]>0   &&
                stack2D[i][8]>0   &&
                stack2D[i][9]>0   
          ){
             //pass
          }else{
        	  //보내는 데이터를 문자열로 바꿔줌
             s2D.push(stack2D[i]+"");
          }   
       }
       
       for(var i=0; i<cnt10;i++){
    	  //보내는 데이터를 문자열로 바꿔줌
          s2D.unshift([0,0,0,0,0, 0,0,0,0,0]+"");
          
       }
       
       //, 지워진거 뺸 채로 새로 그려주기
       for(var i=0; i<25; i++){
          stack2D[i][0] = parseInt(s2D[i].split(",")[0]);
          stack2D[i][1] = parseInt(s2D[i].split(",")[1]);
          stack2D[i][2] = parseInt(s2D[i].split(",")[2]);
          stack2D[i][3] = parseInt(s2D[i].split(",")[3]);
          stack2D[i][4] = parseInt(s2D[i].split(",")[4]);
          
          stack2D[i][5] = parseInt(s2D[i].split(",")[5]);
          stack2D[i][6] = parseInt(s2D[i].split(",")[6]);
          stack2D[i][7] = parseInt(s2D[i].split(",")[7]);
          stack2D[i][8] = parseInt(s2D[i].split(",")[8]);
          stack2D[i][9] = parseInt(s2D[i].split(",")[9]);
       }
       
       console.log("cnt10",cnt10);
       console.log("s2D",s2D);
       
    }
    
    function getCnt10(){
       //25번 돌아가면서 i의 모든 값이 0보다 크면 카운트..
       var cnt =0;
       for(var i=0; i<25; i++){          
             if(
                   stack2D[i][0]>0   &&
                   stack2D[i][1]>0   &&
                   stack2D[i][2]>0   &&
                   stack2D[i][3]>0   &&
                   stack2D[i][4]>0   &&
                   
                   stack2D[i][5]>0   &&
                   stack2D[i][6]>0   &&
                   stack2D[i][7]>0   &&
                   stack2D[i][8]>0   &&
                   stack2D[i][9]>0   
             ){
                cnt++;
                }   
       }
       
       return cnt;
    }
    
    //테트리스 도형 떨어지는 속도 (setTimeout에 miliseconds로 설정)
    function mytime(){
       myclick({code:'ArrowDown'});
       setTimeout(mytime,2000)
       
    }
    //onload함수로, 프로그램 실행하면 mytime이 자동으로 실행되게 함. (자동으로 블럭 내려가게)
    function myinit(){
       mytime();
       
    }
    
    // The function of the change figure status when press 'UP'key
    function changeStatus(){
       if(b.type == 2 || b.type ==3 || b.type==4){
          if(b.status==1){
             b.status =2;
          }else if(b.status==2){
             b.status=1;   
          }
       }
       if(b.type == 5 || b.type ==6 || b.type==7){
          if(b.status==1){
             b.status =2;
          }else if(b.status==2){
             b.status=3;   
          }else if(b.status==3){
             b.status=4;   
          }else if(b.status==4){
             b.status=1;   
          }
       }      
    }
    
    
    </script>
    </head>
    <body onload="myinit()">
    
    <table border="1px">
       <tr>
          <td style="width:280px;">
          <input style="width : 50px;" type="text" id="my_id">
          <input type="button" value="참가" onclick="fn_login()">
          <input type="button" value="게임시작" onclick="fn_start()""><br>
          
          Mission : <div id="my_mission">10</div>
          <table border="1px">
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
          </table>
          </td>
          
          <td>
             <table border="1px" style = "font-size: 7px;">
                <tr>
                <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                </tr>
                
                <tr>
                  <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>         
                </tr>
                
                <tr>
                <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                </tr>
                
                <tr>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>         
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                </tr>
                
             </table>
          </td>
       </tr>
    </table>
    
        {{ room_name|json_script:"room-name" }}
        <script>
        	// 네트워크 접속 관련 코드
            const roomName = JSON.parse(document.getElementById('room-name').textContent);
          
            var ws_url = 'ws://' + window.location.host + '/ws/chat/' + roomName + '/';
              
            console.log("ws_url",ws_url);
            
          //이거 선언 안 하면 메세지 안 감 
            //이제 기능에서의 핵심1
            const chatSocket = new WebSocket(ws_url);
    
            chatSocket.onclose = function(e) {
                console.error('Chat socket closed unexpectedly');
            };
                   //핵심, 받아오는거
            chatSocket.onmessage = function(e) {
                const data = JSON.parse(e.data);
                var message = data.message;
                //메세지 짤라줘야 함
                // ' : ' 을 기준으로 자르겠다 
                var arr_msg = message.split(":");
                // : 기준으로 0번째 방은 : 앞의 내용인 login start win 등...
                
                //로그인 하는 메서드 호출
                if(arr_msg[0]=="login"){
                   rev_login(arr_msg[1]);
                }
                //시작하는 메서드 호출
                if(arr_msg[0]=="start"){
                   rev_start();
                }
                //화면 공유해줌
                if(arr_msg[0]=="myscreen"){
                   rev_myscreen(arr_msg[1],arr_msg[2],arr_msg[3]);
                }
                // 승리 메서드 호출
                if(arr_msg[0]=="win"){
                    rev_win(arr_msg[1]);
                 }
            };
            
            //게임에서 승리하면 alert화면을 띄워주고, 게임진행을 멈춤
            function rev_win(winner_id){
               alert(winner_id+"가 이겼습니다.");
               flagIng = false;
            }
            
            //플레이어 간 화면 실시간으로 진행상황 공유해주는 메서드
            function rev_myscreen(my_id,screen_info,mission_info){
             var idx_dupl = -1;
                  for(var i=0; i<user_ids.length; i++){
                     if(user_ids[i]==my_id){
                        idx_dupl = i;
                        break;
                     }
                  }
                  var objs_mission = document.querySelectorAll(".user_mission");
                  objs_mission[idx_dupl].innerHTML = mission_info;
                  
                  var objs_can = document.querySelectorAll(".user_can");
                  var arr_screen = screen_info.split(",");
                  for (var i = 0; i < 25; i++) {
                 for (var j = 0; j < 10; j++) {
                    var ctx = objs_can[idx_dupl].getContext("2d");
                    if(arr_screen[i*10+j] == 0) ctx.fillStyle = 'white';
                    
                    if(arr_screen[i*10+j] == '1') ctx.fillStyle = '#2E9AFE';
                    if(arr_screen[i*10+j] == '2') ctx.fillStyle = '#9F81F7';
                    if(arr_screen[i*10+j] == '3') ctx.fillStyle = '#81F781';
                    if(arr_screen[i*10+j] == '4') ctx.fillStyle = '#F5DA81';
                    if(arr_screen[i*10+j] == '5') ctx.fillStyle = '#FE2E2E';
                    if(arr_screen[i*10+j] == '6') ctx.fillStyle = '#FA58AC';
                    if(arr_screen[i*10+j] == '7') ctx.fillStyle = '#FFFF00';
                    
                    if(arr_screen[i*10+j] == '11') ctx.fillStyle = '#0040FF';
                    if(arr_screen[i*10+j] == '12') ctx.fillStyle = '#9A2EFE';
                    if(arr_screen[i*10+j] == '13') ctx.fillStyle = '#81F781';
                    if(arr_screen[i*10+j] == '14') ctx.fillStyle = '#FFBF00';
                    if(arr_screen[i*10+j] == '15') ctx.fillStyle = '#B40404';
                    if(arr_screen[i*10+j] == '16') ctx.fillStyle = '#8A0868';
                    if(arr_screen[i*10+j] == '17') ctx.fillStyle = '#AEB404';
                         
                        ctx.fillRect(j*30, i*6, 29, 5);
                 }
              }
            }
            
            //게임 시작하는 메서드
            function rev_start(){
               flagIng = true;
            }
            
            var user_ids = [];
            function rev_login(my_id){
               console.log("my_id",my_id);
               
               //증복확인하자, ture, false보다는 -1반환하는 숫자로 하는게 낫다..?
               //indexOf가 못찾으면 -1 반환하는 것 처럼... 
               //논리적으로 왜 -1이 더 나은가
               var idx_dupl = -1;
               
               for(var i=0; i<user_ids.length; i++){
                  if(user_ids[i]==my_id){
                     idx_dupl =i;
                     break;
                  }
               }
               if(idx_dupl == -1){
                  user_ids.push(my_id);
               }
               console.log("idx_dupl",idx_dupl);
               
               var objs = document.querySelectorAll(".user_id");
               
               for(var i=0; i<user_ids.length; i++){
                  objs[i].innerHTML = user_ids[i]
               }
               
               
            }
          
            //이제 기능에서의 핵심2
    
            //아래 fn_ 함수들의 메시지를 알리는 함수
            function mysend(message){
               var json = {
                        'message': message
                    }
                    chatSocket.send(JSON.stringify(json));
            }
            
            
            //참여자의 화면을 우측 참여자 화면의 canvas tag에 그려주는 메서드, 점수도 넣어줘여
            function fn_myscreen(){
               var obj = document.querySelector("#my_id"); 
               var obj_mission = document.querySelector("#my_mission"); //나의 my_mission(id)
               var message = "myscreen:" + obj.value+":"+scrin2D+":"+obj_mission.innerHTML;
               
               mysend(message);
            }
            
            //승리하였음을 알리는 메서드
            function fn_win(){
               var obj = document.querySelector("#my_id");
               var message = "win:" + obj.value;
               mysend(message);
            }
            //참여하였음을 알리는 메서드
            function fn_login(){
               var obj = document.querySelector("#my_id");
               var message = "login:" + obj.value;
               mysend(message);
            }
            //게임 시작을 알리는 메서드
            function fn_start(){
               var message = "start";
               mysend(message);
            }
            
            
        </script>
        
    </body>
    </html>

    자세한 내용은 코드에 적힌 주석 참고.

     

     

    이제

     

    여기 탈락한 선생님들을 탈락했다고 표시하고 싶음

     -> 이름을 까맣게 하거나 배경을 까맣게 하거나 해서 표시를 하고 싶음..

     

    lose : 참여자이름

     

    보내면, 보낸 부분의 이름이 회색 톤으로 되게 하기.

     

    -->alert는 뜨지 않고 배경만 까맣게 바꿔주기. 

    (alert속성 중, 버튼을 안 누르면 다른 조작이 불가능 하니까)

     

    <html>
    <head>
    <title>테트리스</title>
    <style type="text/css">
       td{
          width: 20px;
          height: 20px;
       }
    z
    
    </style>
    <script type="text/javascript">
    class Block {
       constructor() {
          this.type = 2;
          this.status = 1;      //공통값이 1이..default니까..
                            //이번에 i가 회전 중심점
          this.i =2;
          this.j =2;
       }
    }
    
    //게임 진행여부 true면 진행하도록, false면 진행하지 않도록
    var flagIng = false;
    var b = new Block();
    
    var block2D =[
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0]
          
    ];
    
    var stack2D =[
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [1,0,0,0,0, 0,0,0,0,0],
          
          [1,1,0,0,0, 0,0,0,0,0],
          [1,1,1,1,1, 1,1,1,1,0],
          [1,1,1,1,1, 1,1,1,1,0],
          [1,1,1,1,1, 1,1,1,1,0],
          [1,1,1,1,1, 1,1,1,1,0]
          
    ];
    
    var scrin2D =[
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0],
          [0,0,0,0,0, 0,0,0,0,0]
          
    ];
    
    
    function setBlock2DFromBlock(){
       
       //시작하면서 초기화 해 줌 : 블럭을 이동할 때 마다 새로 그리니까, 이전 흔적이 남지 않음
       //지나간 흔적을 기본배경색으로 바꾸는 역할
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             block2D[i][j] = 0;
          }
       }
       
       //1번도형
       if(b.type ==1){
          block2D[b.i      ][b.j   ] = b.type;
          block2D[b.i      ][b.j+1   ] = b.type;
          block2D[b.i+1   ][b.j   ] = b.type;
          block2D[b.i+1   ][b.j+1   ] = b.type;
       }
       //2번도형
       if(b.type ==2){
          if(b.status ==1){      //가로 1자
             block2D[b.i   ][b.j-1   ] = b.type;
             block2D[b.i   ][b.j   ] = b.type;
             block2D[b.i   ][b.j+1   ] = b.type;
             block2D[b.i   ][b.j+2   ] = b.type;
          }
          if(b.status ==2){      //세로 1자
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+2   ][b.j   ] = b.type;
          }
       }
       //3번도형
       if(b.type ==3){
          if(b.status ==1){      
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j-1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
       }
       //4번도형
       if(b.type ==4){
          if(b.status ==1){      
             block2D   [b.i   ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i-1   ][b.j+1   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
       }
       //5번도형
       if(b.type ==5){
          if(b.status ==1){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i-1   ][b.j+1   ] = b.type;
          }
          if(b.status ==3){      
             block2D[b.i-1   ][b.j-1   ] = b.type;
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
          if(b.status ==4){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j-1   ] = b.type;
          }
       }
       //6번도형
       if(b.type ==6){
          if(b.status ==1){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i   ][b.j   ] = b.type;
             block2D[b.i+1      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j-1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j+1   ] = b.type;
          }
          if(b.status ==3){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i-1   ][b.j+1   ] = b.type;
          }
          if(b.status ==4){      
             block2D[b.i-1   ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
          }
          
       }
       //7번도형
       if(b.type ==7){
          if(b.status ==1){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
          }
          if(b.status ==2){      
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
          }
          if(b.status ==3){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i      ][b.j+1   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
          if(b.status ==4){      
             block2D[b.i      ][b.j-1   ] = b.type;
             block2D[b.i      ][b.j   ] = b.type;
             block2D[b.i-1   ][b.j   ] = b.type;
             block2D[b.i+1   ][b.j   ] = b.type;
          }
       }
    }
    
    function setScrin2D(){
       //시작하면서 초기화 해 줌 : 블럭을 이동할 때 마다 새로 그리니까, 이전 흔적이 남지 않음
       //지나간 흔적을 기본배경색으로 바꾸는 역할
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             scrin2D[i][j] = 0;
          }
       }
       
       //block2D와 stack2D에 i,j값이 0보다 큰 경우에는 0이 아닌 값을 scrin2D에 넣어주기, 반복문
       //block의 것을 scrin에
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(block2D[i][j]>0){
                scrin2D[i][j] =block2D[i][j];
             }
          }
       }
       //stack의 것을 scrin에
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(stack2D[i][j]>0){
                scrin2D[i][j] =stack2D[i][j];
             }
          }
       }   
    }
    
    function myrender(){
    //tds를 불러와서 10진수를 이용하는 방법1, 이걸 선호
    //td2D를 만들어서 만들어 주는 방법2
    //색은 0, 1~7(살아있는 도형), 11~17(stack된 도형)
    
       var tds  = document.querySelectorAll(".mydisp");
    
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(scrin2D[i][j] == 0){
                
                      
                tds[i*10+j].style.backgroundColor = "white";
             }
             
             //살아있는 도형 색상
             if(scrin2D[i][j] == 1){
                tds[i*10+j].style.backgroundColor = "#2E9AFE";
             }      
             if(scrin2D[i][j] == 2){
                tds[i*10+j].style.backgroundColor = "#9F81F7";
             }      
             if(scrin2D[i][j] == 3){
                tds[i*10+j].style.backgroundColor = "#81F781";
             }      
             if(scrin2D[i][j] == 4){
                tds[i*10+j].style.backgroundColor = "#F5DA81";
             }      
             if(scrin2D[i][j] == 5){
                tds[i*10+j].style.backgroundColor = "#FE2E2E";
             }      
             if(scrin2D[i][j] == 6){
                tds[i*10+j].style.backgroundColor = "#FA58AC";
             }      
             if(scrin2D[i][j] == 7){
                tds[i*10+j].style.backgroundColor = "#FFFF00";
             }   
             
             //쌓인 도형 색상
             if(scrin2D[i][j] == 11){
                tds[i*10+j].style.backgroundColor = "#0040FF";
             }      
             if(scrin2D[i][j] == 12){
                tds[i*10+j].style.backgroundColor = "#9A2EFE";
             }      
             if(scrin2D[i][j] == 13){
                tds[i*10+j].style.backgroundColor = "#81F781";
             }      
             if(scrin2D[i][j] == 14){
                tds[i*10+j].style.backgroundColor = "#FFBF00";
             }      
             if(scrin2D[i][j] == 15){
                tds[i*10+j].style.backgroundColor = "#B40404";
             }      
             if(scrin2D[i][j] == 16){
                tds[i*10+j].style.backgroundColor = "#8A0868";
             }      
             if(scrin2D[i][j] == 17){
                tds[i*10+j].style.backgroundColor = "#AEB404";
             }      
    
          }
       }
    
    }
    
    window.addEventListener("keydown", (e) => 
    {   
       //키를 누르면 호출
       myclick(e);
    }
    );
    
    
    function isCrushWall(){
       //for문 돌려서 블럭의 갯수가 4개면 false ==충돌하지 않았다, 
       //4개가 아니면 true ==충돌했다 반환하는 거 짜보기
       //2중for문돌려서, 0보다 크면 false, 4보다 작으면 false
       
       var cnt = 0;
       
       //2중for문돌려서, 0보다 크면, count증가
          for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             if(block2D[i][j]>0){
                cnt++;
                   }
                }
             }
       if(cnt==4){ //for문 돌려서 블럭의 갯수가 4개면 false ==충돌하지 않았다, 
          return false; 
       }else{ //4개가 아니면 true ==충돌했다 반환하는 거 짜보기
          return true;
       }
       
    }
    
    function isCrushStack(){
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
             //한 칸이 stack 값과 block값을 동시에 갖는 경우 ==충돌한 경우 
             if(block2D[i][j]>0 && stack2D[i][j]>0){
                return true;   //충돌했다
                   }
                }
             }
       return false;   //두개의 값을 동시에 갖지 않으면 ==충돌하지 않았다.
    }
    
    
    function moveBlock2DToStack2D(){
       //stack으로 이동하면서 색도 바꿔줘야 하고
       //stack으로 block을 이동도 시켜줘야함..
       
       for(var i=0; i<25; i++){
          for(var j=0;j<10;j++){
              
             //0보다 크면 i,j에 있는걸 이동시켜준다..
             if(block2D[i][j]>0){
                stack2D[i][j] = block2D[i][j]+10;
                   }
                }
             }
       
    }
    
    
    function myclick(e){
       console.log(e);
       if(!flagIng)
          return ;
       
       var bakType       = b.type;
       var bakStatus    = b.status;
       var baki        = b.i;
       var bakj        = b.j;
             
       flagDown = false;
       
       //The function of the Using direction key
       if (e.code == 'ArrowUp') {
           changeStatus();
        }
        if (e.code == 'ArrowDown') {
           b.i++;
           flagDown = true;
        }
        if (e.code == 'ArrowLeft') {
           b.j--;
        }
        if (e.code == 'ArrowRight') {
           b.j++;
        }
       
       //바닥과 부딛히는 경우의 변수 설정
       var flagUnder =false;
        
    //call functions
       //바닥을 뚫고 나가면 에러가 나니까 try-catch처리하고, error시 충돌했다는 true반환
       try {
          setBlock2DFromBlock();
       } catch (error){
          flagUnder = true;
       }
       
       
    //   console.log(block2D);
       setScrin2D();
    //   console.log(scrin2D);
    
       //벽과 충돌하는 경우를 정의하자, 충돌 안하는 경우가 많으니 기본값 false
       var flagWall = isCrushWall();
       // stack과 충돌하는 경우를 정의해보자
       var flagStack = isCrushStack();
       
       //충돌을 하나로 합침
       var flagCrush = flagWall || flagStack || flagUnder;
       
    //   console.log("flagCrush",flagCrush);
    
       //flagCrush가 true인 경우에 실행됨.
       if(flagCrush){
           b.type   = bakType;
           b.status = bakStatus;    
           b.i      = baki;
           b.j      = bakj;
           
          setBlock2DFromBlock();
          setScrin2D();
          
       }
       if(flagCrush && flagDown){
          moveBlock2DToStack2D();
          //stack2D의 5라인에 닿으면 게임종료되게
          //블럭이 천장까지 쌓이면 종료
          if(
             stack2D[5][0]>0   ||
             stack2D[5][1]>0   ||
             stack2D[5][2]>0   ||
             stack2D[5][3]>0   ||
             stack2D[5][4]>0   ||
             
             stack2D[5][5]>0   ||
             stack2D[5][6]>0   ||
             stack2D[5][7]>0   ||
             stack2D[5][8]>0   ||
             stack2D[5][9]>0   
          ){
             alert("게임에서 졌습니다.");
             fn_lose();
             flagIng = false;
          }
          
          
          //10개짜리인거 없애주겠습니다..
          
          //10개짜리가 몇개 있는지
          var cnt10 = getCnt10();
          
          var obj = document.querySelector("#my_mission");
          var int_mission = parseInt(obj.innerText);
          int_mission = int_mission - cnt10;
          obj.innerText = int_mission;
          if(int_mission<1){
             alert("게임에서 이겼습니다.");
             fn_win();
             flagIng = false;
          }
          
          
          remove10(cnt10);
          console.log("cnt10",cnt10)
          
          //b.type 하고 set...
           b.type   = parseInt(Math.random()*7)+1;
           b.status = 1;    
           b.i      = 1;
           b.j      = 5;
           setBlock2DFromBlock();
          setScrin2D();
       }
       //버튼 클릭할 때 마다 나의 상태가 변하는데, 그 나의 스크린을 보여 주어야 함. 
       //배열로 만들어 주는데, 문자열을 더해주면 ( +"") 문자열로 변함
       //몇 번째 캔버스인지 찾아서 그림그려주면 되져
       //함수에서 문자열 더해줘서, 2차원X, 1차원 배열로 넘어옴
       fn_myscreen();
       myrender();
       console.log(stack2D);
    }
    
    function remove10(cnt10){
       //stack2D비슷한거니까 s2D라고 명명해봅시다
       var s2D =[];
       for(var i=0; i<25; i++){          
          if(
                stack2D[i][0]>0   &&
                stack2D[i][1]>0   &&
                stack2D[i][2]>0   &&
                stack2D[i][3]>0   &&
                stack2D[i][4]>0   &&
                
                stack2D[i][5]>0   &&
                stack2D[i][6]>0   &&
                stack2D[i][7]>0   &&
                stack2D[i][8]>0   &&
                stack2D[i][9]>0   
          ){
             //pass
          }else{
        	  //보내는 데이터를 문자열로 바꿔줌
             s2D.push(stack2D[i]+"");
          }   
       }
       
       for(var i=0; i<cnt10;i++){
    	  //보내는 데이터를 문자열로 바꿔줌
          s2D.unshift([0,0,0,0,0, 0,0,0,0,0]+"");
          
       }
       
       //, 지워진거 뺸 채로 새로 그려주기
       for(var i=0; i<25; i++){
          stack2D[i][0] = parseInt(s2D[i].split(",")[0]);
          stack2D[i][1] = parseInt(s2D[i].split(",")[1]);
          stack2D[i][2] = parseInt(s2D[i].split(",")[2]);
          stack2D[i][3] = parseInt(s2D[i].split(",")[3]);
          stack2D[i][4] = parseInt(s2D[i].split(",")[4]);
          
          stack2D[i][5] = parseInt(s2D[i].split(",")[5]);
          stack2D[i][6] = parseInt(s2D[i].split(",")[6]);
          stack2D[i][7] = parseInt(s2D[i].split(",")[7]);
          stack2D[i][8] = parseInt(s2D[i].split(",")[8]);
          stack2D[i][9] = parseInt(s2D[i].split(",")[9]);
       }
       
       console.log("cnt10",cnt10);
       console.log("s2D",s2D);
       
    }
    
    function getCnt10(){
       //25번 돌아가면서 i의 모든 값이 0보다 크면 카운트..
       var cnt =0;
       for(var i=0; i<25; i++){          
             if(
                   stack2D[i][0]>0   &&
                   stack2D[i][1]>0   &&
                   stack2D[i][2]>0   &&
                   stack2D[i][3]>0   &&
                   stack2D[i][4]>0   &&
                   
                   stack2D[i][5]>0   &&
                   stack2D[i][6]>0   &&
                   stack2D[i][7]>0   &&
                   stack2D[i][8]>0   &&
                   stack2D[i][9]>0   
             ){
                cnt++;
                }   
       }
       
       return cnt;
    }
    
    //테트리스 도형 떨어지는 속도 (setTimeout에 miliseconds로 설정)
    function mytime(){
       myclick({code:'ArrowDown'});
       setTimeout(mytime,2000)
       
    }
    //onload함수로, 프로그램 실행하면 mytime이 자동으로 실행되게 함. (자동으로 블럭 내려가게)
    function myinit(){
       mytime();
       
    }
    
    // The function of the change figure status when press 'UP'key
    function changeStatus(){
       if(b.type == 2 || b.type ==3 || b.type==4){
          if(b.status==1){
             b.status =2;
          }else if(b.status==2){
             b.status=1;   
          }
       }
       if(b.type == 5 || b.type ==6 || b.type==7){
          if(b.status==1){
             b.status =2;
          }else if(b.status==2){
             b.status=3;   
          }else if(b.status==3){
             b.status=4;   
          }else if(b.status==4){
             b.status=1;   
          }
       }      
    }
    
    
    </script>
    </head>
    <body onload="myinit()">
    
    <table border="1px">
       <tr>
          <td style="width:280px;">
          <input style="width : 50px;" type="text" id="my_id">
          <input type="button" value="참가" onclick="fn_login()">
          <input type="button" value="게임시작" onclick="fn_start()""><br>
          
          Mission : <div id="my_mission">10</div>
          <table border="1px">
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
             <tr>
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
                <td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" /><td class="mydisp" />
             </tr>
          </table>
          </td>
          
          <td>
             <table border="1px" style = "font-size: 7px;">
                <tr>
                <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                </tr>
                
                <tr>
                  <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>         
                </tr>
                
                <tr>
                <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                </tr>
                
                <tr>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>
             <td style="width:50px"><span class="user_id"></span> <span class="user_mission"></span></td>         
                </tr>
                
                <tr>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                <td style="width:50px"><canvas style="width:50px; height :125px;" class="user_can"></canvas></td>
                </tr>
                
             </table>
          </td>
       </tr>
    </table>
    
        {{ room_name|json_script:"room-name" }}
        <script>
        	// 네트워크 접속 관련 코드
            const roomName = JSON.parse(document.getElementById('room-name').textContent);
          
            var ws_url = 'ws://' + window.location.host + '/ws/chat/' + roomName + '/';
              
            console.log("ws_url",ws_url);
            
          //이거 선언 안 하면 메세지 안 감 
            //이제 기능에서의 핵심1
            const chatSocket = new WebSocket(ws_url);
    
            chatSocket.onclose = function(e) {
                console.error('Chat socket closed unexpectedly');
            };
                   //핵심, 받아오는거
            chatSocket.onmessage = function(e) {
                const data = JSON.parse(e.data);
                var message = data.message;
                //메세지 짤라줘야 함
                // ' : ' 을 기준으로 자르겠다 
                var arr_msg = message.split(":");
                // : 기준으로 0번째 방은 : 앞의 내용인 login start win 등...
                
                //로그인 하는 메서드 호출
                if(arr_msg[0]=="login"){
                   rev_login(arr_msg[1]);
                }
                //시작하는 메서드 호출
                if(arr_msg[0]=="start"){
                   rev_start();
                }
                //화면 공유해줌
                if(arr_msg[0]=="myscreen"){
                   rev_myscreen(arr_msg[1],arr_msg[2],arr_msg[3]);
                }
                // 승리 메서드 호출
                if(arr_msg[0]=="win"){
                    rev_win(arr_msg[1]);
                 }
               //패함 알림 메서드 호출
                if(arr_msg[0]=="lose"){
                	rev_lose(arr_msg[1]);
                }
            };
            
            
            function rev_lose(my_id){
                var idx_dupl = -1;
                     for(var i=0; i<user_ids.length; i++){
                        if(user_ids[i]==my_id){
                           idx_dupl = i;
                           break;
                        }
                     }
                var objs = document.querySelectorAll(".user_id");
                objs[idx_dupl].style.backgroundColor = "red";
            }
            
            //게임에서 승리하면 alert화면을 띄워주고, 게임진행을 멈춤
            function rev_win(winner_id){
               alert(winner_id+"가 이겼습니다.");
               flagIng = false;
            }
            
            //플레이어 간 화면 실시간으로 진행상황 공유해주는 메서드
            function rev_myscreen(my_id,screen_info,mission_info){
             var idx_dupl = -1;
                  for(var i=0; i<user_ids.length; i++){
                     if(user_ids[i]==my_id){
                        idx_dupl = i;
                        break;
                     }
                  }
                  var objs_mission = document.querySelectorAll(".user_mission");
                  objs_mission[idx_dupl].innerHTML = mission_info;
                  
                  var objs_can = document.querySelectorAll(".user_can");
                  var arr_screen = screen_info.split(",");
                  for (var i = 0; i < 25; i++) {
                 for (var j = 0; j < 10; j++) {
                    var ctx = objs_can[idx_dupl].getContext("2d");
                    if(arr_screen[i*10+j] == 0) ctx.fillStyle = 'white';
                    
                    if(arr_screen[i*10+j] == '1') ctx.fillStyle = '#2E9AFE';
                    if(arr_screen[i*10+j] == '2') ctx.fillStyle = '#9F81F7';
                    if(arr_screen[i*10+j] == '3') ctx.fillStyle = '#81F781';
                    if(arr_screen[i*10+j] == '4') ctx.fillStyle = '#F5DA81';
                    if(arr_screen[i*10+j] == '5') ctx.fillStyle = '#FE2E2E';
                    if(arr_screen[i*10+j] == '6') ctx.fillStyle = '#FA58AC';
                    if(arr_screen[i*10+j] == '7') ctx.fillStyle = '#FFFF00';
                    
                    if(arr_screen[i*10+j] == '11') ctx.fillStyle = '#0040FF';
                    if(arr_screen[i*10+j] == '12') ctx.fillStyle = '#9A2EFE';
                    if(arr_screen[i*10+j] == '13') ctx.fillStyle = '#81F781';
                    if(arr_screen[i*10+j] == '14') ctx.fillStyle = '#FFBF00';
                    if(arr_screen[i*10+j] == '15') ctx.fillStyle = '#B40404';
                    if(arr_screen[i*10+j] == '16') ctx.fillStyle = '#8A0868';
                    if(arr_screen[i*10+j] == '17') ctx.fillStyle = '#AEB404';
                         
                        ctx.fillRect(j*30, i*6, 29, 5);
                 }
              }
            }
            
            //게임 시작하는 메서드
            function rev_start(){
               flagIng = true;
            }
            
            var user_ids = [];
            function rev_login(my_id){
               console.log("my_id",my_id);
               
               //증복확인하자, ture, false보다는 -1반환하는 숫자로 하는게 낫다..?
               //indexOf가 못찾으면 -1 반환하는 것 처럼... 
               //논리적으로 왜 -1이 더 나은가
               var idx_dupl = -1;
               
               for(var i=0; i<user_ids.length; i++){
                  if(user_ids[i]==my_id){
                     idx_dupl =i;
                     break;
                  }
               }
               if(idx_dupl == -1){
                  user_ids.push(my_id);
               }
               console.log("idx_dupl",idx_dupl);
               
               var objs = document.querySelectorAll(".user_id");
               
               for(var i=0; i<user_ids.length; i++){
                  objs[i].innerHTML = user_ids[i]
               }
               
               
            }
          
            //이제 기능에서의 핵심2
    
            //아래 fn_ 함수들의 메시지를 알리는 함수
            function mysend(message){
               var json = {
                        'message': message
                    }
                    chatSocket.send(JSON.stringify(json));
            }
            
            
            //참여자의 화면을 우측 참여자 화면의 canvas tag에 그려주는 메서드, 점수도 넣어줘여
            function fn_myscreen(){
               var obj = document.querySelector("#my_id"); 
               var obj_mission = document.querySelector("#my_mission"); //나의 my_mission(id)
               var message = "myscreen:" + obj.value+":"+scrin2D+":"+obj_mission.innerHTML;
               
               mysend(message);
            }
            
            //승리하였음을 알리는 메서드
            function fn_win(){
               var obj = document.querySelector("#my_id");
               var message = "win:" + obj.value;
               mysend(message);
            }
            //참여하였음을 알리는 메서드
            function fn_login(){
               var obj = document.querySelector("#my_id");
               var message = "login:" + obj.value;
               mysend(message);
            }
            //게임 시작을 알리는 메서드
            function fn_start(){
               var message = "start";
               mysend(message);
            }
            //게임에서 패했음을 알리는 메서드
            function fn_lose(){
                var obj = document.querySelector("#my_id");
                var message = "lose:" + obj.value;
                mysend(message);
             }
            
            
        </script>
        
    </body>
    </html>

    패함 알림 메서드 추가하고 적용함....

     

     

    심심하니까 도형 떨어지는 속도를 랜덤으로 해보자

     

    //테트리스 도형 떨어지는 속도 (setTimeout에 miliseconds로 설정)
    function mytime(){
    	myclick({code:'ArrowDown'});
    	//setTimeout(mytime,2000);
    	  
    	
    	//시간을 랜덤으로 0.1 ~ 2초 사이로 줄까? 100~2000까지 Math.random으로 짜보자.
    	var speed = parseInt(Math.random()*1900)+100; 
    	setTimeout(mytime,speed);	   
    			   
       
    }

     

    그러면 이제 온라인으로 해볼거예요

    이렇게 가능하죠

     

    다른 사람이 지면 이름이 빨간색으로 뜸

     

     

    예에ㅔㅔㅔ이김

     

     

    장고 말고 다른거로도 해봄^0^

    'main' 카테고리의 다른 글

    22-09-21_jsp(1)  (0) 2022.09.21
    22-09-20_jsp  (2) 2022.09.20
    22-09-19_jsp  (2) 2022.09.19
    22-09-19_python  (0) 2022.09.19
    22-09-16_jsp  (4) 2022.09.16
Designed by Tistory.