So I’ve made a port of tetris using gscript. Ever since I saw a screenshot of a tetris game running on Graal 2001 it became my main goal.
It made me realize also that programming wasn’t that hard and that if kids could put tetris in graal, why couldn’t I?
So here it is… it’s not fully complete… it doesn’t speed up with the score but I have other plans for it.
[CODE]//NPC made by 2ndwolf
if (created) {
playerx =10;
playery = 10;
//Global Vars
//Init
alltetrominos =
//Z
{1,1,0,0,
0,1,1,0,
0,0,0,0,
0,0,0,0,
0,1,0,0,
1,1,0,0,
1,0,0,0,
0,0,0,0,
1,1,0,0,
0,1,1,0,
0,0,0,0,
0,0,0,0,
0,1,0,0,
1,1,0,0,
1,0,0,0,
0,0,0,0,
//S
0,1,1,0,
1,1,0,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
1,1,0,0,
0,1,0,0,
0,0,0,0,
0,1,1,0,
1,1,0,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
1,1,0,0,
0,1,0,0,
0,0,0,0,
//L
1,0,0,0,
1,0,0,0,
1,1,0,0,
0,0,0,0,
1,1,1,0,
1,0,0,0,
0,0,0,0,
0,0,0,0,
1,1,0,0,
0,1,0,0,
0,1,0,0,
0,0,0,0,
0,0,1,0,
1,1,1,0,
0,0,0,0,
0,0,0,0,
//J
0,1,0,0,
0,1,0,0,
1,1,0,0,
0,0,0,0,
1,0,0,0,
1,1,1,0,
0,0,0,0,
0,0,0,0,
1,1,0,0,
1,0,0,0,
1,0,0,0,
0,0,0,0,
1,1,1,0,
0,0,1,0,
0,0,0,0,
0,0,0,0,
//O
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0,
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0,
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0,
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0,
//I
1,1,1,1,
0,0,0,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0,
1,1,1,1,
0,0,0,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0,
//T
1,1,1,0,
0,1,0,0,
0,0,0,0,
0,0,0,0,
0,1,0,0,
1,1,0,0,
0,1,0,0,
0,0,0,0,
0,1,0,0,
1,1,1,0,
0,0,0,0,
0,0,0,0,
1,0,0,0,
1,1,0,0,
1,0,0,0,
0,0,0,0};
tetromino.colors =
{ 1,0,0,
1,1,0,
0,0,1,
.8,.33,0,
0,.6,1,
.4,1,0,
1,0,1};
tetromino.type = 0;
tetromino.type.wait = 0;
imgindexs = 100;
tetromino.allflips = 64;
tetromino.oneflip = 16;
tetromino.width = 4;
playing.board.width = 10;
playing.board.height = 20;
playing.limits.width = 12;
playing.board.start = 4;
playing.prevision.width = 8;
tetromino.falling = 0;
tetromino.falling.dropstate = -1;
tetromino.destroying = -1;
game.speed = 20;
game.origin = {10,10};
atomsize = {1,1};
setarray this.key,10;
playing.board =
{0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0};
playing.board.previous =
{0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0};
setarray this.coords,arraylen(playing.board)*2;
setarray tetromino.atoms.pos,tetromino.oneflip;
setarray tetromino.atoms.oldpos,tetromino.oneflip;
setarray atom.type,arraylen(playing.board);
setarray freseen.indexs,4;
for(this.i=0;this.i<arraylen(this.coords)/2;this.i++){
this.coords[this.i*2] = game.origin[0]+this.i-int(this.i/playing.board.width)playing.board.width;
this.coords[this.i2+1] = game.origin[1]+int(this.i/playing.board.width);
if(this.i<arraylen(freseen.indexs)){
freseen.indexs[this.i] = imgindexs;
imgindexs++;
}
}
foreseetetromino();
detach();
this.timeout.time = 0.05;
timeout = this.timeout.time;
}
if(timeout){
tetromino.pushed.down = 0;
//tetromino.falling.dropstate -1 = just dropped
//tetromino.falling.dropstate 0 = new tetromino required
//tetromino.falling.dropstate 1 = tetromino falling
//tetromino.destroying = 1 destroy lines
//tetromino.destroying = 0 drop lines
//tetromino.destroying =-1 done
if (tetromino.falling.dropstate==-1){
detach();
}
if(tetromino.falling.dropstate == 0){
if(tetromino.destroying==-1){
addtetromino();
foreseetetromino();
tetromino.falling.dropstate = 1;
} else if (tetromino.destroying==1){
destroylines();
} else if (tetromino.destroying==0) {
droplines();
}
}
get_Keys();
if (this.key[1]>0) {
if(this.movloop%4==0){
moveleft();
} else if (this.key[1]==1) {
this.movloop = 1;
moveleft();
}
}
if (this.key[3]>0) {
if(this.movloop%4==0){
moveright();
} else if (this.key[1]==1) {
this.movloop = 1;
moveright();
}
}
if(this.key[0]==1){
rotatetetromino();
}
if (this.key[2]>0) {
testdropstate();
if(tetromino.falling.dropstate==1){
tetromino.pushed.down = 1;
movedown();
}
}
if(tetromino.pushed.down!=1&&this.loop%20==0){
testdropstate();
if(tetromino.falling.dropstate>0) naturalfall();
}
draw();
freezeplayer this.timeout.time;
hideplayer this.timeout.time;
this.loop++;
this.movloop++;
timeout = this.timeout.time;
}
function testdropstate(){
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
if(tetromino.atoms.pos[this.i]!=-1) atom.type[tetromino.atoms.pos[this.i]] = tetromino.falling;
if(tetromino.atoms.pos[this.i]!=-1 && (
tetromino.atoms.pos[this.i]+11>arraylen(playing.board)||
(playing.board[tetromino.atoms.pos[this.i]+10]>0 &&
!(tetromino.atoms.pos[this.i]+10 in tetromino.atoms.pos)))){
tetromino.falling.dropstate = -1;
}
}
}
function foreseetetromino(){
tetromino.foreseen = int(random(0,7));
freseen.startindex = tetromino.allflips*tetromino.foreseen;
this.o = 0;
for(this.i=0;this.i<tetromino.oneflip;this.i++){
if(alltetrominos[freseen.startindex+this.i]==1){
showimg freseen.indexs[this.o],tetromino_atom.gif,25+this.i%tetromino.width,25+int(this.i/tetromino.width);
changeimgcolors freseen.indexs[this.o],tetromino.colors[tetromino.foreseen3],tetromino.colors[tetromino.foreseen3+1],
tetromino.colors[tetromino.foreseen*3+2],1;
this.o++;
}
}
}
function detach(){
tetromino.falling.dropstate = 0;
//Check for lines to destroy
for(this.i=0;this.i<arraylen(playing.board)/playing.board.width;this.i++){
line.filling = 0;
for(this.j=0;this.j<playing.board.width;this.j++){
if(playing.board[this.i*playing.board.width+this.j]>0)line.filling++;
}
if(line.filling==playing.board.width){
addstring lines.filled,#v(this.i);
}
}
if(sarraylen(lines.filled)>0)tetromino.destroying = 1;
}
function addtetromino(){
// saved.loop = this.loop;
tetromino.rotate = 0;
tetromino.falling = tetromino.foreseen;
tetromino.startindex = tetromino.allflipstetromino.falling;
this.o = 0;
for(this.i=0;this.i<tetromino.oneflip;this.i++){
if(alltetrominos[tetromino.startindex+this.i]==1){
//Array of Positions on board for hit detection
tetromino.atoms.pos[this.i] = playing.board.start+this.i+(int(this.i/tetromino.width)(playing.board.width-tetromino.width));
//Placed img indexes on board for drawing
playing.board[tetromino.atoms.pos[this.i]] = imgindexs;
imgindexs++;
} else tetromino.atoms.pos[this.i] = -1;
}
}
function destroylines(){
for(this.i=0;this.i<sarraylen(lines.filled);this.i++){
for(this.j=0;this.j<playing.board.width;this.j++){
hideimg playing.board[strtofloat(#I(lines.filled,this.i))*playing.board.width+this.j];
playing.board[strtofloat(#I(lines.filled,this.i))*playing.board.width+this.j] = 0;
}
}
tetromino.destroying = 0;
}
function droplines(){
lines.falling = 0;
for(this.i=sarraylen(lines.filled)-1;this.i>=0;this.i–){
lines.falling++;
for(this.j=strtofloat(#I(lines.filled,this.i))playing.board.width+(playing.board.widthlines.falling)-1;this.j>0;this.j–){
if(this.j<arraylen(playing.board)&&this.j-playing.board.widthlines.falling>=0){
playing.board[this.j] = playing.board[this.j-playing.board.width];
atom.type[this.j] = atom.type[this.j-playing.board.width];
} else if (this.j-playing.board.widthlines.falling<0){
playing.board[this.j] = 0;
}
}
}
tetromino.destroying = -1;
unset lines.filled;
}
function draw(){
for(this.i=0;this.i<arraylen(playing.board);this.i++){
if(playing.board.previous[this.i]>0&&playing.board[this.i]==0){
hideimg playing.board.previous[this.i];
}
if(playing.board[this.i]!=0){
showimg playing.board[this.i],tetromino_atom.gif,this.coords[this.i2],this.coords[this.i2+1];
changeimgcolors playing.board[this.i],tetromino.colors[atom.type[this.i]*3],tetromino.colors[atom.type[this.i]*3+1],
tetromino.colors[atom.type[this.i]*3+2],1;
}
playing.board.previous[this.i] = playing.board[this.i];
}
for(this.i=imgindexs-1;this.i>imgindexs-5;this.i–){
changeimgcolors this.i,tetromino.colors[tetromino.falling3],tetromino.colors[tetromino.falling3+1],
tetromino.colors[tetromino.falling*3+2],1;
}
}
function rotatetetromino(){
tetromino.rotate = (tetromino.rotate+1)%4;
tetromino.startindex = (tetromino.allflipstetromino.falling)+(tetromino.rotatetetromino.oneflip);
if(tetromino.atoms.pos[0]==-1&&tetromino.atoms.pos[1]==-1)tetromino.board.pos = tetromino.atoms.pos[2]-2;
else if (tetromino.atoms.pos[0]==-1) tetromino.board.pos = tetromino.atoms.pos[1]-1;
else tetromino.board.pos = tetromino.atoms.pos[0];
this.o = 0;
this.undo = 0;
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
tetromino.atoms.oldpos[this.i] = tetromino.atoms.pos[this.i];
}
for(this.i=0;this.i<tetromino.oneflip;this.i++){
if(alltetrominos[tetromino.startindex+this.i]==1){
//Array of Positions on board for hit detection
tetromino.atoms.pos[this.i] = tetromino.board.pos+this.i+(int(this.i/tetromino.width)*(playing.board.width-tetromino.width));
if(playing.board[tetromino.atoms.pos[this.i]]!=0 &&
!(tetromino.atoms.pos[this.i] in tetromino.atoms.oldpos)||
(this.i>0 &&
int(tetromino.atoms.pos[this.i]%playing.board.width)==0 &&
int(tetromino.atoms.pos[this.i-1]%playing.board.width)==9)||
tetromino.atoms.pos[this.i]>arraylen(playing.board)) {
for(this.j=0;this.j<arraylen(tetromino.atoms.pos);this.j++){
this.undo = 1;
break;
}
}
} else tetromino.atoms.pos[this.i] = -1;
}
if(this.undo==1){
tetromino.rotate = (tetromino.rotate-1)%4;
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
tetromino.atoms.pos[this.i] = tetromino.atoms.oldpos[this.i];
}
} else {
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
if(tetromino.atoms.oldpos[this.i]!=-1){
hideimg playing.board[tetromino.atoms.oldpos[this.i]];
playing.board[tetromino.atoms.oldpos[this.i]] = 0;
}
if(tetromino.atoms.pos[this.i]!=-1){
playing.board[tetromino.atoms.pos[this.i]] = imgindexs;
imgindexs++;
}
}
}
}
function moveright(){
none.zero = 1;
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
if((tetromino.atoms.pos[this.i]+1)%playing.board.width==0 ||
(playing.board[tetromino.atoms.pos[this.i]+1] != 0 &&
!(tetromino.atoms.pos[this.i]+1 in tetromino.atoms.pos))){
if(tetromino.atoms.pos[this.i]!=-1){
none.zero=0;
break;
}
}
}
if(none.zero==1){
for(this.i=arraylen(tetromino.atoms.pos)-1;this.i>=0;this.i–){
if(tetromino.atoms.pos[this.i]!=-1){
playing.board[tetromino.atoms.pos[this.i]+1] = playing.board[tetromino.atoms.pos[this.i]];
playing.board[tetromino.atoms.pos[this.i]] = 0;
tetromino.atoms.pos[this.i] += 1;
}
}
}
}
function moveleft(){
none.zero = 1;
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
if(tetromino.atoms.pos[this.i]!=-1 && (
(tetromino.atoms.pos[this.i]-1)%playing.board.width==9 ||
(playing.board[tetromino.atoms.pos[this.i]-1] != 0 &&
!(tetromino.atoms.pos[this.i]-1 in tetromino.atoms.pos)))){
none.zero=0;
break;
}
}
if(none.zero==1){
for(this.i=0;this.i<arraylen(tetromino.atoms.pos);this.i++){
if(tetromino.atoms.pos[this.i]!=-1){
playing.board[tetromino.atoms.pos[this.i]-1] = playing.board[tetromino.atoms.pos[this.i]];
playing.board[tetromino.atoms.pos[this.i]] = 0;
tetromino.atoms.pos[this.i] -= 1;
}
}
}
}
function movedown(){
for(this.i=arraylen(tetromino.atoms.pos)-1;this.i>=0;this.i–){
if(tetromino.atoms.pos[this.i]!=-1){
playing.board[tetromino.atoms.pos[this.i]+playing.board.width] = playing.board[tetromino.atoms.pos[this.i]];
playing.board[tetromino.atoms.pos[this.i]] = 0;
tetromino.atoms.pos[this.i] += playing.board.width;
}
}
}
function naturalfall(){
for(this.i=arraylen(tetromino.atoms.pos)-1;this.i>=0;this.i–){
if(tetromino.atoms.pos[this.i]!=-1){
playing.board[tetromino.atoms.pos[this.i]+playing.board.width] = playing.board[tetromino.atoms.pos[this.i]];
playing.board[tetromino.atoms.pos[this.i]] = 0;
tetromino.atoms.pos[this.i] += playing.board.width;
}
}
}
function get_Keys(){
for (this.keyCheck = 0;this.keyCheck < 10; this.keyCheck++){
if (keydown(this.keyCheck))
this.key[this.keyCheck] = (this.key[this.keyCheck] == 0)?1:2;//1 = pressed,2 = held
else
this.key[this.keyCheck] = (this.key[this.keyCheck]>0)?-1:0;//-1 = released, 0 = not held
}
}[/CODE]