Skip to content

Instantly share code, notes, and snippets.

@gujc71
Last active July 16, 2017 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gujc71/b61d56ff4e96e8f12ce6d98201bf10f1 to your computer and use it in GitHub Desktop.
Save gujc71/b61d56ff4e96e8f12ce6d98201bf10f1 to your computer and use it in GitHub Desktop.
Tetris
<canvas id="tetrisCanvas" width="200" height="400"></canvas>
<script>
// control with keyboard, block color
var canvas = document.getElementById('tetrisCanvas');
var ctx = canvas.getContext('2d');
var shapes = [
[ 0x4640, 0x0E40, 0x4C40, 0x4E00 ], // 'T'
[ 0x8C40, 0x6C00, 0x8C40, 0x6C00 ], // 'S'
[ 0x4C80, 0xC600, 0x4C80, 0xC600 ], // 'Z'
[ 0x4444, 0x0F00, 0x4444, 0x0F00 ], // 'I'
[ 0x44C0, 0x8E00, 0xC880, 0xE200 ], // 'J'
[ 0x88C0, 0xE800, 0xC440, 0x2E00 ], // 'L'
[ 0xCC00, 0xCC00, 0xCC00, 0xCC00 ] // 'O'
];
function getNextShape() {
curShapeType = Math.floor((Math.random() * 7));
curRotation = 0;
return shapes[curShapeType][curRotation]
}
var ROW_CNT = 20;
var COL_CNT = 10;
var KEY = { ESC: 27, SPACE: 32, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40 };
var shapeColor = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
var curShapeType = 0, curRotation = 0, curShape = getNextShape() ;
var sPos = {x: (COL_CNT-4) / 2, y:0};
var gamePanel = [];
for (var y = 0; y < ROW_CNT; y++) {
gamePanel[y] = [];
for (var x = 0; x < COL_CNT; x++) {
gamePanel[y][x] = 0;
}
}
var intervalHandler = setInterval(playingTetris, 400);
function playingTetris() {
if ( intersects(sPos.y + 1, sPos.x)) {
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++)
if ((curShape & (0x8000 >> (i * 4 + j))) && gamePanel[sPos.y+i]) {
gamePanel[sPos.y+i][sPos.x+j] = curShapeType+1;
}
curShape = getNextShape();
sPos = {x: (COL_CNT-4) / 2, y:0};
if (intersects(sPos.y, sPos.x)) {
clearInterval(intervalHandler);
alert("Game Over");
}
gamePanel = removeRow();
} else {
sPos.y++;
}
draw();
}
function intersects(y, x) {
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++)
if (curShape & (0x8000 >> (i * 4 + j)))
if (y+i >= ROW_CNT || x+j < 0 || x+j >= 10 || gamePanel[y+i][x+j])
return true;
return false;
}
function draw() {
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 200, 400);
ctx.rect(0, 0, 200, 400);
ctx.strokeStyle="blue";
ctx.stroke();
ctx.fillStyle = 'black';
for (var y = 0; y < gamePanel.length; y++) {
for (var x = 0; x < gamePanel[y].length; x++) {
if (gamePanel[y][x]) {
ctx.fillStyle = shapeColor[gamePanel[y][x]-1];
ctx.fillRect(x * 20, y * 20, 19, 19);
}
}
}
ctx.fillStyle = shapeColor[curShapeType];
for (var y = 0; y < 4; y++) {
for (var x = 0; x < 4; x++) {
if (curShape & (0x8000 >> (y * 4 + x))) {
ctx.fillRect((sPos.x+x) * 20, (sPos.y+y) * 20, 19, 19);
}
}
}
}
function moveShape(value) {
if ( !intersects(sPos.y, sPos.x+value)) {
sPos.x += value;
draw();
}
}
function dropShape() {
for (var y=sPos.y; y<ROW_CNT; y++) {
if ( !intersects(sPos.y+1, sPos.x)) {
sPos.y++;
draw();
} else {
break;
}
}
}
function rotateShape() {
curRotation = (curRotation + 1) % 4;;
curShape = shapes[curShapeType][curRotation]
draw();
}
function removeRow() {
var newRows = [];
var k = ROW_CNT;
for (var y = ROW_CNT-1; y>=0; y--) {
for (var x = 0; x < COL_CNT; x++) {
if (!gamePanel[y][x]) {
newRows[--k] = gamePanel[y].slice();
break;
}
}
}
for (var y = 0; y < k; y++) {
newRows[y] = [];
for (var x = 0; x < COL_CNT; x++)
newRows[y][x] = 0;
}
return newRows;
}
function keydown(ev) {
var handled = false;
switch(ev.keyCode) {
case KEY.LEFT: moveShape(-1); handled = true; break;
case KEY.RIGHT: moveShape( 1); handled = true; break;
case KEY.UP: rotateShape(); handled = true; break;
case KEY.DOWN: dropShape(); handled = true; break;
case KEY.ESC: clearInterval(intervalHandler); handled = true; break;
}
if (handled) {
ev.preventDefault();
}
}
document.addEventListener('keydown', keydown, false);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment