redone representation of shapes
parent
5a82790651
commit
9daba643aa
190
shapes.js
190
shapes.js
|
@ -1,190 +0,0 @@
|
|||
var shapes = [
|
||||
[ [[0,0],[1,0],[0,1],[1,1]] ], //box
|
||||
|
||||
[ [[1,0],[1,1],[1,2],[1,3]],
|
||||
[[0,1],[1,1],[2,1],[3,1]] ], //|
|
||||
|
||||
[ [[0,0],[0,1],[1,1],[1,2]],
|
||||
[[1,0],[2,0],[0,1],[1,1]] ], //s
|
||||
|
||||
[ [[1,0],[0,1],[1,1],[0,2]],
|
||||
[[0,0],[1,0],[1,1],[2,1]] ], //z
|
||||
|
||||
[ [[0,0],[1,0],[0,1],[0,2]], //r
|
||||
[[0,0],[0,1],[1,1],[2,1]],
|
||||
[[1,0],[1,1],[0,2],[1,2]],
|
||||
[[0,0],[1,0],[2,0],[2,1]] ],
|
||||
|
||||
[ [[0,0],[0,1],[0,2],[1,2]],
|
||||
[[0,1],[1,1],[2,1],[2,0]],
|
||||
[[0,0],[1,0],[1,1],[1,2]],
|
||||
[[0,0],[1,0],[2,0],[0,1]] ], //l
|
||||
|
||||
[ [[0,0],[1,0],[2,0],[1,1]],
|
||||
[[0,0],[0,1],[1,1],[0,2]],
|
||||
[[0,1],[1,1],[2,1],[1,0]],
|
||||
[[1,1],[2,0],[2,1],[2,2]] ], //t
|
||||
];
|
||||
|
||||
// var b_shape = {
|
||||
// "color" : 1,
|
||||
// "rotations" : 1,
|
||||
// "data": [
|
||||
// { "x" : 2,
|
||||
// "y" : 2,
|
||||
// "val" : [ [1, 1, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] }
|
||||
// ]
|
||||
// }
|
||||
|
||||
// var s_shape = {
|
||||
// "color" : 2,
|
||||
// "rotations" : 2,
|
||||
// "data": [
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [1, 0, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [0, 1, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [0, 1, 1, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// ]
|
||||
// }
|
||||
|
||||
// var z_shape = {
|
||||
// "color" : 3,
|
||||
// "rotations" : 2,
|
||||
// "data": [
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [0, 1, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [1, 1, 0, 0],
|
||||
// [0, 1, 1, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// ]
|
||||
// }
|
||||
|
||||
// var i_shape = {
|
||||
// "color" : 4,
|
||||
// "rotations" : 2,
|
||||
// "data": [
|
||||
// { "x" : 1,
|
||||
// "y" : 4,
|
||||
// "val" : [ [1, 0, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [1, 0, 0, 0] ] },
|
||||
// { "x" : 4,
|
||||
// "y" : 1,
|
||||
// "val" : [ [1, 1, 1, 1],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// ]
|
||||
// }
|
||||
|
||||
// var r_shape = {
|
||||
// "color" : 5,
|
||||
// "rotations" : 4,
|
||||
// "data": [
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [1, 1, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [1, 1, 1, 0],
|
||||
// [0, 0, 1, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [0, 1, 0, 0],
|
||||
// [0, 1, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [1, 0, 0, 0],
|
||||
// [1, 1, 1, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// ]
|
||||
// }
|
||||
|
||||
// var l_shape = {
|
||||
// "color" : 6,
|
||||
// "rotations" : 4,
|
||||
// "data": [
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [1, 0, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [1, 1, 1, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [1, 1, 0, 0],
|
||||
// [0, 1, 0, 0],
|
||||
// [0, 1, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [0, 0, 1, 0],
|
||||
// [1, 1, 1, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// ]
|
||||
// }
|
||||
|
||||
// var t_shape = {
|
||||
// "color" : 7,
|
||||
// "rotations" : 4,
|
||||
// "data": [
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [0, 1, 0, 0],
|
||||
// [1, 1, 1, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [1, 0, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [1, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 3,
|
||||
// "y" : 2,
|
||||
// "val" : [ [1, 1, 1, 0],
|
||||
// [0, 1, 0, 0],
|
||||
// [0, 0, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// { "x" : 2,
|
||||
// "y" : 3,
|
||||
// "val" : [ [0, 1, 0, 0],
|
||||
// [1, 1, 0, 0],
|
||||
// [0, 1, 0, 0],
|
||||
// [0, 0, 0, 0] ] },
|
||||
// ]
|
||||
// }
|
11
tetris.html
11
tetris.html
|
@ -1,7 +1,7 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>tetris</title>
|
||||
<script type="text/javascript" src="shapes.js"></script>
|
||||
<!-- <script type="text/javascript" src="shapes.js"></script> -->
|
||||
<script type="text/javascript" src="tetris.js"></script>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
|
@ -23,9 +23,12 @@
|
|||
background-color:gray;
|
||||
}
|
||||
</style>
|
||||
<canvas id="canvas" width="200" height="400"></canvas>
|
||||
<canvas id="preview" width=80 height=80></canvas>
|
||||
reload to start a new game. use a/f keys to rotate and h/l to go
|
||||
<canvas id="canvas" width=200 height=400></canvas>
|
||||
<canvas id="preview" width=100 height=120></canvas>
|
||||
<br />
|
||||
reload to start a new game.
|
||||
<br />
|
||||
use a/f keys to rotate and h/l to go
|
||||
left or right, space to drop.
|
||||
</div>
|
||||
<div id="status">
|
||||
|
|
192
tetris.js
192
tetris.js
|
@ -1,16 +1,40 @@
|
|||
//really simple tetris in canvas element
|
||||
//2009 obneq
|
||||
//2009, 2010 obneq
|
||||
|
||||
document.onkeyup=key;
|
||||
|
||||
var shapes = [b_shape, s_shape, z_shape, i_shape, l_shape, r_shape, t_shape];
|
||||
var colors = ["rgb(13, 13, 13)", "rgb(200, 13, 13)",
|
||||
"rgb(13, 200, 13)", "rgb(13, 13, 200)",
|
||||
"rgb(200, 200, 13)", "rgb(200, 13, 200)",
|
||||
"rgb(13, 200, 200)", "rgb(200, 200, 200)"];
|
||||
|
||||
var levels = [888, 666, 555, 444, 404, 333, 303, 222, 202, 111, 101];
|
||||
var levels = [777, 666, 555, 444, 404, 333, 303, 222, 202, 111, 101];
|
||||
var run;
|
||||
var shapes = [ [ [[0,0],[1,0],[0,1],[1,1]] ], //box
|
||||
|
||||
[ [[1,0],[1,1],[1,2],[1,3]],
|
||||
[[0,1],[1,1],[2,1],[3,1]] ], //line
|
||||
|
||||
[ [[0,0],[0,1],[1,1],[1,2]],
|
||||
[[1,0],[2,0],[0,1],[1,1]] ], //s
|
||||
|
||||
[ [[1,0],[0,1],[1,1],[0,2]],
|
||||
[[0,0],[1,0],[1,1],[2,1]] ], //z
|
||||
|
||||
[ [[1,0],[2,0],[1,1],[1,2]],
|
||||
[[0,0],[0,1],[1,1],[2,1]],
|
||||
[[1,0],[1,1],[0,2],[1,2]],
|
||||
[[0,1],[1,1],[2,1],[2,2]] ], //r
|
||||
|
||||
[ [[1,0],[1,1],[1,2],[2,2]],
|
||||
[[0,1],[1,1],[2,1],[2,0]],
|
||||
[[0,0],[1,0],[1,1],[1,2]],
|
||||
[[0,1],[1,1],[2,1],[0,2]] ], //l
|
||||
|
||||
[ [[0,0],[1,0],[2,0],[1,1]],
|
||||
[[0,0],[0,1],[1,1],[0,2]],
|
||||
[[0,2],[1,2],[2,2],[1,1]],
|
||||
[[1,1],[2,0],[2,1],[2,2]] ], ]; //t
|
||||
|
||||
function board(x, y){
|
||||
//constructs a new empty board
|
||||
|
@ -22,24 +46,15 @@ function board(x, y){
|
|||
board[i]=new Array(y);
|
||||
return board;
|
||||
}(x, y);
|
||||
|
||||
this.max_pos = y;
|
||||
|
||||
this.add = function(s){
|
||||
//shapes get added to the board only after
|
||||
//shapes are added to the board after
|
||||
//they cant be moved anymore
|
||||
|
||||
//d is a shortcut, this "pattern" is used
|
||||
//everywhere...
|
||||
var d = s.Shape.data[s.Rotation];
|
||||
for(var i=0; i<d.x; i++)
|
||||
for(var j=0; j<d.y; j++)
|
||||
//FIXME: indexing of shapes and board is braindamaged.
|
||||
//its [y][x] for shapes and [x][y] for the board!
|
||||
if(d.val[j][i])
|
||||
this.val[s.Xpos+i][s.Ypos+j] = s.Shape.color;
|
||||
var d=s.Shape[s.Rotation]
|
||||
for(var i=0; i<4; i++)
|
||||
this.val[s.Xpos+d[i][0]][s.Ypos+d[i][1]]=s.Color;
|
||||
}
|
||||
|
||||
|
||||
this.check_lines=function(){
|
||||
//this function checks the board
|
||||
//for full lines and collapses them
|
||||
|
@ -53,12 +68,11 @@ function board(x, y){
|
|||
for(var i=0; i<this.x; i++)
|
||||
if(!this.val[i][l])
|
||||
return false;
|
||||
this.max_pos++;
|
||||
status.lines++;
|
||||
status.check_level();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
this.scroll=function(l){
|
||||
while(--l)
|
||||
for(var i=0; i<this.x; i++)
|
||||
|
@ -70,37 +84,36 @@ function shape (){
|
|||
//constructs a new random shape
|
||||
this.Xpos = 4;
|
||||
this.Ypos = 0;
|
||||
this.Shape=shapes[Math.floor(Math.random()*7)]
|
||||
var id = Math.floor(Math.random()*7);
|
||||
this.Color=id+1;
|
||||
this.Shape=shapes[id];
|
||||
this.Rotation = 0;
|
||||
|
||||
this.move=function(x,y){
|
||||
//move if new position is valid
|
||||
var d=this.Shape.data[this.Rotation];
|
||||
var newX = this.Xpos + x;
|
||||
var newY = this.Ypos + y;
|
||||
//enforce board bounds
|
||||
newX=Math.max(0, Math.min(newX, board.x - d.x));
|
||||
newY=Math.max(0, Math.min(newY, board.y - d.y));
|
||||
//check for obstacles on board
|
||||
if(this.check_move(newX, newY)){
|
||||
this.Xpos = newX;
|
||||
this.Ypos = newY;
|
||||
}
|
||||
if(!this.check_position(newX, newY, this.Rotation))
|
||||
return;
|
||||
this.Xpos = newX;
|
||||
this.Ypos = newY;
|
||||
view.update();
|
||||
}
|
||||
|
||||
this.rotate = function(r){
|
||||
//rotate if new position is valid
|
||||
//make cw and ccw rotation work
|
||||
var newrot = (this.Rotation+r)%this.Shape.rotations;
|
||||
var newrot = (this.Rotation+r)%this.Shape.length;
|
||||
if (newrot<0)
|
||||
newrot=this.Shape.rotations+newrot;
|
||||
newrot=this.Shape.length+newrot;
|
||||
//check for obstacles on board
|
||||
if (this.check_rotation(newrot))
|
||||
this.Rotation = newrot;
|
||||
if (!this.check_position(this.Xpos, this.Ypos, newrot))
|
||||
return;
|
||||
this.Rotation = newrot;
|
||||
view.update();
|
||||
}
|
||||
|
||||
|
||||
this.drop=function(){
|
||||
while(!this.stuck())
|
||||
this.Ypos+=1;
|
||||
|
@ -108,36 +121,22 @@ function shape (){
|
|||
}
|
||||
}
|
||||
|
||||
//dont mind the weird indexes, see above...
|
||||
shape.prototype.check_move=function(newX, newY){
|
||||
var d = this.Shape.data[this.Rotation];
|
||||
for(var i=0; i<d.x; i++)
|
||||
for(var j=0; j<d.y; j++)
|
||||
if(d.val[j][i] && board.val[newX + i][newY + j])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
shape.prototype.check_rotation=function (r){
|
||||
var d = this.Shape.data[r];
|
||||
if(this.Ypos+d.y > board.y || this.Xpos+d.x > board.x)
|
||||
return false;
|
||||
for(var i=0; i<d.x; i++)
|
||||
for(var j=0; j<d.y; j++)
|
||||
if(d.val[j][i] && board.val[this.Xpos + i][this.Ypos + j])
|
||||
return false;
|
||||
shape.prototype.check_position=function(newX, newY, newR){
|
||||
var d = this.Shape[newR];
|
||||
for(var i=0; i<4; i++){
|
||||
if((newX+d[i][0]<0 || newX+d[i][0]>=board.x) ||
|
||||
(newY+d[i][1]<0 || newY+d[i][1]>=board.y))
|
||||
return false;
|
||||
if(board.val[newX+d[i][0]][newY+d[i][1]])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
shape.prototype.stuck=function (){
|
||||
var d = this.Shape.data[this.Rotation];
|
||||
if(this.Ypos + d.y==board.y)
|
||||
return true;
|
||||
for(i=0; i<d.x; i++)
|
||||
for(j=0; j<d.y; j++)
|
||||
if(d.val[j][i] && board.val[this.Xpos + i][this.Ypos + j + 1])
|
||||
return true;
|
||||
return false;
|
||||
if(this.check_position(this.Xpos, this.Ypos+1, this.Rotation))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function view(size){
|
||||
|
@ -147,32 +146,35 @@ function view(size){
|
|||
this.ctx.strokeStyle = colors[0];
|
||||
this.xsize=board.x*size;
|
||||
this.ysize=board.y*size;
|
||||
|
||||
this.update=function(){
|
||||
|
||||
this.update=function() {
|
||||
//draw the board and the current shape
|
||||
var d=current.Shape.data[current.Rotation];
|
||||
this.ctx.clearRect(0, 0, this.xsize, this.ysize);
|
||||
this.draw_board();
|
||||
for (var i=0; i<d.y; i++)
|
||||
for (var j=0; j<d.x; j++)
|
||||
if(d.val[i][j]) {
|
||||
this.ctx.fillStyle = colors[current.Shape.color];
|
||||
this.ctx.fillRect((current.Xpos + j) * size,
|
||||
(current.Ypos + i) * size, size, size);
|
||||
this.ctx.strokeRect((current.Xpos + j) * size,
|
||||
(current.Ypos + i) * size, size, size);
|
||||
}
|
||||
var c=current.Shape[current.Rotation];
|
||||
|
||||
this.ctx.fillStyle = colors[current.Color];
|
||||
for(var i=0; i<4; i++){
|
||||
this.ctx.fillRect((c[i][0]+current.Xpos)*size,
|
||||
(c[i][1]+current.Ypos)*size,
|
||||
size, size);
|
||||
|
||||
this.ctx.strokeRect((c[i][0]+current.Xpos)*size,
|
||||
(c[i][1]+current.Ypos)*size,
|
||||
size, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.draw_board=function(){
|
||||
//draw the board
|
||||
for (var i=board.max_pos; i<board.y; i++)
|
||||
for (var i=0; i<board.y; i++)
|
||||
for(var j=0; j<board.x; j++){
|
||||
var b=board.val[j][i];
|
||||
if(b){
|
||||
this.ctx.fillStyle=colors[b];
|
||||
this.ctx.fillRect(j * size, i * size, size, size);
|
||||
this.ctx.strokeRect(j * size, i * size, size, size);
|
||||
this.ctx.fillRect(j*size, i*size, size, size);
|
||||
this.ctx.strokeRect(j*size, i*size, size, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,22 +187,21 @@ function preview(size){
|
|||
this.ctx.strokeStyle = colors[0];
|
||||
|
||||
this.update=function(){
|
||||
this.ctx.clearRect(0, 0, 4*size, 4*size);
|
||||
var d=next.Shape.data[next.Rotation];
|
||||
for (var i=0; i<d.y; i++)
|
||||
for (var j=0; j<d.x; j++)
|
||||
if(d.val[i][j]) {
|
||||
this.ctx.fillStyle = colors[next.Shape.color];
|
||||
this.ctx.fillRect(j*size, i*size, size, size);
|
||||
this.ctx.strokeRect(j*size, i*size, size, size);
|
||||
}
|
||||
this.ctx.clearRect(0, 0, 5*size, 6*size);
|
||||
var d=next.Shape[0];
|
||||
for (var i=0; i<4; i++) {
|
||||
this.ctx.fillStyle = colors[next.Color];
|
||||
this.ctx.fillRect(size+d[i][0]*size, size+d[i][1]*size, size, size);
|
||||
this.ctx.strokeRect(size+d[i][0]*size, size+d[i][1]*size, size, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function status(){
|
||||
this.lines=0;
|
||||
this.level=0;
|
||||
this.level=1;
|
||||
var s=document.getElementById("status");
|
||||
|
||||
this.check_level=function(){
|
||||
if(this.lines%10==0){
|
||||
clearInterval(run);
|
||||
|
@ -215,12 +216,13 @@ function status(){
|
|||
}
|
||||
|
||||
function key(e){
|
||||
//stolen from the internet...
|
||||
//next 4 lines stolen from the internet...
|
||||
var evt=(e)?e:(window.event)?window.event:null;
|
||||
if(evt){
|
||||
var key=(evt.charCode)?evt.charCode:
|
||||
var key=(evt.charCode)?evt.charCode:
|
||||
((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
|
||||
//vi-style keys. you are allowed to move a shape up for now.
|
||||
//vi-style keys. you are allowed
|
||||
//to move a shape up for now.
|
||||
if(key=="74")
|
||||
current.move(0, 1);
|
||||
else if(key=="75")
|
||||
|
@ -241,13 +243,12 @@ function key(e){
|
|||
function step(){
|
||||
//the main loop
|
||||
if(current.stuck()){
|
||||
//the board starts at top left... more braindamage
|
||||
board.max_pos=Math.min(current.Ypos, board.max_pos);
|
||||
board.add(current);
|
||||
if(board.max_pos<=0)
|
||||
if(current.Ypos==0)
|
||||
clearInterval(run);
|
||||
//FIXME: add scoring
|
||||
board.add(current);
|
||||
board.check_lines();
|
||||
if(!next.check_position(next.Xpos, next.Ypos, next.Rotation))
|
||||
return;
|
||||
current = next;
|
||||
next = new shape();
|
||||
preview.update();
|
||||
|
@ -258,9 +259,7 @@ function step(){
|
|||
}
|
||||
|
||||
function new_game(){
|
||||
//board size
|
||||
board = new board(10,20);
|
||||
//size of one unit in pixel
|
||||
next = new shape();
|
||||
current = new shape();
|
||||
view = new view(20);
|
||||
|
@ -271,6 +270,5 @@ function new_game(){
|
|||
preview.update();
|
||||
view.update();
|
||||
//go!
|
||||
run=setInterval(step, 666);
|
||||
run=setInterval(step, levels[0]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue