package code;
import java.awt.*;
//import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
/**
* 俄罗斯方块
* 高雷
* 2007年11月30日
*/
public class Tetris extends Canvas implements Runnable
{
private Random rand;
private Thread thread;
private Graphics gb;
private Image buffer;
private Image gameOverImg; //游戏结束
private static final int s_width = 240;
private static final int s_height = 320;
private static final int s_box_w = 16;
private static final int s_box_h = 16;
private static final int s_box_w_sum = 10; //操作区域宽 格子数
private static final int s_box_h_sum = 20; //操作区域高 格子数
private static final int s_line_between_x = s_box_w * s_box_w_sum;//分割线x位置
public static final int UP = -1;
public static final int DOWN = -2;
public static final int LEFT = -3;
public static final int RIGHT = -4;
public static final int init_x = 3; //当前方块初始化坐标X
public static final int init_y = 0; //当前方块初始化坐标y
public static int s_box_x = init_x; //当前方块坐标X
public static int s_box_y = init_y; //当前方块坐标Y
private static int level = 1; //等级
private static int success = 0; //得分
private static long goDownDelayTime[] = //1800; //下降延迟时间
{
1000, 900, 800, 700,
600, 500, 400,
300, 200, 100
};
private static int level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]); //升级成绩
private static boolean isShowReseau = true; //是否现实网格
private static short s_next_box = 0; //下一个方块编号
private static short boxColor; //当前box的颜色
private static final Color gameBG = new Color( 0x333333 ); //游戏区域背景颜色
private static final Color gameColor[] = new Color[]
{
new Color( 0x444444 ), //网格颜色
new Color( 0xEEEEEE ), //方块颜色
new Color( 0xEE0000 ),
new Color( 0x00EE00 ),
new Color( 0x0000EE ),
new Color( 0xEE00EE ),
new Color( 0xEEEE00 ),
new Color( 0x00EEEE )
};
private static final short box_sum[][] = new short[][] //所有方块图形
{
{ 0x0660, 0x0660, 0x0660, 0x0660 },
{ 0x2222, 0x00F0, 0x2222, 0x00F0 },
{ 0x0264, 0x0630, 0x0264, 0x0630 },
{ 0x0462, 0x0360, 0x0462, 0x0360 },
{ 0x02E0, 0x4460, 0x0740, 0x0622 },
{ 0x0E20, 0x2260, 0x0470, 0x0644 },
{ 0x0464, 0x00E4, 0x04C4, 0x04E0 }
};
private static short next_box[] = new short[]{ 0x0660, 0x0660, 0x0660, 0x0660 };
private static short box[] = new short[]{ 0x0660, 0x0660, 0x0660, 0x0660 };
private static short map[][]; //地图
private static short box_state = 0;//当前BOX的状态//旋转方向
private static short matrix[][] = //定义矩阵用来计算出box_sum的方块
{
{ 0x1000, 0x0100, 0x0010, 0x0001 },
{ 0x2000, 0x0200, 0x0020, 0x0002 },
{ 0x4000, 0x0400, 0x0040, 0x0004 },
{ (short)0x8000, 0x0800, 0x0080, 0x0008 }
};
public Tetris()
{
rand = new Random( System.currentTimeMillis() );
try
{
gameOverImg = Toolkit.getDefaultToolkit().getImage("src/pics/laser.png");
}catch(Exception e){}
setSize( s_width, s_height ); //设置画布
initGame(); //游戏初始化
thread = new Thread(this);
thread.start();
}
private void initGame()
{
level = 1; //等级
success = 0; //得分
map = new short[s_box_h_sum][s_box_w_sum];
setNextBox(); //设置下一个BOX
setBox(); //将下一个BOX设置成当前BOX
setGameOver( false ); //恢复游戏
}
private void setBox() //将next_box设置成当前可控制box
{
box_state = 0; //box 状态
s_box_x = init_x; //当前方块坐标X
s_box_y = init_y; //当前方块坐标Y
boxColor = s_next_box; //设置当前BOX颜色
System.arraycopy( next_box, 0, box, 0, next_box.length ); //box = next_box
goDownPreTime = System.currentTimeMillis(); //设置好当前BOX后 计时
setNextBox(); //设置下一个BOX
if( !isCanMove() )
{
setGameOver( true );
}
}
public static boolean isGameOver = false;
public static long updatas = 0;
public static long fps = 0;
private long startTime, beginTime, endTime;
private long delay = 25;
private long upTime = 25;
public void run()
{
while ( true )
{
try
{
beginTime = System.currentTimeMillis();
updatas++;
updata( updatas );
repaint();
endTime = System.currentTimeMillis();
upTime = endTime-beginTime;
if( upTime<delay )
{
fps = 1000/delay;
thread.sleep(delay-upTime);
}
else
fps = 1000/upTime;
}catch(Exception e){ }
}
}
void setGameOver( boolean _isGameOver )
{
isGameOver = _isGameOver;
}
public void updata( long updatas )
{
}
public void update(Graphics g)
{
paint(g);
}
public static int offx = 2;
public static int offy = 2;
public void paint(Graphics g)
{
try
{
if( buffer == null )
{
buffer = createImage( s_width, s_height ); //设置画布缓冲区
gb = buffer.getGraphics(); //得到绘图设备
}
// gb.translate( offx, offy );
gb.setColor( new Color( 0x0 ) ); //初始化 画布颜色
gb.setClip ( 0, 0, s_width, s_height); //初始化 画布区域
gb.fillRect( 0, 0, s_width, s_height); //初始化 画布填充
paintReseau( gb ); //绘制网格
paintNextBox( gb ); //绘制下一BOX
paintMap( gb ); //绘制地图上不可以动BOX
paintBox( gb, s_box_x, s_box_y ); //绘制当前可控制BOX
gb.setColor( new Color( 0xFF3333 ) ); //分割线颜色
gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height ); //分割线
gb.drawString( "FPS:"+fps, s_line_between_x+10,10 ); //祯数
gb.drawString( "等级:"+level, s_line_between_x+10,30 ); //等级
gb.drawString( "得分:"+success, s_line_between_x+10,50 ); //分数
if( isGameOver )
{
gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );
}
// gb.translate( -offx, -offy );
}
catch(Exception e)
{
System.out.println("err at paint.e====="+e);
}
g.drawImage( buffer, offx, offy, null); //将画布缓冲区绘制到屏幕//偏移 (2,2)
}
private void paintReseau( Graphics g ) //绘制网格
{
g.setColor( gameBG );
g.fillRect( 0, 0, s_line_between_x, s_height );
if( isShowReseau )
{
g.setColor( gameColor[0] );
for( int i=0; i<s_line_between_x/s_box_w; i++ ) // |
{
g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );
}
for( int j=0; j<s_height/s_box_h; j++ ) // -
{
g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );
}
}
}
private void paintBox( Graphics g, int off_x, int off_y )
{
for( int i=0; i<4; i++ ) //行
{
for( int j=0; j<4; j++ ) //列
{
if( (box[box_state] & matrix[i][j]) == matrix[i][j] )
{
g.setColor( gameColor[ boxColor ] );
g.fillRect( (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );
g.setColor( gameBG );
g.drawRect( (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2 );
}
}
}
goDown(); //BOX是否下降
}
private void paintNextBox( Graphics g )
{
int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;
int off_y = s_height/2;
g.translate( off_x, off_y );
g.setColor( gameBG );
g.fillRect( 0, 0, 4*s_box_w, 4*s_box_h );
if( isShowReseau ) //显示格式
{
g.setColor( gameColor[0] );
for( int i=0; i<5; i++ ) // |
{
g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );
}
for( int j=0; j<5; j++ ) // -
{
g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );
}
}
for( int i=0; i<4; i++ ) //行
{
for( int j=0; j<4; j++ ) //列
{
if( (next_box[0]