The following video shows the java code in action:
The tetris game Java source code is as follows:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Tetris extends JFrame{
boolean stopthread=false;
int SIZE_HORIZ=13;
int SIZE_VERTI=35;
Graphics g;
boolean waitnow=false;
int[][] board=new int[SIZE_VERTI][SIZE_HORIZ];
int t_[]={1,0,1,1,1,2,2,1};
int t_90[]={0,1,1,0,1,1,2,1};
int t_180[]={0,1,1,0,1,1,1,2};
int t_270[]={0,1,1,1,1,2,2,1};
int l_[]={0,2,1,0,1,1,1,2};
int l_90[]={0,1,1,1,2,1,2,2};
int l_180[]={1,0,1,1,1,2,2,0};
int l_270[]={0,0,0,1,1,1,2,1};
int s_[]={0,0,0,1,1,0,1,1};
int z_[]={1,1,1,2,2,0,2,1};
int z_90[]={0,1,1,1,1,2,2,2};
int i_ver[]={0,1,1,1,2,1,3,1};
int i_hor[]={1,0,1,1,1,2,1,3};
String scorestr;
Random rand=new Random(System.currentTimeMillis());
Color colors[]={Color.BLUE,Color.GREEN,Color.MAGENTA,Color.RED,Color.YELLOW};
File HighScore;
Color bgcolor=Color.WHITE;
/*
Numbering for blocks:
(values of fallingBlockNumber)
0=T
1=L
2=S
3=Z
4=I
*/
int [] blockarray;
int fallingblockNum;
int fallingBlockVersion=0;
int fallingBlockRow=0;
int fallingBlockCol=0;
int startdelay=200;
int motiondelay;
int scoreInc=5;
int myscore=0;
int tversion;
boolean spawn=true;
int scorespeedctrl=0;
int timehalving=0;
String highscoreholder;
int highscore;
KeyListener kl;
public Tetris()
{
int i,j;
startdelay=250;
scoreInc=5;
myscore=0;
motiondelay=startdelay;
NextBlock();
for(i=0;i<35;i++)
for(j=0;j<13;j++)
board[i][j]=0;
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(480,500);
setResizable(false);
setLocationRelativeTo(null);
HighScore=new File(System.getProperty("java.io.tmpdir")+File.separator+"TetrisHighScore");
try{
if(HighScore.exists())
{
BufferedReader br=new BufferedReader(new FileReader(HighScore));
highscoreholder=br.readLine();
highscore=Integer.parseInt(br.readLine());
br.close();
}
else
{
highscoreholder=null;
highscore=0;
}
}catch(Exception ex){}
kl=new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if(!spawn&&!waitnow)
{
waitnow=true;
int key=e.getKeyCode();
if(key==KeyEvent.VK_UP)//up
{
if(fallingblockNum==0||fallingblockNum==1)
tversion=(fallingBlockVersion+1)%4;
else if(fallingblockNum==4||fallingblockNum==3)
tversion=(fallingBlockVersion+1)%2;
if(fallingblockNum!=2&&isDrawable(fallingBlockRow,fallingBlockCol,tversion))
{
clearOldBlockVersion(g);
fallingBlockVersion=tversion;
blockarray=getFallingBlockArray();
drawNewBlockVersion(g);
}
}
else if(key==KeyEvent.VK_LEFT)//left
{
if(isDrawable(fallingBlockRow,fallingBlockCol-1,fallingBlockVersion))
{
clearOldBlockVersion(g);
fallingBlockCol--;
drawNewBlockVersion(g);
}
}
else if(key==KeyEvent.VK_RIGHT)//right
{
if(isDrawable(fallingBlockRow,fallingBlockCol+1,fallingBlockVersion))
{
clearOldBlockVersion(g);
fallingBlockCol++;
drawNewBlockVersion(g);
}
}
else if(key==KeyEvent.VK_DOWN)//down
{
if(isDrawable(fallingBlockRow+1,fallingBlockCol,fallingBlockVersion))
{
clearOldBlockVersion(g);
fallingBlockRow++;
drawNewBlockVersion(g);
}
}
waitnow=false;
}
}
@Override
public void keyReleased(KeyEvent e) {}
};
th.start();
addKeyListener(kl);
}
void NextBlock()
{
fallingblockNum=rand.nextInt(5);
if(fallingblockNum==0||fallingblockNum==1)
fallingBlockVersion=rand.nextInt(4);
else if(fallingblockNum==4||fallingblockNum==3)
fallingBlockVersion=rand.nextInt(2);
else
fallingBlockVersion=0;
fallingBlockRow=0;
fallingBlockCol=5;
blockarray=getFallingBlockArray();
}
int[] getFallingBlockArray()
{
int a=fallingblockNum*10+fallingBlockVersion;
switch(a)
{
case 0:return (t_);
case 1:return (t_90);
case 2:return (t_180);
case 3:return (t_270);
case 10:return (l_);
case 11:return (l_90);
case 12:return (l_180);
case 13:return (l_270);
case 20:return (s_);
case 30:return (z_);
case 31:return (z_90);
case 40:return (i_hor);
case 41:return (i_ver);
}
return (i_ver);
}
boolean isDrawable(int newrow,int newcol,int blockversion)
{
int i,tempversion;
boolean flag=true;
tempversion=fallingBlockVersion;
fallingBlockVersion=blockversion;
blockarray=getFallingBlockArray();
for(i=0;i<8;i+=2)
{
if(newrow+blockarray[i]>34||newrow+blockarray[i]<0)
{
flag=false;
break;
}
if(newcol+blockarray[i+1]>12||newcol+blockarray[i+1]<0)
{
flag=false;
break;
}
if(board[(newrow+blockarray[i])][(newcol+blockarray[i+1])]==2)
{
flag=false;
break;
}
}
fallingBlockVersion=tempversion;
blockarray=getFallingBlockArray();
return flag;
}
void clearOldBlockVersion(Graphics g)
{
int i,r,c;
for(i=0;i<8;i+=2)
{
r=fallingBlockRow+blockarray[i];
c=fallingBlockCol+blockarray[i+1];
board[r][c]=0;
g.setColor(bgcolor);
g.fillRect(8+c*13,32+r*13,14,14);
}
}
void drawNewBlockVersion(Graphics g)
{
int i,r,c;
for(i=0;i<8;i+=2)
{
r=fallingBlockRow+blockarray[i];
c=fallingBlockCol+blockarray[i+1];
board[r][c]=1;
g.setColor(colors[fallingblockNum]);
g.fillRect(8+c*13,32+r*13,13,13);
g.setColor(Color.BLACK);//cyan,orange
g.drawRect(8+c*13,32+r*13,13,13);
}
}
boolean isGameOver(Graphics g)
{
if(isDrawable(0,5,fallingBlockVersion)==false)
return true;
drawNewBlockVersion(g);
if(isAtBottom())
return true;
return false;
}
boolean isAtBottom()
{
int i,max=0,ti,tj;
for(i=0;i<8;i+=2)
if(blockarray[i]>max)
max=blockarray[i];
if(fallingBlockRow+max>=34)
return true;
for(i=0;i<8;i+=2)
{
ti=blockarray[i]+fallingBlockRow;
tj=blockarray[i+1]+fallingBlockCol;
if(board[ti+1][tj]==2)
return true;
}
return false;
}
void showScore(Graphics g)
{
int left,top;
left=getWidth()-100;
top=getHeight()/2;
g.setColor(bgcolor);
g.fillRect(left,top,80,70);
g.setColor(Color.RED);
g.setFont(new Font("Arial",Font.BOLD,14));
g.drawString("Score: "+Integer.toString(myscore),left,top+20);
}
void CollapseFilledRow(Graphics g)
{
int i,j,k,sum,copyskipover=0,r;
for(i=34;i>=0;)
{
sum=0;//full flag
for(j=0;j<13;j++)
sum+=board[i][j];
if(sum==2*13)//row full
{
myscore+=scoreInc;
copyskipover++;
}
if(sum==0)
break;
i--;
if(copyskipover>0)
{
for(j=0;j<13;j++)
{
r=i+copyskipover;
board[r][j]=board[i][j];
if(board[i][j]==0)
{
g.setColor(bgcolor);
g.fillRect(8+j*13,32+r*13,14,14);
}
else
{
g.setColor(Color.GREEN);
g.fillRect(8+j*13,32+r*13,13,13);
g.setColor(Color.BLACK);
g.drawRect(8+j*13,32+r*13,13,13);
}
}
}
}
for(k=0;k<copyskipover;k++)
{
r=i+k;
for(j=0;j<13;j++)
{
board[r][j]=0;
g.setColor(bgcolor);
g.fillRect(8+j*13,32+r*13,14,14);
}
}
showScore(g);
}
public static void main(String[] args)
{
Tetris tt=new Tetris();
tt.setVisible(true);
}
void GameOver(Graphics g)
{
stopthread=true;
g.setColor(Color.RED);
g.setFont(new Font("Arial",Font.BOLD,28));
String str="Game Over.";
g.drawString(str,getWidth()/2-10, getHeight()/2);
if(highscore>0)
str="Highscore : "+highscoreholder+" - "+Integer.toString(highscore);
g.setFont(new Font("Arial",Font.BOLD,16));
g.drawString(str,getWidth()/2-30, getHeight()/2+80);
if(myscore>highscore)
{
highscoreholder=JOptionPane.showInputDialog("New high score. Enter your name:");
highscore=myscore;
try{
if(!HighScore.exists())
HighScore.createNewFile();
BufferedWriter bw=new BufferedWriter(new FileWriter(HighScore));
bw.write(highscoreholder);
bw.newLine();
bw.write(Integer.toString(highscore));
bw.close();
}catch(Exception ee){}
}
}
Thread th=new Thread()
{
int i;
public void run()
{
try {
while(!isShowing())
Thread.sleep(1000);
} catch (InterruptedException ex) {}
setOpacity(1f);
setBackground(bgcolor);
getContentPane().setBackground(bgcolor);
g=getGraphics();
g.setColor(Color.RED);
g.drawRect(6,30,13*13+6,35*13+6);
showScore(g);
while(!stopthread)
{
g.setColor(Color.RED);
g.drawRect(6,30,13*13+6,35*13+6);
while (waitnow)
{
try {
Thread.sleep(20);
} catch (InterruptedException ex) {}
}
waitnow=true;
if(isAtBottom()&&!spawn)
{
for(i=0;i<8;i+=2)
{
board[fallingBlockRow+blockarray[i]][fallingBlockCol+blockarray[i+1]]=2;
}
spawn=true;
CollapseFilledRow(g);
}
if(spawn)
{
NextBlock();
blockarray=getFallingBlockArray();
spawn=false;
if(isGameOver(g))
{
GameOver(g);
return;
}
}
else
{
timehalving=(timehalving+1)%3;
if(timehalving==2)
{
clearOldBlockVersion(g);
fallingBlockRow++;
drawNewBlockVersion(g);
}
}
scorespeedctrl=(scorespeedctrl+1)%140;
if(scorespeedctrl==0&&motiondelay>0)
{
motiondelay-=12;
scoreInc+=2;
if(motiondelay<0)
motiondelay=0;
}
waitnow=false;
try {
Thread.sleep(motiondelay);
} catch (InterruptedException ex) {}
}
}
};
}

