566 lines
15 KiB
JavaScript
566 lines
15 KiB
JavaScript
var twirlRunning = false;
|
|
function twirlGame() {
|
|
var twirl_dimensions = { 'height': 20, 'width': 10 };
|
|
var canvas = document.getElementById('twirl');
|
|
if (!canvas || !$('#twirl').is(':visible') || twirlRunning == true) {
|
|
return;
|
|
}
|
|
twirlRunning = true;
|
|
var tPieces = [];
|
|
var dropper;
|
|
var win = $('#twirl').closest('.wind');
|
|
var tn = win.find('.top_navbar');
|
|
canvas.height = win.height();
|
|
canvas.width = win.width();
|
|
var twirlctx = canvas.getContext('2d');
|
|
|
|
twirlctx.beginPath;
|
|
twirlctx.font = "1 26px arial";
|
|
|
|
|
|
var twirlPieces = [
|
|
{
|
|
'name': 'straight',
|
|
'colour': 'red',
|
|
'offset': 3,
|
|
'piece': [
|
|
[ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ]
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ],
|
|
[ [ 1, -1 ], [ 0, 0 ], [ -1, -2 ], [ -2, -3 ] ]
|
|
|
|
]
|
|
},
|
|
{
|
|
'name': 'cube',
|
|
'colour': 'blue',
|
|
'offset': 4,
|
|
'piece': [
|
|
[ 0, 0 ], [ 1, 0 ], [ 0, 1 ], [ 1, 1 ]
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ],
|
|
]
|
|
},
|
|
{
|
|
'name': 'left_curl',
|
|
'colour': 'green',
|
|
'offset': 3,
|
|
'piece': [
|
|
[ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 0, 1 ]
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ],
|
|
[ [ 0, -1 ], [ 0, -1 ], [ -1, 0 ], [ 1, 0 ] ],
|
|
[ [ 0, 1 ], [ 0, 1 ], [ 0, 0 ], [ 2, 0 ] ],
|
|
[ [ 1, 1 ], [ 1, 1 ], [ -1, -1 ], [ 1, -1 ] ],
|
|
]
|
|
},
|
|
{
|
|
'name': 'right_curl',
|
|
'colour': 'yellow',
|
|
'offset': 3,
|
|
'piece': [
|
|
[ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 2, 1 ],
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 2, 1 ] ],
|
|
[ [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ 1, 1 ] ],
|
|
[ [ 1, 0 ], [ 2, 1 ], [ 3, 1 ], [ 1, 1 ] ],
|
|
[ [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 2, -1 ] ]
|
|
]
|
|
},
|
|
{
|
|
'name': 'crown',
|
|
'colour': 'orange',
|
|
'offset': 3,
|
|
'piece': [
|
|
[ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 1, 1 ]
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 1, 1 ] ],
|
|
[ [ 1, -1 ], [ 0, 0 ], [ 1, 0 ], [ 1, 1 ] ],
|
|
[ [ 1, -1 ], [ 2, 0 ], [ 1, 0 ], [ 0, 0 ] ],
|
|
[ [ 1, -1 ], [ 2, 0 ], [ 1, 0 ], [ 1, 1 ] ],
|
|
]
|
|
},
|
|
{
|
|
'name': 'lstep',
|
|
'colour': 'lightgreen',
|
|
'offset': 3,
|
|
'piece': [
|
|
[ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 2, 1 ]
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 2, 1 ] ],
|
|
[ [ 1, -1 ], [ 0, 0 ], [ 1, 0 ], [ 0, 1 ] ],
|
|
]
|
|
},
|
|
{
|
|
'name': 'rstep',
|
|
'colour': 'lightblue',
|
|
'offset': 3,
|
|
'piece': [
|
|
[ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 2, 0 ]
|
|
],
|
|
'rotations': [
|
|
[ [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 2, 0 ] ],
|
|
[ [ 0, -1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ]
|
|
]
|
|
}
|
|
];
|
|
var twirlSpace = {
|
|
'columns': 10,
|
|
'rows': 18,
|
|
'top': 35,
|
|
'bottom': (canvas.height - 90),
|
|
'left': 10,
|
|
'right': (canvas.width * .7128),
|
|
'nextPiece': randomPiece(),
|
|
'speed': 1000,
|
|
'originalSpeed': 1000,
|
|
'drop': 'no',
|
|
'fallingPieces': 0,
|
|
'status': 'ok',
|
|
'nextPl': [],
|
|
'score': 0,
|
|
'highScore': twirlHighScore,
|
|
'paused': false
|
|
};
|
|
$.each(twirlPieces, function(i,v) {
|
|
v.blockHeight = ((twirlSpace.bottom - twirlSpace.top) / twirlSpace.rows);
|
|
v.blockWidth = ((twirlSpace.right - twirlSpace.left) / twirlSpace.columns);
|
|
twirlSpace['blockHeight'] = v.blockHeight;
|
|
twirlSpace['blockWidth'] = v.blockWidth;
|
|
});
|
|
|
|
function randomPiece() {
|
|
var random_number = numeral(Math.random() * 10).format('0');
|
|
while (random_number >= twirlPieces.length) {
|
|
random_number = numeral(Math.random() * 10).format('0');
|
|
}
|
|
return random_number;
|
|
}
|
|
|
|
function drawPiece(n,next) {
|
|
|
|
var p = twirlPieces[ n || 0 ];
|
|
var pls = [];
|
|
twirlctx.fillStyle = p.colour;
|
|
twirlctx.strokeStyle = 'black';
|
|
|
|
var status = 'falling';
|
|
var delete_it = 'no';
|
|
$.each(p.piece, function(i,v) {
|
|
var l = twirlSpace.left + (p.blockWidth * v[0]) + (p.blockWidth * p.offset);
|
|
var t = twirlSpace.top + (p.blockHeight * v[1]);
|
|
var r = Date.now();
|
|
if (next == 'next') {
|
|
$.each(tPieces, function(i,v) {
|
|
$.each(v, function(ir,pl) {
|
|
|
|
});
|
|
});
|
|
l = (canvas.width * .66) + (p.blockWidth * v[0]) + (p.blockWidth);
|
|
t = 80 + (p.blockHeight * v[1]);
|
|
status = 'next';
|
|
}
|
|
var pl = [
|
|
l,
|
|
t,
|
|
p.blockWidth,
|
|
p.blockHeight,
|
|
status,
|
|
0,
|
|
p,
|
|
r,
|
|
0,
|
|
i,
|
|
n
|
|
];
|
|
pls.push(pl);
|
|
});
|
|
twirlctx.fillStyle = 'beige';
|
|
return pls;
|
|
}
|
|
function drawTwirl() {
|
|
clearInterval(dropper);
|
|
twirlSpace.initiated = Date.now();
|
|
|
|
twirlctx.strokeRect(5, 30, canvas.width - 10, canvas.height - 80);
|
|
twirlctx.strokeRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
|
|
|
|
twirlctx.fillText('Next', ( (canvas.width * .7128) + ( twirlctx.measureText('text').width / 2)), 50);
|
|
twirlctx.strokeRect(canvas.width * .7128 + 10, 50, (canvas.width * .7128 * .3), 100);
|
|
tPieces.push(drawPiece(twirlSpace.nextPiece));
|
|
twirlSpace.nextPiece = randomPiece();
|
|
twirlSpace.nextPl = drawPiece(twirlSpace.nextPiece,'next');
|
|
twirlctx.stroke();
|
|
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fill();
|
|
|
|
twirlDropper();
|
|
}
|
|
|
|
function twirlDropper() {
|
|
|
|
dropper = setInterval(function() {
|
|
twirlctx.fillStyle = 'white';
|
|
twirlctx.fillRect(canvas.width * .7128 + 10, 50, (canvas.width * .7128 * .3), 100);
|
|
twirlctx.fill();
|
|
pieceDropper(twirlSpace.nextPl);
|
|
twirlSpace.fallingPieces = 0;
|
|
twirlSpace.nextPl = drawPiece(twirlSpace.nextPiece,'next');
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fill();
|
|
if (twirlSpace.status == 'ok') {
|
|
$.each(tPieces, function(i,v) {
|
|
pieceDropper(v)
|
|
});
|
|
if (twirlSpace.fallingPieces == 0) {
|
|
|
|
tPieces.push(drawPiece(twirlSpace.nextPiece));
|
|
if (twirlSpace.speed != twirlSpace.originalSpeed) {
|
|
clearInterval(dropper);
|
|
twirlSpace.speed = twirlSpace.originalSpeed;
|
|
twirlDropper()
|
|
}
|
|
|
|
twirlSpace.nextPiece = randomPiece();
|
|
twirlctx.fillStyle = 'white';
|
|
twirlctx.fillRect(canvas.width * .7128 + 10, 50, (canvas.width * .7128 * .3), 100);
|
|
|
|
twirlctx.fill();
|
|
twirlSpace.nextPl = drawPiece(twirlSpace.nextPiece,'next');
|
|
pieceDropper(twirlSpace.nextPl);
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
}
|
|
}
|
|
else if (status == 'game over') {
|
|
gameOver();
|
|
}
|
|
twirlSpace.status = boundaryPiece();
|
|
twirlSpace.nextPl = drawPiece(twirlSpace.nextPiece,'next');
|
|
},twirlSpace.speed);
|
|
}
|
|
|
|
function pieceDropper(v) {
|
|
pieceEliminator();
|
|
$.each(v, function(ir,pl) {
|
|
if (pl && pl[4] == 'falling') {
|
|
twirlSpace.fallingPieces += 1;
|
|
pl[1] = (pl[1] + (twirlSpace.blockHeight));
|
|
pl[5] += 1;
|
|
|
|
}
|
|
|
|
if (pl) {
|
|
twirlctx.fillStyle = pl[6]['colour'];
|
|
twirlctx.fillRect(pl[0],pl[1],pl[2],pl[3]);
|
|
twirlctx.strokeRect(pl[0],pl[1],pl[2],pl[3]);
|
|
twirlctx.stroke();
|
|
if (ir == v.length) {
|
|
twirlSpace.status = boundaryPiece();
|
|
}
|
|
}
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (!twirlSpaceInitiated) {
|
|
$(document).on('keydown', function(e) {
|
|
if (topWindow() == 'twirl') {
|
|
e.preventDefault();
|
|
if (e.keyCode == 27) {
|
|
pauseGame();
|
|
}
|
|
if (e.keyCode == 32) {
|
|
movePiece('drop');
|
|
}
|
|
if (e.keyCode == 37) {
|
|
movePiece('left');
|
|
}
|
|
else if (e.keyCode == 39) {
|
|
movePiece('right');
|
|
}
|
|
else if (e.keyCode == 40) {
|
|
movePiece('down');
|
|
}
|
|
else if (e.keyCode == 38) {
|
|
movePiece('rotate');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function pauseGame() {
|
|
if (twirlSpace.paused == true) {
|
|
twirlSpace.paused = false;
|
|
twirlctx.fillStyle = 'beige';
|
|
var text = 'Resuming';
|
|
if (tPieces.length == 0) {
|
|
text = 'Beginning';
|
|
}
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fillStyle = 'black';
|
|
twirlctx.fillText(text, (twirlSpace.left + (twirlSpace.right / 2) - (twirlctx.measureText(text).width / 2)), (twirlSpace.top + (twirlSpace.bottom / 2)));
|
|
twirlctx.fill();
|
|
|
|
var count = 3;
|
|
var countdown = 3000 / count;
|
|
var remaining = 3000;
|
|
var i = setInterval(function() {
|
|
if (count == 0) { clearInterval(i); }
|
|
else {
|
|
remaining = countdown * (count - 1);
|
|
if (remaining < twirlSpace.speed) {
|
|
twirlDropper();
|
|
}
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fillStyle = 'black';
|
|
twirlctx.fillText(text, (twirlSpace.left + (twirlSpace.right / 2) - (twirlctx.measureText(text).width / 2)), (twirlSpace.top + (twirlSpace.bottom / 2)));
|
|
twirlctx.fill();
|
|
twirlctx.fillStyle = 'black';
|
|
twirlctx.fillText(count, (twirlSpace.left + (twirlSpace.right / 2) - (twirlctx.measureText(count).width / 2)), (twirlSpace.top + (twirlSpace.bottom / 2) + 30));
|
|
twirlctx.fill();
|
|
count--;
|
|
}
|
|
}, countdown);
|
|
|
|
}
|
|
else {
|
|
twirlSpace.paused = true;
|
|
clearInterval(dropper);
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fillStyle = 'black';
|
|
twirlctx.fillText('Paused', (twirlSpace.left + (twirlSpace.right / 2) - (twirlctx.measureText('Paused').width / 2)), (twirlSpace.top + (twirlSpace.bottom / 2)));
|
|
twirlctx.fill();
|
|
}
|
|
}
|
|
|
|
function pieceEliminator() {
|
|
var rows = {};
|
|
var eliminate = [];
|
|
var eliminated = [];
|
|
var eliminator = Date.now();
|
|
$.each(tPieces, function(i,v) {
|
|
$.each(v, function(ir,pl) {
|
|
if (rows[pl[1]] == undefined) { rows[pl[1]] = []; }
|
|
if (pl[4] == 'laid') {
|
|
rows[pl[1]].push(pl[0]);
|
|
}
|
|
|
|
if (rows[pl[1]].length == twirlSpace.columns) {
|
|
console.log('elminating ' + pl[1]);
|
|
if (pl[4] == 'laid') {
|
|
rows[pl[1]].push(pl[0]);
|
|
eliminate.push(pl[1]);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
var pushDown = [];
|
|
$.each(eliminate, function(e,el) {
|
|
$.each(tPieces, function(i,v) {
|
|
$.each(v, function(ir,pl) {
|
|
var gone = 0;
|
|
if (pl[1] < el) {
|
|
pushDown.push(pl);
|
|
}
|
|
if (pl[1] == el) {
|
|
eliminated.push(ir);
|
|
gone = 1;
|
|
}
|
|
|
|
});
|
|
twirlSpace.score = (twirlSpace.score + (eliminated.length));
|
|
$.each(eliminated, function(ip,vp) {
|
|
v.splice(vp)
|
|
});
|
|
eliminated = [];
|
|
});
|
|
});
|
|
$.each(pushDown.reverse(), function(i,pl) {
|
|
pl[1] = pl[1] + twirlSpace.blockHeight;
|
|
});
|
|
twirlctx.fillStyle = 'white';
|
|
|
|
twirlctx.fillRect((canvas.width * .7128 + 10), 200, 100, 60);
|
|
twirlctx.fillRect((canvas.width * .7128 + 12), 250, 100, 60);
|
|
twirlctx.fill();
|
|
|
|
|
|
if (twirlSpace.score > twirlSpace.highScore) {
|
|
twirlSpace.highScore = twirlSpace.score;
|
|
settingSetter({ 'app': 'twirl', 'setting': 'high_score', 'value': twirlSpace.highScore });
|
|
}
|
|
twirlctx.fillStyle = 'black';
|
|
twirlctx.fillText(twirlSpace.score, (canvas.width * .7128 + 12), 220);
|
|
twirlctx.fillStyle = 'blue';
|
|
twirlctx.fillText(twirlSpace.highScore, (canvas.width * .7128 + 12), 250);
|
|
twirlctx.fill();
|
|
twirlctx.stroke();
|
|
}
|
|
|
|
var twirlSpaceInitiated = Date.now();
|
|
|
|
function movePiece(direction) {
|
|
if (twirlSpace.paused == true) { return; }
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
var fallingPieces = 0;
|
|
var status = boundaryPiece(direction);
|
|
if (status == 'ok') {
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fill();
|
|
$.each(tPieces, function(i,v) {
|
|
$.each(v, function(ir,pl) {
|
|
var transformed;
|
|
if (pl[4] == 'falling') {
|
|
fallingPieces += 1;
|
|
twirlctx.fillStyle = pl[6]['colour'];
|
|
if (direction == 'right') {
|
|
pl[0] = (pl[0] + (twirlSpace.blockWidth));
|
|
}
|
|
else if (direction == 'left') {
|
|
pl[0] = (pl[0] - (twirlSpace.blockWidth));
|
|
}
|
|
else if (direction == 'down') {
|
|
pl[1] = (pl[1] + (twirlSpace.blockHeight));
|
|
pl[5] += 1;
|
|
}
|
|
else if (direction == 'drop') {
|
|
twirlSpace.speed = 1;
|
|
clearInterval(dropper);
|
|
twirlDropper();
|
|
if (!$('#twirl').is(':visible')) {
|
|
clearInterval(dropper);
|
|
}
|
|
//clearInterval(dropper);
|
|
//twirlSpace.speed = twirlSpace.originalSpeed;
|
|
//twirlDropper();
|
|
}
|
|
else if (direction == 'rotate') {
|
|
transformed = pl[8];
|
|
if (pl[8] >= pl[6]['rotations'].length - 1) {
|
|
pl[8] = 0;
|
|
}
|
|
else {
|
|
pl[8]++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if ((transformed || transformed == 0) && pl[8] != transformed) {
|
|
var block = pl[9];
|
|
var new_block = twirlPieces[pl[10]]['rotations'][pl[8]][pl[9]];
|
|
var old_block = twirlPieces[pl[10]]['rotations'][transformed][pl[9]];
|
|
|
|
var xdiff = (new_block[0] - old_block[0]) * twirlSpace.blockWidth;
|
|
var ydiff = (new_block[1] - old_block[1]) * twirlSpace.blockHeight;
|
|
pl[0] = pl[0] + xdiff;
|
|
pl[1] = pl[1] + ydiff;
|
|
}
|
|
|
|
twirlctx.fillStyle = pl[6]['colour'];
|
|
twirlctx.fillRect(pl[0],pl[1],pl[2],pl[3]);
|
|
twirlctx.strokeRect(pl[0],pl[1],pl[2],pl[3]);
|
|
twirlctx.stroke();
|
|
});
|
|
});
|
|
}
|
|
else if (status == 'game over') {
|
|
gameOver();
|
|
}
|
|
twirlctx.save('a');
|
|
twirlSpace.nextPl = drawPiece(twirlSpace.nextPiece,'next');
|
|
twirlctx.restore('a');
|
|
}
|
|
|
|
function boundaryPiece(direction) {
|
|
var laid = 0;
|
|
var status = 'ok';
|
|
|
|
$.each(tPieces.reverse(), function(i,v) {
|
|
$.each(v, function(ir,pl) {
|
|
if (pl[4] == 'falling') {
|
|
if ((pl[1] + pl[3]) >= twirlSpace.bottom) {
|
|
laid = 1;
|
|
}
|
|
|
|
$.each(tPieces, function(ip,vp) {
|
|
$.each(vp, function(irp, vrp) {
|
|
|
|
if (pl[7] != vrp[7]) {
|
|
if ((pl[1] + pl[3]) == vrp[1] && (pl[0] == vrp[0])) {
|
|
laid = 1;
|
|
}
|
|
}
|
|
|
|
if (direction == 'right') {
|
|
if (((pl[0] + pl[3] + pl[3]) == vrp[0] && (pl[1] == vrp[1]) && (pl[7] != vrp[7])) || (pl[0] + pl[3] + pl[3] ) >= twirlSpace.right) {
|
|
status = 'no';
|
|
}
|
|
}
|
|
else if (direction == 'left') {
|
|
if ((pl[0] - pl[3]) <= twirlSpace.left || ((pl[7] != vrp[7]) && (pl[1] == vrp[1]) && (pl[0] + pl[3]) == (vrp[0] + vrp[2]))) {
|
|
status = 'no';
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
if (laid == 1) {
|
|
$.each(v, function(ir,pl) {
|
|
|
|
if (pl[1] <= twirlSpace.top && pl[4] != 'falling') {
|
|
status = 'game over';
|
|
gameOver();
|
|
}
|
|
pl[4] = 'laid';
|
|
});
|
|
|
|
}
|
|
});
|
|
return status;
|
|
}
|
|
|
|
function gameOver() {
|
|
twirlctx.fillStyle = 'beige';
|
|
|
|
twirlctx.fillRect(twirlSpace.left, twirlSpace.top, twirlSpace.right, twirlSpace.bottom);
|
|
twirlctx.fillStyle = 'black';
|
|
twirlctx.fillText('Game Over!', (twirlSpace.left + (twirlSpace.right / 2) - (twirlctx.measureText('Game Over!').width / 2)), (twirlSpace.top + (twirlSpace.bottom / 2)));
|
|
twirlctx.fill();
|
|
clearInterval(dropper);
|
|
twirlSpace.paused = true;
|
|
twirlSpace.score = 0;
|
|
tPieces = [];
|
|
}
|
|
document.addEventListener("visibilitychange", function(e) {
|
|
|
|
if (e.returnValue == true) {
|
|
twirlSpace.paused = true;
|
|
pauseGame();
|
|
}
|
|
});
|
|
drawTwirl();
|
|
}
|
|
|
|
twirlGame(); |