310 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			310 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var figs = [
 | |
|     //[ 0, 0, 4, 0],
 | |
| 
 | |
|     //  0 0
 | |
|     //  0 0
 | |
|     [  1, 1, 0, 1, 1, 0, 0, 0],
 | |
|     //  0000
 | |
|     [ -2, 0, -1, 0,  0,  0, 1,  0],
 | |
|     //   00
 | |
|     //  00
 | |
|     [ -1, 0,  0, 0,  0,  1, 1,  1],
 | |
|     //  00
 | |
|     //   00
 | |
|     [  0, 0,  0, 1, -1, 1,  1, 0],
 | |
|     //   0
 | |
|     //  000
 | |
|     [  0, 0,  1, 0,  0, 1, -1, 0 ],
 | |
|     //    0
 | |
|     //  000
 | |
|     [ 0, 0, -1, 0, -2, 0, 0, 1 ],
 | |
|     [ 0, 0, -1, 0, -2, 0, 0, -1 ]
 | |
| ];
 | |
| 
 | |
| var Buffer = require('buffer').Buffer;
 | |
| 
 | |
| var startpos = [4, 15];
 | |
| var cupsize = [10, 20];
 | |
| var cup = new Buffer(cupsize[0]*cupsize[1]);
 | |
| var moveInterval;
 | |
| 
 | |
| function clearCup()
 | |
| {
 | |
|     for (var i=0; i <cup.length; ++i)
 | |
|         cup[i] = 0;
 | |
| }
 | |
| 
 | |
| var anglecoeff = [1, 0,  0, 1,
 | |
|                   0, -1, 1, 0,
 | |
|                   -1, 0, 0, -1,
 | |
|                   0, 1, -1, 0];
 | |
| //       0: x = 1x + 0y, y =  0x + 1y
 | |
| //       1: x = 0x - 1y, y =  1x + 0y
 | |
| //       2: x =-1x + 0y, y =  0x - 1y
 | |
| //       2: x = 0x + 1y, y = -1x + 0y;
 | |
| 
 | |
| 
 | |
| function intersects(num, pos, angle)
 | |
| {
 | |
|     angle %= 4;
 | |
|     var fig = getTransformedFigure(num, angle, pos);
 | |
|     for (var i=0; i < fig.length; i+= 2)
 | |
|     {
 | |
|         var x = fig[i];
 | |
|         var y = fig[i+1]
 | |
|         if (y < 0)
 | |
|             return true;
 | |
|         if (x < 0)
 | |
|             return true;
 | |
|         if (x >= cupsize[0])
 | |
|             return true;
 | |
|         if (y >= cupsize[1])
 | |
|             return true;
 | |
|         if (cup[x + y*cupsize[0]])
 | |
|             return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| function putfig(num, pos, angle)
 | |
| {
 | |
|     angle %= 4;
 | |
|     var fig = getTransformedFigure(num, angle, pos);
 | |
|     for (var i=0; i < fig.length; i+= 2)
 | |
|     {
 | |
|         var x = fig[i];
 | |
|         var y = fig[i+1]
 | |
|         var ind = x + y*cupsize[0];
 | |
|         cup[ind] = 1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| function deleteLines()
 | |
| {
 | |
|     for (var y=0; y < cupsize[1]; ++y)
 | |
|     {
 | |
|         var count = 0;
 | |
|         for (var x=0; x < cupsize[0]; ++x)
 | |
|         {
 | |
|            var i = x + y*cupsize[0];
 | |
|            if (cup[i] == 1)
 | |
|                count++;
 | |
|         }
 | |
|         if (count == cupsize[0]) // full line;
 | |
|         {
 | |
|             var count = 0;
 | |
|             for (var yy=y; yy < cupsize[1] - 1; ++yy)
 | |
|             {
 | |
|                 for (var xx=0; xx < cupsize[0]; ++xx)
 | |
|                 {
 | |
|                    var ii = xx + yy*cupsize[0];
 | |
|                    cup[ii] = cup[ii+cupsize[0]];
 | |
|                 }
 | |
|             }
 | |
|             y--;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| var x11 = require('../lib');
 | |
| var Exposure = x11.eventMask.Exposure;
 | |
| var KeyPress = x11.eventMask.KeyPress;
 | |
| var sqsize = 15;
 | |
| var wid, cidBlack, cidWhite;
 | |
| var angle = 0;
 | |
| var gamestate = 'stopped';
 | |
| var timer;
 | |
| var X;
 | |
| var pos = [4, 13];
 | |
| var fignum = 0;
 | |
| 
 | |
| function timerMove()
 | |
| {
 | |
|     var newpos = [pos[0], pos[1]];
 | |
|     newpos[1]--;
 | |
|     if (intersects(fignum, newpos, angle))
 | |
|     {
 | |
|         putfig(fignum, pos, angle);
 | |
| 
 | |
|         deleteLines();
 | |
| 
 | |
|         fignum = parseInt((Math.random()*100)%figs.length);
 | |
|         pos[0] = startpos[0];
 | |
|         pos[1] = startpos[1];
 | |
|         angle = 0;
 | |
|         if (intersects(fignum, pos, angle)) {
 | |
|              process.exit(0);
 | |
|         }
 | |
|         draw();
 | |
|     } else {
 | |
|        pos = newpos;
 | |
|        draw();
 | |
|     }
 | |
| }
 | |
| 
 | |
| function startGame()
 | |
| {
 | |
|     // start timers set up cirrent + next figure, clear cup
 | |
|     clearCup();
 | |
|     moveInterval = setInterval(timerMove, 200);
 | |
| }
 | |
| 
 | |
| function getTransformedFigure(num, angle, pos)
 | |
| {
 | |
|     var tfig = [];
 | |
|     var fig = figs[num];
 | |
|     for (var i=0; i < fig.length; i+=2)
 | |
|     {
 | |
|         var figx = fig[i];
 | |
|         var figy = fig[i+1]
 | |
|         var x = pos[0] + anglecoeff[angle*4]*figx + anglecoeff[angle*4+1]*figy;
 | |
|         var y = pos[1] + anglecoeff[angle*4+2]*figx + anglecoeff[angle*4+3]*figy;
 | |
|         tfig.push(x);
 | |
|         tfig.push(y);
 | |
|     }
 | |
|     return tfig;
 | |
| }
 | |
| 
 | |
| function draw()
 | |
| {
 | |
|     var whiterects = [];
 | |
|     var blackrects = [];
 | |
|     for (var x=0; x < cupsize[0]; ++x)
 | |
|     {
 | |
|         for (var y=0; y < cupsize[1]; ++y)
 | |
|         {
 | |
|             var index = x + y*cupsize[0];
 | |
|             var rect = [x*sqsize, (cupsize[1]-1)*sqsize - y*sqsize, sqsize, sqsize];
 | |
|             if (cup[index] != 0)
 | |
|                 blackrects = blackrects.concat(rect);
 | |
|             else
 | |
|                 whiterects = whiterects.concat(rect);
 | |
|         }
 | |
|     }
 | |
|     var fig = getTransformedFigure(fignum, angle, pos);
 | |
|     for (var i=0; i < fig.length; i+=2)
 | |
|     {
 | |
|         var x = fig[i];
 | |
|         var y = fig[i+1]
 | |
|         blackrects = blackrects.concat([x*sqsize, (cupsize[1]-1)*sqsize - y*sqsize, sqsize, sqsize]);
 | |
|     }
 | |
|     X.PolyFillRectangle(wid, cidWhite, whiterects);
 | |
|     X.PolyFillRectangle(wid, cidBlack, blackrects);
 | |
| }
 | |
| 
 | |
| function rotate(v)
 | |
| {
 | |
|     var newangle = angle + v;
 | |
|     if (newangle < 0)
 | |
|         newangle = 3;
 | |
|     if (newangle >= 4)
 | |
|         newangle = 0;
 | |
|     if (intersects(fignum, pos, newangle))
 | |
|         return;
 | |
| 
 | |
|     angle = newangle;
 | |
|     draw();
 | |
| }
 | |
| 
 | |
| function rotateUp()
 | |
| {
 | |
|    rotate(1);
 | |
| }
 | |
| 
 | |
| function rotateDown()
 | |
| {
 | |
|    rotate(-1);
 | |
| }
 | |
| 
 | |
| function moveX(v)
 | |
| {
 | |
|     var newpos = [pos[0] + v, pos[1]];
 | |
|     if (intersects(fignum, newpos, angle))
 | |
|         return;
 | |
|     pos = [newpos[0], newpos[1]];
 | |
|     draw();
 | |
| }
 | |
| 
 | |
| function moveLeft()
 | |
| {
 | |
|     moveX(-1);
 | |
| }
 | |
| 
 | |
| function moveRight()
 | |
| {
 | |
|     moveX(1);
 | |
| }
 | |
| 
 | |
| function drop()
 | |
| {
 | |
|     var newpos = [pos[0], pos[1]];
 | |
|     while (!intersects(fignum, newpos, angle))
 | |
|         newpos[1]--;
 | |
|     newpos[1]++;
 | |
|     pos = [newpos[0], newpos[1]];
 | |
|     draw();
 | |
| }
 | |
| 
 | |
| 
 | |
| x11.createClient(function(err, display) {
 | |
|     var ks = x11.keySyms;
 | |
|     var ks2Name = {};
 | |
|     for (var key in ks)
 | |
|         ks2Name[ ks[key].code ] = key;
 | |
|     var kk2Name = {};
 | |
|     var min = display.min_keycode;
 | |
|     var max = display.max_keycode;
 | |
|     X = display.client;
 | |
|     X.GetKeyboardMapping(min, max-min, function(err, list) {
 | |
|         for (var i=0; i < list.length; ++i)
 | |
|         {
 | |
|             var name = kk2Name[i+min] = [];
 | |
|             var sublist = list[i];
 | |
|             for (var j =0; j < sublist.length; ++j)
 | |
|                 name.push(ks2Name[sublist[j]]);
 | |
|         }
 | |
| 
 | |
|     var root = display.screen[0].root;
 | |
|     var white = display.screen[0].white_pixel;
 | |
|     var black = display.screen[0].black_pixel;
 | |
|     wid = X.AllocID();
 | |
|     X.CreateWindow(wid, root, 0, 0, cupsize[0]*sqsize, cupsize[1]*sqsize, 0, 0, 0, 0, { backgroundPixel: white, eventMask: KeyPress|Exposure });
 | |
|     cidBlack = X.AllocID();
 | |
|     cidWhite = X.AllocID();
 | |
|     X.CreateGC(cidBlack, wid,  { foreground: black, background: white } );
 | |
|     X.CreateGC(cidWhite, wid,  { foreground: white, background: black } );
 | |
|     X.MapWindow(wid);
 | |
| 
 | |
|     clearCup();
 | |
|     startGame();
 | |
| 
 | |
|     X.on('event', function(ev) {
 | |
|          switch(ev.type) {
 | |
|          case 6:
 | |
|               break;
 | |
|          case 12: // expose
 | |
|               draw(); break;
 | |
|          case 2:
 | |
|               var key = kk2Name[ev.keycode][0];
 | |
|               console.log(key);
 | |
|               switch(key) {
 | |
|                   case 'XK_Up': rotateUp(); break;
 | |
|                   case 'XK_Down': rotateDown(); break;
 | |
|                   case 'XK_Left': moveLeft(); break;
 | |
|                   case 'XK_Right': moveRight(); break;
 | |
|                   case 'XK_space': drop(); break;
 | |
|               }
 | |
|               break;
 | |
|          default:
 | |
|               console.log('default event', ev);
 | |
|          }
 | |
|     });
 | |
| 
 | |
|     X.on('end', function() {
 | |
|         clearInterval(moveInterval);
 | |
|     });
 | |
| 
 | |
|   });
 | |
| 
 | |
| });
 |