import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class RussiaTetris extends Applet implements Runnable{
Thread thread;
private Image offImg;//缓冲图象
private Graphics offG;//缓冲
final int BaseX=20;
final int BaseY=20;
final int BlockSize =20;//每个块的大小
//定义游戏中出现的信息
final String INFO_READY = "S键 开始游戏";
final String INFO_PAUSE = "P键 继续游戏";
final String INFO_GAMEOVER = "游戏结束 任意键继续";
byte SHAPE[][][][] = //[造型索引][旋转索引][4][坐标]
{
{//造型一
{{ 0, 0},{ 1, 0},{ 0, 1},{ 1, 1}}, //旋转一[][]....
{{ 0, 0},{ 1, 0},{ 0, 1},{ 1, 1}}, //旋转二[][]....
{{ 0, 0},{ 1, 0},{ 0, 1},{ 1, 1}}, //旋转三........
{{ 0, 0},{ 1, 0},{ 0, 1},{ 1, 1}} //旋转四........
},
{//造型二
{{-1, 0},{ 0, 0},{ 0, 1},{ 1, 1}}, //旋转一[]
{{ 0,-1},{ 0, 0},{-1, 0},{-1, 1}}, //旋转二[]() []()
{{-1, 0},{ 0, 0},{ 0, 1},{ 1, 1}}, //旋转三[][] []
{{ 0,-1},{ 0, 0},{-1, 0},{-1, 1}} //旋转四
},
{//造型三
{{ 1, 0},{ 0, 0},{ 0, 1},{-1, 1}}, // 旋转一 []
{{ 0,-1},{ 0, 0},{ 1, 0},{ 1, 1}}, // 旋转二 ()[] ()[]
{{ 1, 0},{ 0, 0},{ 0, 1},{-1, 1}}, // 旋转三 [][] []
{{ 0,-1},{ 0, 0},{ 1, 0},{ 1, 1}} // 旋转四
},
{//造型四
{{ 0, 0},{ 1, 0},{ 2, 0},{ 0, 1}}, // 旋转一 [] []
{{ 0,-2},{ 0,-1},{ 0, 0},{ 1, 0}}, // 旋转二 ()[][] []() [][]() []
{{-2, 0},{-1, 0},{ 0, 0},{ 0,-1}}, // 旋转三 [] [] ()[]
{{-1, 0},{ 0, 0},{ 0, 1},{ 0, 2}} // 旋转四 []
},
{//造型五
{{-2, 0},{-1, 0},{ 0, 0},{ 0, 1}}, // 旋转一 []
{{ 0, 0},{ 1, 0},{ 0, 1},{ 0, 2}}, // 旋转二 [][]() [] [] ()[]
{{ 0,-1},{ 0, 0},{ 1, 0},{ 2, 0}}, // 旋转三 [] []() ()[][] []
{{ 0,-2},{ 0,-1},{ 0, 0},{-1, 0}} // 旋转四 []
},
{//造型六
{{-1, 0},{ 0, 0},{ 1, 0},{ 0, 1}}, // 旋转一
{{ 0,-1},{ 0, 0},{ 0, 1},{ 1, 0}}, // 旋转二 [] [] []
{{-1, 0},{ 0, 0},{ 1, 0},{ 0,-1}}, // 旋转三 []()[] ()[] []()[] []()
{{-1, 0},{ 0, 0},{ 0,-1},{ 0, 1}} // 旋转四 [] [] []
},
{//造型六
{{ 0,-1},{ 0, 0},{ 0, 1},{ 0, 2}}, // 旋转一 []
{{-1, 0},{ 0, 0},{ 1, 0},{ 2, 0}}, // 旋转二 () []()[][]
{{ 0,-1},{ 0, 0},{ 0, 1},{ 0, 2}}, // 旋转三 []
{{-1, 0},{ 0, 0},{ 1, 0},{ 2, 0}} // 旋转四 []
}
};
//定义游戏中使用的变量
final int[] Speeds = {60,50,40,30,20,15,10,5,3,1};//速度值定义
byte[][] Ground = new byte[10][20];//在 10 X 20 的场地游戏,预留顶部放置方块的空间一格
byte[][] NextShape = new byte[4][2];//存放下块造型
int CurrentX; //当前X左边
int CurrentY; //当前Y坐标
int CurrentShapeIndex; //当前造型索引
int CurrentTurnIndex; //当前旋转索引
int CurrentColorIndex; //当前造型色彩索引
int NextShapeIndex; //下块出现的造型的索引
int GameSpeed = 0; //游戏速度
int SpeedVar = 0; //延时计数
int FlashSpeed = 60; //信息提示闪烁速度
int FlashVar = 0; //闪烁延时计数
int ClearTotalLine = 0; //消掉的总行数
Color[] Colors = {Color.black,Color.red,Color.green,Color.blue,Color.magenta,Color.yellow,Color.orange,Color.pink};
//定义游戏中出现的状态
final int READY = 0;
final int GAMING = 1;
final int PAUSE = 2;
final int GAMEOVER = 3;
private int CurrentMode = READY; //游戏状态变量
String InfoStr = new String(INFO_READY);
public void init(){
offImg = createImage(getSize().width, getSize().height);//创建缓冲图象大小
offG = offImg.getGraphics();
setBackground(Color.black);
}
public void MakeNextShape(){
NextShapeIndex = (int)(Math.random()*70) /10;
NextShape = SHAPE[NextShapeIndex][0];
}
public void ClearGround(){//清除场地
for(int i=0; i<10; i++)
for(int j=0; j<20; j++) Ground[i][j]=0;
CurrentMode = READY;
ClearTotalLine = 0;
}
public void StartGame(){//开始游戏
ClearGround();
CurrentShapeIndex = (int)(Math.random()*70) /10;
CurrentX = 4;
CurrentY = 0;
CurrentMode = GAMING;
CurrentColorIndex = (int)(Math.random()*70) /10 +1;
MakeNextShape();
}
public void drawABlock(Graphics g,int x,int y,int colorIndex){//用指定的颜色画一个方块
g.setColor(Colors[colorIndex]);
g.fill3DRect(BaseX + x * BlockSize, BaseY + y * BlockSize , BlockSize, BlockSize, true);
g.fill3DRect(BaseX + x * BlockSize + 1, BaseY + y * BlockSize +1, BlockSize -2, BlockSize-2, true);
}
public void drawShape(Graphics g,int x,int y, int shapeindex,int trunindex)//在指定位置画指定的造型
{
for(int i=0; i<4; i++){
if(y+SHAPE[shapeindex][trunindex][i][1]>=0)//不画最顶上不在区域的块
drawABlock(g,x+SHAPE[shapeindex][trunindex][i][0]
,y+SHAPE[shapeindex][trunindex][i][1],CurrentColorIndex);
}
}
public void drawGround(Graphics g){//画整个画面
//画提示信息及行数及其他
g.setColor(new Color(255,255,255));
if(CurrentMode == READY)
g.drawString(" + / - : 调整速度",BaseX,BaseY-3);
if(CurrentMode == GAMING) g.drawString("↑:翻转 →/←:移动 ↓:快落 R:重玩",BaseX,BaseY-3);
g.drawRect(BaseX-1,BaseY-1,BlockSize*10, BlockSize*20);
for(int i=0; i<10; i++)
for(int j=1; j<20; j++)
if(Ground[i][j]!=0) drawABlock(g,i,j,Ground[i][j]);
//显示相关信息
g.setColor(Color.lightGray);
g.drawRect(BaseX+BlockSize*10,BaseY-1,BlockSize*2+BlockSize/2+BlockSize/2,20); // 与下一块提示对齐
g.drawString("TETRIS",BaseX + BlockSize * 10+8,BaseY + 14);//画游戏相关信息
g.drawString("已消行数",BaseX + BlockSize * 10+5,BaseY * 3 );
g.drawString(String.valueOf(ClearTotalLine),BaseX + BlockSize * 10+5,BaseY * 4);
g.drawString("当前速度",BaseX + BlockSize * 10+5,BaseY * 6 );
g.drawString(String.valueOf(GameSpeed),BaseX + BlockSize * 10+5,BaseY * 7);
//g.drawString("http://www.delfan.com" ,BaseX,BaseY + BlockSize * 21-10 );
}
public void drawNextBlock(Graphics g){//画下一块
g.setColor(Color.lightGray);
g.drawString("下一块",BaseX+11*BlockSize - BlockSize / 2,BaseY+17*BlockSize);
g.drawRect(BaseX + BlockSize * 10, BaseY + BlockSize *18 - BlockSize / 2
,BlockSize * 2 + BlockSize / 2,BlockSize * 2);
g.setColor(Color.blue);
for(int i=0; i<4; i++)
g.fill3DRect(BaseX + 11 * BlockSize + NextShape[i][0]*BlockSize / 2
, BaseY + 18 * BlockSize + NextShape[i][1]*BlockSize / 2 , BlockSize / 2 , BlockSize /2, true);
}
public void drawInfo(Graphics g){//绘制提示的信息
g.setColor(Color.white);
Font old = g.getFont();
g.setFont(new Font("宋体",0,24));
g.drawString(InfoStr,BaseX+5*BlockSize - InfoStr.length()* 7 ,BaseY+10*BlockSize);
g.setFont(old);
}
public void paint(Graphics g){
offG.clearRect(0,0,getSize().width,getSize().height);
drawGround(offG);
switch(CurrentMode){
case READY :
case PAUSE :
case GAMEOVER :
drawInfo(offG);
break;
case GAMING :
drawShape(offG,CurrentX,CurrentY,CurrentShapeIndex,CurrentTurnIndex);
drawNextBlock(offG);
break;
}
if(offG!=null) g.drawImage(offImg,0,0,this);
}
public void update(Graphics g){
paint(g);
}
public void start(){
thread = new Thread(this);
thread.start();
}
public void stop(){
thread = null;
}
public void run(){
Thread current= Thread.currentThread();
while(thread ==current){
try{
Thread.currentThread().sleep(10);
}catc