Skip to content

Instantly share code, notes, and snippets.

@rummik
Created October 28, 2014 13:27
Show Gist options
  • Save rummik/d67f15f26a1903bdfe52 to your computer and use it in GitHub Desktop.
Save rummik/d67f15f26a1903bdfe52 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style id="jsbin-css">
canvas {
outline: 1px solid #000;
}
</style>
</head>
<body>
<canvas></canvas>
<script id="jsbin-javascript">
({
canvas: document.querySelector('canvas'),
ctx: document.querySelector('canvas').getContext('2d'),
_hold: false,
_redraw: false,
_time: Date.now(),
_board: [],
_mino: {},
lines: 0,
board: {
width: 8,
height: 15,
_scale: 8
},
minos: [
{
width: 2,
height: 2,
data: [ 1, 1, 1, 1 ]
},
{
width: 2,
height: 3,
data: [ 1, 1, 1, 0, 1, 0 ]
},
{
width: 2,
height: 3,
data: [ 1, 1, 0, 1, 0, 1 ]
},
{
width: 3,
height: 2,
data: [ 0, 1, 0, 1, 1, 1 ]
},
{
width: 3,
height: 2,
data: [ 0, 1, 1, 1, 1, 0 ]
},
{
width: 3,
height: 2,
data: [ 1, 1, 0, 0, 1, 1 ]
},
{
width: 1,
height: 4,
data: [ 1, 1, 1, 1 ]
}
],
get rate() {
return 1000 - (this.lines / 200 * 950);
},
get time() {
return Date.now() - this._time;
},
get mino() {
var self = this;
if (this._mino.id === undefined) {
this._mino = {
_id: null,
_rotation: 0,
x: null,
y: null,
width: null,
height: null,
data: [],
get id() {
return this._id;
},
set id(id) {
this._id = id;
this._rotation = 0;
this.width = self.minos[id].width;
this.height = self.minos[id].height;
this.data = self.minos[id].data;
this.x = Math.round((self.board.width - this.width) / 2);
this.y = -this.height;
},
get rotation() {
return this._rotation;
},
set rotation(rotation) {
rotation = rotation % 4;
this._rotation = rotation;
},
rotate: function(deg) {
var i, d, x, y;
var w = this.width;
var h = this.height;
var len = this.data.length;
switch (deg) {
case 90:
this.width = h;
this.height = w;
for (d=[], i=0; i<len; i++) {
d.push(this.data[((i % h + 1) * w) - Math.floor(i / h) - 1]);
}
this.data = d;
break;
// inefficient, but works
case -90:
this.rotate(180);
this.rotate(90);
break;
case 180:
case -180:
this.data.reverse();
break;
}
}
};
}
return this._mino;
},
selectMino: function(id) {
if (typeof id !== 'number' || id < 0 || id >= this.minos.length) {
id = Math.floor(Math.random() * this.minos.length);
}
this.mino.id = id;
},
hold: function(hold) {
this._hold = typeof hold === 'undefined' ? !this._hold : hold;
if (!this._hold) {
this._time = Date.now();
}
},
main: function() {
var step = Math.floor(this.time / this.rate);
if (step > 0) {
this._time = Date.now();
this.mino.y += step;
this._redraw = true;
}
if (this._redraw) {
this.draw();
this._redraw = false;
}
},
draw: function() {
var ctx = this.ctx;
ctx.clearRect(
0, 0,
this.canvas.width, this.canvas.height
);
ctx.fillStyle = 'black';
for (var y=0; y<this.board.height; y++) {
for (var x=0; x<this.board.width; x++) {
if (!this._board[y][x]) {
continue;
}
ctx.fillRect(
this.board._scale * x + x,
this.board._scale * y + y,
this.board._scale,
this.board._scale
);
}
}
var mino = this.mino.data;
for (var _x, _y, n=0; n<mino.length; n++) {
if (!mino[n]) {
continue;
}
_x = this.mino.x + (n % this.mino.width);
_y = this.mino.y + Math.floor(n / this.mino.width);
ctx.fillRect(
this.board._scale * _x + _x,
this.board._scale * _y + _y,
this.board._scale,
this.board._scale
);
}
},
init: function() {
for (var x=0,row=[]; x<this.board.width; row[x]=0,x++);
for (var y=0; y<this.board.height; y++) {
this._board[y] = row.slice();
}
window.blur = this.hold.bind(this, false);
window.focus = this.hold.bind(this, true);
this.selectMino();
this.canvas.width = this.board.width +
this.board._scale *
this.board.width;
this.canvas.height = this.board.height +
this.board._scale *
this.board.height;
this._redraw = true;
var self = this;
(function loop() {
if (self._hold) {
return;
}
self.main();
requestAnimationFrame(loop);
})();
}
}).init();
</script>
<script id="jsbin-source-css" type="text/css">canvas {
outline: 1px solid #000;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">({
canvas: document.querySelector('canvas'),
ctx: document.querySelector('canvas').getContext('2d'),
_hold: false,
_redraw: false,
_time: Date.now(),
_board: [],
_mino: {},
lines: 0,
board: {
width: 8,
height: 15,
_scale: 8
},
minos: [
{
width: 2,
height: 2,
data: [ 1, 1, 1, 1 ]
},
{
width: 2,
height: 3,
data: [ 1, 1, 1, 0, 1, 0 ]
},
{
width: 2,
height: 3,
data: [ 1, 1, 0, 1, 0, 1 ]
},
{
width: 3,
height: 2,
data: [ 0, 1, 0, 1, 1, 1 ]
},
{
width: 3,
height: 2,
data: [ 0, 1, 1, 1, 1, 0 ]
},
{
width: 3,
height: 2,
data: [ 1, 1, 0, 0, 1, 1 ]
},
{
width: 1,
height: 4,
data: [ 1, 1, 1, 1 ]
}
],
get rate() {
return 1000 - (this.lines / 200 * 950);
},
get time() {
return Date.now() - this._time;
},
get mino() {
var self = this;
if (this._mino.id === undefined) {
this._mino = {
_id: null,
_rotation: 0,
x: null,
y: null,
width: null,
height: null,
data: [],
get id() {
return this._id;
},
set id(id) {
this._id = id;
this._rotation = 0;
this.width = self.minos[id].width;
this.height = self.minos[id].height;
this.data = self.minos[id].data;
this.x = Math.round((self.board.width - this.width) / 2);
this.y = -this.height;
},
get rotation() {
return this._rotation;
},
set rotation(rotation) {
rotation = rotation % 4;
this._rotation = rotation;
},
rotate: function(deg) {
var i, d, x, y;
var w = this.width;
var h = this.height;
var len = this.data.length;
switch (deg) {
case 90:
this.width = h;
this.height = w;
for (d=[], i=0; i<len; i++) {
d.push(this.data[((i % h + 1) * w) - Math.floor(i / h) - 1]);
}
this.data = d;
break;
// inefficient, but works
case -90:
this.rotate(180);
this.rotate(90);
break;
case 180:
case -180:
this.data.reverse();
break;
}
}
};
}
return this._mino;
},
selectMino: function(id) {
if (typeof id !== 'number' || id < 0 || id >= this.minos.length) {
id = Math.floor(Math.random() * this.minos.length);
}
this.mino.id = id;
},
hold: function(hold) {
this._hold = typeof hold === 'undefined' ? !this._hold : hold;
if (!this._hold) {
this._time = Date.now();
}
},
main: function() {
var step = Math.floor(this.time / this.rate);
if (step > 0) {
this._time = Date.now();
this.mino.y += step;
this._redraw = true;
}
if (this._redraw) {
this.draw();
this._redraw = false;
}
},
draw: function() {
var ctx = this.ctx;
ctx.clearRect(
0, 0,
this.canvas.width, this.canvas.height
);
ctx.fillStyle = 'black';
for (var y=0; y<this.board.height; y++) {
for (var x=0; x<this.board.width; x++) {
if (!this._board[y][x]) {
continue;
}
ctx.fillRect(
this.board._scale * x + x,
this.board._scale * y + y,
this.board._scale,
this.board._scale
);
}
}
var mino = this.mino.data;
for (var _x, _y, n=0; n<mino.length; n++) {
if (!mino[n]) {
continue;
}
_x = this.mino.x + (n % this.mino.width);
_y = this.mino.y + Math.floor(n / this.mino.width);
ctx.fillRect(
this.board._scale * _x + _x,
this.board._scale * _y + _y,
this.board._scale,
this.board._scale
);
}
},
init: function() {
for (var x=0,row=[]; x<this.board.width; row[x]=0,x++);
for (var y=0; y<this.board.height; y++) {
this._board[y] = row.slice();
}
window.blur = this.hold.bind(this, false);
window.focus = this.hold.bind(this, true);
this.selectMino();
this.canvas.width = this.board.width +
this.board._scale *
this.board.width;
this.canvas.height = this.board.height +
this.board._scale *
this.board.height;
this._redraw = true;
var self = this;
(function loop() {
if (self._hold) {
return;
}
self.main();
requestAnimationFrame(loop);
})();
}
}).init();</script></body>
</html>
canvas {
outline: 1px solid #000;
}
({
canvas: document.querySelector('canvas'),
ctx: document.querySelector('canvas').getContext('2d'),
_hold: false,
_redraw: false,
_time: Date.now(),
_board: [],
_mino: {},
lines: 0,
board: {
width: 8,
height: 15,
_scale: 8
},
minos: [
{
width: 2,
height: 2,
data: [ 1, 1, 1, 1 ]
},
{
width: 2,
height: 3,
data: [ 1, 1, 1, 0, 1, 0 ]
},
{
width: 2,
height: 3,
data: [ 1, 1, 0, 1, 0, 1 ]
},
{
width: 3,
height: 2,
data: [ 0, 1, 0, 1, 1, 1 ]
},
{
width: 3,
height: 2,
data: [ 0, 1, 1, 1, 1, 0 ]
},
{
width: 3,
height: 2,
data: [ 1, 1, 0, 0, 1, 1 ]
},
{
width: 1,
height: 4,
data: [ 1, 1, 1, 1 ]
}
],
get rate() {
return 1000 - (this.lines / 200 * 950);
},
get time() {
return Date.now() - this._time;
},
get mino() {
var self = this;
if (this._mino.id === undefined) {
this._mino = {
_id: null,
_rotation: 0,
x: null,
y: null,
width: null,
height: null,
data: [],
get id() {
return this._id;
},
set id(id) {
this._id = id;
this._rotation = 0;
this.width = self.minos[id].width;
this.height = self.minos[id].height;
this.data = self.minos[id].data;
this.x = Math.round((self.board.width - this.width) / 2);
this.y = -this.height;
},
get rotation() {
return this._rotation;
},
set rotation(rotation) {
rotation = rotation % 4;
this._rotation = rotation;
},
rotate: function(deg) {
var i, d, x, y;
var w = this.width;
var h = this.height;
var len = this.data.length;
switch (deg) {
case 90:
this.width = h;
this.height = w;
for (d=[], i=0; i<len; i++) {
d.push(this.data[((i % h + 1) * w) - Math.floor(i / h) - 1]);
}
this.data = d;
break;
// inefficient, but works
case -90:
this.rotate(180);
this.rotate(90);
break;
case 180:
case -180:
this.data.reverse();
break;
}
}
};
}
return this._mino;
},
selectMino: function(id) {
if (typeof id !== 'number' || id < 0 || id >= this.minos.length) {
id = Math.floor(Math.random() * this.minos.length);
}
this.mino.id = id;
},
hold: function(hold) {
this._hold = typeof hold === 'undefined' ? !this._hold : hold;
if (!this._hold) {
this._time = Date.now();
}
},
main: function() {
var step = Math.floor(this.time / this.rate);
if (step > 0) {
this._time = Date.now();
this.mino.y += step;
this._redraw = true;
}
if (this._redraw) {
this.draw();
this._redraw = false;
}
},
draw: function() {
var ctx = this.ctx;
ctx.clearRect(
0, 0,
this.canvas.width, this.canvas.height
);
ctx.fillStyle = 'black';
for (var y=0; y<this.board.height; y++) {
for (var x=0; x<this.board.width; x++) {
if (!this._board[y][x]) {
continue;
}
ctx.fillRect(
this.board._scale * x + x,
this.board._scale * y + y,
this.board._scale,
this.board._scale
);
}
}
var mino = this.mino.data;
for (var _x, _y, n=0; n<mino.length; n++) {
if (!mino[n]) {
continue;
}
_x = this.mino.x + (n % this.mino.width);
_y = this.mino.y + Math.floor(n / this.mino.width);
ctx.fillRect(
this.board._scale * _x + _x,
this.board._scale * _y + _y,
this.board._scale,
this.board._scale
);
}
},
init: function() {
for (var x=0,row=[]; x<this.board.width; row[x]=0,x++);
for (var y=0; y<this.board.height; y++) {
this._board[y] = row.slice();
}
window.blur = this.hold.bind(this, false);
window.focus = this.hold.bind(this, true);
this.selectMino();
this.canvas.width = this.board.width +
this.board._scale *
this.board.width;
this.canvas.height = this.board.height +
this.board._scale *
this.board.height;
this._redraw = true;
var self = this;
(function loop() {
if (self._hold) {
return;
}
self.main();
requestAnimationFrame(loop);
})();
}
}).init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment