| 
				   | 
				
| Line 1: | 
Line 1: | 
 | Even Tetris can be implemented with JSXGraph.
  |  | 
 | <html>
  |  | 
 | <script type="text/javascript" src="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraphcore.js"></script>
  |  | 
 |         <style type="text/css">
  |  | 
 |            .jxgbox {
  |  | 
 |             overflow:hidden;
  |  | 
 |             background-color:#ffffff;
  |  | 
 |             border-style:solid;
  |  | 
 |             border-width:2px;
  |  | 
 |             border-color:#000000;
  |  | 
 |            }
  |  | 
 |            body {
  |  | 
 |             font-family:Arial;
  |  | 
 |            }
  |  | 
 |         </style> 
  |  | 
 | 
  |  | 
  | 
 |   <script type="text/javascript">
  |  | 
 |     /* <![CDATA[ */
  |  | 
 |     var started = false;
  |  | 
 |     var board = JXG.JSXGraph.initBoard('jxgbox', {originX: 0, originY: 500, unitX: 25, unitY: 25, showCopyright:false, showNavigation:false}); // Spielfeld 10x20
  |  | 
 |     var board2 = JXG.JSXGraph.initBoard('jxgbox2', {originX: 0, originY: 125, unitX: 25, unitY: 25, showCopyright:false, showNavigation:false});
  |  | 
 |     var usedPolys = new Array(10);
  |  | 
 |     var i,j;
  |  | 
 |     for(i=0;i<10;i++) {
  |  | 
 |         usedPolys[i] = new Array(20);
  |  | 
 |         for(j=0;j<20;j++) {
  |  | 
 |             usedPolys[i][j] = 0;
  |  | 
 |         }
  |  | 
 |     }
  |  | 
 |     var colors = ['none','#DC143C','#FF8C00','#87CEEB','#FFD700','#4B0082','#0000CD','#32CD32'];
  |  | 
 |     
  |  | 
 |     function drawPointsAndPolys(board,width,height,vorschau) {
  |  | 
 |         var i,j,pArr = {};
  |  | 
 |         board.suspendUpdate();
  |  | 
 |         for(i=0;i<=width;i++) {
  |  | 
 |             for(j=0; j<=height;j++) {
  |  | 
 |                 pArr[i+''+j] = board.createElement('point',[i,j],{withLabel:false,face:'plus',draft:true});
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         for(i=0;i<width;i++) {
  |  | 
 |             for(j=0; j<height;j++) {
  |  | 
 |                 var idpoly = 'poly_'+i+'_'+j;
  |  | 
 |                 if(vorschau) {
  |  | 
 |                     idpoly = 'poly_'+i+'_'+j+'_v';
  |  | 
 |                 }
  |  | 
 |                 var poly = board.createElement('polygon',
  |  | 
 |                                        [pArr[i+''+j], pArr[(i+1)+''+j], pArr[(i+1)+''+(j+1)], pArr[i+''+(j+1)]],
  |  | 
 |                                        {fillColor:'white',visible:false,id:idpoly});
  |  | 
 |                 for(k=0;k<4;k++) {
  |  | 
 |                     poly.borders[k].setProperty('strokeColor:#666666');
  |  | 
 |                 } 
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         board.unsuspendUpdate();
  |  | 
 |         return pArr;
  |  | 
 |     }    
  |  | 
 |     
  |  | 
 |     function shape(style) {
  |  | 
 |         if(style == 1) { // I
  |  | 
 |             return {face:[[1,1,1,1],[0,0,0,0],[0,0,0,0],[0,0,0,0]],size:4};
  |  | 
 |         }
  |  | 
 |         else if(style == 2) { // T
  |  | 
 |             return {face:[[2,0,0],[2,2,0],[2,0,0]],size:3};
  |  | 
 |         }
  |  | 
 |         else if(style == 3) { // O
  |  | 
 |             return {face:[[3,3],[3,3]],size:2};
  |  | 
 |         }
  |  | 
 |         else if(style == 4) { // L
  |  | 
 |             return {face:[[4,4,4],[4,0,0],[0,0,0]],size:3};
  |  | 
 |         }      
  |  | 
 |         else if(style == 5) { // J
  |  | 
 |             return {face:[[5,0,0],[5,5,5],[0,0,0]],size:3};
  |  | 
 |         }
  |  | 
 |         else if(style == 6) { // S
  |  | 
 |             return {face:[[6,0,0],[6,6,0],[0,6,0]],size:3};
  |  | 
 |         }  
  |  | 
 |         else if(style == 7) { // Z
  |  | 
 |             return {face:[[0,7,0],[7,7,0],[7,0,0]],size:3};
  |  | 
 |         }          
  |  | 
 |     }    
  |  | 
 |     
  |  | 
 |     function compareWithAbsoluteShape(s,posX,posY) {
  |  | 
 |         for(i=0;i<s.size;i++) {
  |  | 
 |             for(j=0;j<s.size;j++) {
  |  | 
 |                 if(s.face[i][j] != 0) {
  |  | 
 |                     if(i+posX < 0 || i+posX > 9) {
  |  | 
 |                         return false;
  |  | 
 |                     }
  |  | 
 |                     if(j+posY < 0 || j+posY > 19) {
  |  | 
 |                         return false;
  |  | 
 |                     }                    
  |  | 
 |                     if(usedPolys[i+posX][j+posY] == 1) {
  |  | 
 |                         return false;
  |  | 
 |                     }
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         return true;
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function drawShape(s,posX,posY) {
  |  | 
 |         board.suspendUpdate();
  |  | 
 |         var i,j;
  |  | 
 |         for(i=0;i<s.size;i++) {
  |  | 
 |             for(j=0;j<s.size;j++) {
  |  | 
 |                 if(s.face[i][j] != 0) {
  |  | 
 |                     showCube(i+posX,j+posY,colors[s.face[i][j]]);
  |  | 
 |                     usedPolys[i+posX][j+posY] = 1;
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         board.unsuspendUpdate();             
  |  | 
 |         return {shape:s,x:posX,y:posY};
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function removeShape(s,posX,posY) {
  |  | 
 |         board.suspendUpdate();
  |  | 
 |         var i,j, shape = new Array();
  |  | 
 |         for(i=0;i<s.size;i++) {
  |  | 
 |             for(j=0;j<s.size;j++) {
  |  | 
 |                 if(s.face[i][j] != 0) {
  |  | 
 |                     hideCube(i+posX,j+posY);
  |  | 
 |                     usedPolys[i+posX][j+posY] = 0;
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         board.unsuspendUpdate();        
  |  | 
 |         return {shape:s,x:posX,y:posY};
  |  | 
 |     } 
  |  | 
 |     
  |  | 
 |     function drawVorschauShape(s,posX,posY) {
  |  | 
 |         board2.suspendUpdate();
  |  | 
 |         var i,j;
  |  | 
 |         for(i=0;i<s.size;i++) {
  |  | 
 |             for(j=0;j<s.size;j++) {
  |  | 
 |                 if(s.face[i][j] != 0) {
  |  | 
 |                     showCubeV(i+posX,j+posY,colors[s.face[i][j]]);
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         board2.unsuspendUpdate();
  |  | 
 |     } 
  |  | 
 | 
  |  | 
 |     function clearVorschau() {
  |  | 
 |         for(i=0;i<5;i++) {
  |  | 
 |             for(j=0;j<5;j++) {
  |  | 
 |                 hideCubeV(i,j);
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |     }
  |  | 
 | 
  |  | 
 |     function showCube(posX,posY,color) {
  |  | 
 |         board.objects['poly_'+posX+'_'+posY].setProperty('visible:true');
  |  | 
 |         board.objects['poly_'+posX+'_'+posY].setProperty('fillColor:'+color);
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function hideCube(posX,posY) {
  |  | 
 |         board.objects['poly_'+posX+'_'+posY].setProperty('visible:false');
  |  | 
 |     }   
  |  | 
 |     
  |  | 
 |     function showCubeV(posX,posY,color) {
  |  | 
 |         board2.objects['poly_'+posX+'_'+posY+'_v'].setProperty('visible:true');
  |  | 
 |         board2.objects['poly_'+posX+'_'+posY+'_v'].setProperty('fillColor:'+color);
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function hideCubeV(posX,posY) {
  |  | 
 |         board2.objects['poly_'+posX+'_'+posY+'_v'].setProperty('visible:false');
  |  | 
 |     } 
  |  | 
 |     
  |  | 
 |     function rotate(shape) { // gegen den Uhrzeigersinn drehen
  |  | 
 |         if(shape.size == 2) {
  |  | 
 |             shape.face = [[shape.face[0][1],shape.face[1][1]],
  |  | 
 |                           [shape.face[0][0],shape.face[1][1]]];
  |  | 
 |         }
  |  | 
 |         else if(shape.size == 3) {
  |  | 
 |             shape.face = [[shape.face[0][2],shape.face[1][2],shape.face[2][2]],
  |  | 
 |                           [shape.face[0][1],shape.face[1][1],shape.face[2][1]],
  |  | 
 |                           [shape.face[0][0],shape.face[1][0],shape.face[2][0]]];
  |  | 
 |         }
  |  | 
 |         else if(shape.size == 4) {
  |  | 
 |             shape.face = [[shape.face[0][3],shape.face[1][3],shape.face[2][3],shape.face[3][3]],
  |  | 
 |                           [shape.face[0][2],shape.face[1][2],shape.face[2][2],shape.face[3][2]],
  |  | 
 |                           [shape.face[0][1],shape.face[1][1],shape.face[2][1],shape.face[3][1]],
  |  | 
 |                           [shape.face[0][0],shape.face[1][0],shape.face[2][0],shape.face[3][0]]];
  |  | 
 |         }          
  |  | 
 |         return shape;
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function getRandom() {
  |  | 
 |         return parseInt(1+Math.random()*7);
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function testLine(i) {
  |  | 
 |         var j;
  |  | 
 |         for(j=0; j<10; j++) {
  |  | 
 |             if(usedPolys[j][i] == 0) {
  |  | 
 |                 return false;
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         return true;
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function testLines() {
  |  | 
 |         var i, arr = new Array();
  |  | 
 |         for(i=0; i<20; i++) {
  |  | 
 |             if(testLine(i)) {
  |  | 
 |                 arr.push(i);
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         return arr;
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     /* doesn't work properly */
  |  | 
 |     function removeLines() {
  |  | 
 |         var arr = testLines(),i,j,k, line;
  |  | 
 |         if(arr.length > 0) {
  |  | 
 |             board.suspendUpdate();
  |  | 
 |             if(arr.length == 1) {
  |  | 
 |                 score += (level+1)*40;
  |  | 
 |             }
  |  | 
 |             else if(arr.length == 2) {
  |  | 
 |                 score += (level+1)*100;
  |  | 
 |             }
  |  | 
 |             else if(arr.length == 3) {
  |  | 
 |                 score += (level+1)*300;
  |  | 
 |             }
  |  | 
 |             else if(arr.length == 4) {
  |  | 
 |                 score += (level+1)*1200;
  |  | 
 |             }     
  |  | 
 |             scoreNode.innerHTML = score;             
  |  | 
 |             for(i=0;i<arr.length;i++) {
  |  | 
 |                 line = arr[i];
  |  | 
 |                 for(j=line+1-i;j<20;j++) {
  |  | 
 |                     for(k=0;k<10;k++) {
  |  | 
 |                         if(usedPolys[k][j] == 1) {
  |  | 
 |                             showCube(k,j-1,board.objects['poly_'+k+'_'+j].visProp['fillColor']);
  |  | 
 |                             usedPolys[k][j-1] = 1;
  |  | 
 |                             hideCube(k,j);
  |  | 
 |                             usedPolys[k][j] = 0;
  |  | 
 |                         }
  |  | 
 |                         else {
  |  | 
 |                             hideCube(k,j-1);
  |  | 
 |                             usedPolys[k][j-1] = 0;
  |  | 
 |                         }
  |  | 
 |                     }
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |             board.unsuspendUpdate();
  |  | 
 |         }
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function keyDown(Evt) {
  |  | 
 |         var code;
  |  | 
 |         if (!Evt) {
  |  | 
 |             Evt = window.event;
  |  | 
 |         }
  |  | 
 |         if (Evt.which) {
  |  | 
 |             code = Evt.which;
  |  | 
 |         } else if (Evt.keyCode) {
  |  | 
 |             code = Evt.keyCode;
  |  | 
 |         }
  |  | 
 |         // 37: left,  38: up,  39: right,  40: down
  |  | 
 |         if (code==38) { 
  |  | 
 |             removeShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             // echte Kopie anlegen...
  |  | 
 |             var s = {};
  |  | 
 |             s.size = curShape.shape.size;
  |  | 
 |             s.face = (new Array()).concat(curShape.shape.face);
  |  | 
 |             if(compareWithAbsoluteShape(rotate(s),curShape.x,curShape.y)) {
  |  | 
 |                 curShape = drawShape(rotate(curShape.shape),curShape.x,curShape.y);
  |  | 
 |             }
  |  | 
 |             else {
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             }
  |  | 
 |             return false;
  |  | 
 |         }
  |  | 
 |         else if(code==39) {
  |  | 
 |             removeShape(curShape.shape,curShape.x,curShape.y);        
  |  | 
 |             if(compareWithAbsoluteShape(curShape.shape,curShape.x+1,curShape.y)) {        
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x+1,curShape.y);
  |  | 
 |             }
  |  | 
 |             else {
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             }
  |  | 
 |             return false;
  |  | 
 |         }
  |  | 
 |         else if(code==37) {
  |  | 
 |             removeShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             if(compareWithAbsoluteShape(curShape.shape,curShape.x-1,curShape.y)) {         
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x-1,curShape.y);
  |  | 
 |             }
  |  | 
 |             else {
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             }
  |  | 
 |             return false;
  |  | 
 |         }    
  |  | 
 |         else if(code==40) {
  |  | 
 |             removeShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             if(compareWithAbsoluteShape(curShape.shape,curShape.x,curShape.y-1)) {           
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x,curShape.y-1);
  |  | 
 |                 score += (level + 1);
  |  | 
 |                 scoreNode.innerHTML = score;
  |  | 
 |             }
  |  | 
 |             else {
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             }
  |  | 
 |             return false;
  |  | 
 |         } 
  |  | 
 |         else if(code==32) { // Space
  |  | 
 |             if(curShape.y > 0) {
  |  | 
 |                 removeShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |                 var i=curShape.y-1; 
  |  | 
 |                 var min = curShape.y;
  |  | 
 |                 while(i>=0) {
  |  | 
 |                     if(compareWithAbsoluteShape(curShape.shape,curShape.x,i)) {           
  |  | 
 |                         min = i
  |  | 
 |                     }
  |  | 
 |                     else {
  |  | 
 |                         i=0;
  |  | 
 |                     }
  |  | 
 |                     i--;
  |  | 
 |                 }
  |  | 
 |                 score += (level + 1)*(curShape.y-min);
  |  | 
 |                 scoreNode.innerHTML = score;                   
  |  | 
 |                 curShape = drawShape(curShape.shape,curShape.x,min);
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         return true;
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function gameOver() {
  |  | 
 |         for(i=0;i<10; i++) {
  |  | 
 |             if(usedPolys[i][18] == 1) {
  |  | 
 |                 return true;
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |         return false;
  |  | 
 |     }
  |  | 
 | 
  |  | 
 |     function goDownByTime() {
  |  | 
 |         removeShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |         if(compareWithAbsoluteShape(curShape.shape,curShape.x,curShape.y-1)) {           
  |  | 
 |             curShape = drawShape(curShape.shape,curShape.x,curShape.y-1);
  |  | 
 |             setTimeout(goDownByTime,timeOutTimes[level]);
  |  | 
 |         }
  |  | 
 |         else {
  |  | 
 |             curShape = drawShape(curShape.shape,curShape.x,curShape.y);
  |  | 
 |             document.getElementById('score').innerHTML
  |  | 
 |             if(!gameOver()) {
  |  | 
 |                 removeLines();
  |  | 
 |                 if(compareWithAbsoluteShape(shape(next),4,16)) {
  |  | 
 |                     curShape = drawShape(shape(next),4,16);
  |  | 
 |                     next = getRandom();
  |  | 
 |                     clearVorschau();
  |  | 
 |                     drawVorschauShape(shape(next),1,1);
  |  | 
 |                     setTimeout(goDownByTime,timeOutTimes[level]);
  |  | 
 |                 }
  |  | 
 |                 else {
  |  | 
 |                     curShape = drawShape(shape(next),4,16);
  |  | 
 |                     alert("Game Over!");
  |  | 
 |                 }
  |  | 
 |             }
  |  | 
 |             else {
  |  | 
 |                 alert("Game Over!");
  |  | 
 |             }
  |  | 
 |         }
  |  | 
 |          
  |  | 
 |     }
  |  | 
 |     
  |  | 
 |     function levelUp() {
  |  | 
 |         if(level < 15) {
  |  | 
 |             level += 1;
  |  | 
 |             document.getElementById('level').innerHTML = level;
  |  | 
 |             setTimeout(levelUp,1000*30);
  |  | 
 |         }
  |  | 
 |     }
  |  | 
 |     var pArray = drawPointsAndPolys(board,10,20,false);
  |  | 
 |     drawPointsAndPolys(board2,5,5,true);
  |  | 
 |     
  |  | 
 |     var score = 0;
  |  | 
 |     var scoreNode = document.getElementById('score');
  |  | 
 |     var level = 1;
  |  | 
 |     var timeOutTimes = [2000,1000,900,800,700,600,500,400,350,300,250,200,150,100,50,25]
  |  | 
 |     var curShape;
  |  | 
 |     var next;
  |  | 
 |     
  |  | 
 |     function startTetris() {
  |  | 
 |         if(!started) {
  |  | 
 |             started = true;
  |  | 
 |             curShape = drawShape(shape(getRandom()),4,16); 
  |  | 
 |             next = getRandom();    
  |  | 
 |             drawVorschauShape(shape(next),1,1);
  |  | 
 |             
  |  | 
 |             document.onkeydown = keyDown;    
  |  | 
 |             setTimeout(goDownByTime,timeOutTimes[level]);
  |  | 
 |             setTimeout(levelUp,1000*30);
  |  | 
 |         }
  |  | 
 |     }
  |  | 
 |   /* ]]> */
  |  | 
 |   </script>
  |  | 
 | </html>
  |  |