📄 singletetirs.java
字号:
/*程序:SingleTetirs.java
*说明:单一俄罗斯方块游戏类
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
//单一砖块组游戏类
public class SingleTetirs implements Runnable{
Graphics g;//绘图区
Component c;
Thread DownThread;
long GAME_SPEED;//纪录游戏速度
long GAME_SCORE;//纪录游戏分数
long GAME_LEVEL;//纪录游戏等级
long GAME_LINE;//纪录游戏消除行数
boolean GAME_RUNNING;//纪录游戏是否进行中
Draw d;//画出砖块方式
int MAPX;//地图X坐标
int MAPY;//地图Y坐标
int MAP_ARRAY[][];//地图数组
int MAP_SHOW_ARRAY[][];//地图显示数组(与移动砖块组结合之数组)
Color MAP_COLOR_ARRAY[][];//地图颜色数组
int GRIDX;//x轴格数
int GRIDY;//y轴格数
int BRICK_WIDTH;//单一砖块_宽
int BRICK_SIDE;//单一砖块_边
int NEXT_BRICK_NUMBER;//下一个砖块组显示数量
boolean IS_SHOW_NEXT;//是否显示下一个砖块组
int NOW_BRICK;//现在动作砖块组编号
int NOW_BRICK_DIRECT;//现在动作砖块组的方向
int NOW_BRICK_X;//现在动作砖块组的x坐标
int NOW_BRICK_Y;//现在动作砖块组的y坐标
SuperBrick NowBrick;//现在动作的砖块组
Color NOW_BRICK_COLOR;//现在动作砖块组的颜色
ArrayList BrickArray;//所有砖块组类数组
ArrayList NextBrickArray;//下一个砖块组储存数组
ArrayList NextBrickColorArray;//下一个砖块组储存数组
public SingleTetirs(Graphics g,//绘图区
int mapx,int mapy,//地图坐标
int gridx,int gridy,//地图方格数
int brick_width,//砖块组宽
int brick_side,//砖块组边
int next_brick_number,//显示下一个砖块组数量
boolean is_show_next,//是否显示下一个砖块组
Component c){//组件
//初始各参数
this.c=c;
this.g=g;
this.MAPX=mapx;
this.MAPY=mapy;
this.GRIDX=gridx;
this.GRIDY=gridy;
this.BRICK_WIDTH=brick_width;
this.BRICK_SIDE=brick_side;
this.NEXT_BRICK_NUMBER=next_brick_number;
this.IS_SHOW_NEXT=is_show_next;
this.MAP_ARRAY=new int[GRIDX][GRIDY];
this.MAP_SHOW_ARRAY=new int[GRIDX][GRIDY];
this.MAP_COLOR_ARRAY=new Color[GRIDX][GRIDY];
this.NOW_BRICK_X=0;
this.NOW_BRICK_Y=0;
this.GAME_SPEED=1000;
this.GAME_SCORE=0;
this.GAME_LEVEL=1;
this.GAME_LINE=0;
//将地图数组归零
for(int i=0;i<GRIDX;i++){
for(int j=0;j<GRIDY;j++){
this.MAP_ARRAY[i][j]=0;
this.MAP_SHOW_ARRAY[i][j]=0;
}
}
//加入所有砖块组类型
BrickArray=new ArrayList();//建立储存砖块组型态的数组
BrickArray.add(new Brick_BB());
BrickArray.add(new Brick_I());
BrickArray.add(new Brick_L());
BrickArray.add(new Brick_UL());
BrickArray.add(new Brick_UT());
BrickArray.add(new Brick_UZ());
BrickArray.add(new Brick_Z());
//产生下一砖块组数据
NextBrickArray=new ArrayList();//建立储存预备砖块组编号的数组
NextBrickColorArray=new ArrayList();//建立储存预备砖块组编号的数组
for(int i=0;i<(NEXT_BRICK_NUMBER+1);i++){
createNextBrick();
}
//建立绘出砖块组对象
d=new Draw(this);
//画出外框
d.DrawMapFrame(0,0,GRIDX*BRICK_WIDTH+2*5,GRIDY*BRICK_WIDTH+2*5,5);
d.DrawMapFrame(290,0,200,350,5);//预备方块外框
d.DrawMapFrame(290,350,200,140,5);//游戏数据外框
showNextBrickGroup();//显示提示方块组
addNextBrick();//新增一个提示方块
showNextBrick();//显示现在动作方块
updateGame(0);//更新游戏数据
//产生控制下降的线程
DownThread=new Thread(this);
DownThread.start();
}
//重绘窗口
public void paint(){
//画出外框
d.DrawMapFrame(0,0,GRIDX*BRICK_WIDTH+2*5,GRIDY*BRICK_WIDTH+2*5,5);
d.DrawMapFrame(290,0,200,350,5);//预备方块
d.DrawMapFrame(290,350,200,140,5);//游戏数据
showNextBrickGroup();
updateGame(0);
reLoadMap();
showNextBrick();
}
//覆盖run()方法
public void run(){
try{
Thread.sleep(GAME_SPEED);
keyPress(KeyEvent.VK_DOWN);
DownThread=new Thread(this);
DownThread.start();
}catch(Exception e){
e.printStackTrace();
}
}
//更新游戏数据
public void updateGame(int line){
d.DrawMapFrame(290,350,200,140,5);
GAME_SCORE+=50*line*line*line*(0.5)*GAME_LEVEL;
GAME_LEVEL=GAME_SCORE/5000+1;
GAME_SPEED=800/GAME_LEVEL+200;
GAME_LINE+=line;
d.DrawFont("级数:"+GAME_LEVEL,300,400,16,Color.cyan,"标楷体");
d.DrawFont("分数:"+GAME_SCORE,300,430,16,Color.red,"标楷体");
d.DrawFont("行数:"+GAME_LINE,300,460,16,Color.green,"标楷体");
}
//产生下一组砖块
public void createNextBrick(){
//产生预备砖块组编号
NextBrickArray.add(new Integer((int)(Math.random()*BrickArray.size())));
//产生预备砖块组颜色
NextBrickColorArray.add(new Color((int)(Math.random()*128+127),
(int)(Math.random()*128+127),
(int)(Math.random()*128+127)));
}
//检查砖块组是否可以放置
public boolean isPut(int x,int y,int type,int mode){
SuperBrick sb=(SuperBrick)BrickArray.get(type);
for(int i=0;i<=4;i++){
for(int j=0;j<=4;j++){
if(sb.BRICK_ARRAY[mode][i][j]==1){
if((i+x)<0 || (i+x)>(GRIDX-1) ||
(j+y)<0 || (j+y)>(GRIDY-1) ||
MAP_ARRAY[i+x][j+y]==1){
return false;
}
}
}
}
return true;
}
//砖块组数组写入地图数组
public void addBrickToMap(){
for(int i=0;i<=4;i++){
for(int j=0;j<=4;j++){
if((NOW_BRICK_X+i)>=0 && (NOW_BRICK_X+i)<GRIDX &&
(NOW_BRICK_Y+j)>=0 && (NOW_BRICK_Y+j)<GRIDY &&
NowBrick.BRICK_ARRAY[NOW_BRICK_DIRECT][i][j]==1){
MAP_ARRAY[NOW_BRICK_X+i][NOW_BRICK_Y+j]=1;
MAP_COLOR_ARRAY[NOW_BRICK_X+i][NOW_BRICK_Y+j]=
NOW_BRICK_COLOR;
}
}
}
}
//产生下一个砖块组
public void addNextBrick(){
NextBrickArray.remove(0);
NextBrickColorArray.remove(0);
NOW_BRICK=((Integer)NextBrickArray.get(0)).intValue();
NOW_BRICK_COLOR=(Color)NextBrickColorArray.get(0);
NOW_BRICK_DIRECT=0;
NOW_BRICK_X=(GRIDX-5)/2;
NOW_BRICK_Y=0;
NowBrick=(SuperBrick)BrickArray.get(NOW_BRICK);
createNextBrick();
}
//显示下一个砖块组
public void showNextBrick(){
if(this.isPut(NOW_BRICK_X,
NOW_BRICK_Y,
NOW_BRICK,
NOW_BRICK_DIRECT)){
d.DrawBrickGroup(NOW_BRICK_X,
NOW_BRICK_Y,
NOW_BRICK,
NOW_BRICK_DIRECT,
NOW_BRICK_COLOR);
}else{
DownThread.stop();
}
}
//检查满行
public void checkFull(){
boolean blFull=true;//满行旗标
int delLine=0;//删除行数计数
for(int j=NOW_BRICK_Y;j<(NOW_BRICK_Y+5);j++){
blFull=true;
for(int i=0;i<GRIDX;i++){
if(j>=0 && j<GRIDY){
if(MAP_ARRAY[i][j]!=1)
blFull=false;
}else{
blFull=false;
}
}
if(blFull){
removeFull(j);//移除满行
delLine++;
}
}
if(delLine>0)
reLoadMap();
updateGame(delLine);
}
//移除满行
public void removeFull(int line){
for(int j=line;j>0;j--){
for(int i=0;i<GRIDX;i++){
MAP_ARRAY[i][j]=MAP_ARRAY[i][j-1];
MAP_COLOR_ARRAY[i][j]=MAP_COLOR_ARRAY[i][j-1];
}
}
for(int i=0;i<GRIDX;i++){
MAP_ARRAY[i][0]=0;
MAP_COLOR_ARRAY[i][0]=Color.black;
}
}
//重新加载地图砖块
public void reLoadMap(){
for(int i=0;i<GRIDX;i++){
for(int j=0;j<GRIDY;j++){
if(MAP_ARRAY[i][j]==1)
d.DrawBrick(i,j,MAP_COLOR_ARRAY[i][j]);
else
d.DrawBrick(i,j,Color.black);
}
}
}
//显示下一组砖块
public void showNextBrickGroup(){
new MoveThread(this).start();
}
//按键事件
public synchronized void keyPress(int KEYCODE){
int x=NOW_BRICK_X;
int y=NOW_BRICK_Y;
int direct=NOW_BRICK_DIRECT;
switch(KEYCODE){
case KeyEvent.VK_UP://上
NOW_BRICK_DIRECT++;
if(NOW_BRICK_DIRECT>=4)
NOW_BRICK_DIRECT=0;
if(isPut(NOW_BRICK_X,
NOW_BRICK_Y,
NOW_BRICK,
NOW_BRICK_DIRECT)){
d.DrawBrickGroup(x,y,direct);
}else{
NOW_BRICK_DIRECT--;
if(NOW_BRICK_DIRECT<0)
NOW_BRICK_DIRECT=3;
}
break;
case KeyEvent.VK_DOWN://下
if(isPut(NOW_BRICK_X,
NOW_BRICK_Y+1,
NOW_BRICK,
NOW_BRICK_DIRECT)){
NOW_BRICK_Y++;
d.DrawBrickGroup(x,y,direct);
}else{//到底
showNextBrickGroup();
addBrickToMap();
checkFull();
addNextBrick();
showNextBrick();
}
break;
case KeyEvent.VK_LEFT://左
if(isPut(NOW_BRICK_X-1,
NOW_BRICK_Y,
NOW_BRICK,
NOW_BRICK_DIRECT)){
NOW_BRICK_X--;
d.DrawBrickGroup(x,y,direct);
}
break;
case KeyEvent.VK_RIGHT://右
if(isPut(NOW_BRICK_X+1,
NOW_BRICK_Y,
NOW_BRICK,
NOW_BRICK_DIRECT)){
NOW_BRICK_X++;
d.DrawBrickGroup(x,y,direct);
}
break;
case KeyEvent.VK_SPACE://直落
while(isPut(NOW_BRICK_X,
NOW_BRICK_Y+1,
NOW_BRICK,
NOW_BRICK_DIRECT)){
NOW_BRICK_Y++;
d.DrawBrickGroup(x,y,direct);
x=NOW_BRICK_X;
y=NOW_BRICK_Y;
}
addBrickToMap();
checkFull();
addNextBrick();
showNextBrickGroup();
showNextBrick();
break;
case KeyEvent.VK_ESCAPE://跳离
System.exit(0);
break;
case KeyEvent.VK_PAUSE://暂停
if(DownThread.isAlive())
DownThread.stop();
else{
DownThread=new Thread(this);//产生控制下降的线程
DownThread.start();
}
break;
}
}
}
/*程序:SingleTetirs.java
*说明:相关绘图方法。
* 建立时需以SingleTetirs对象为创建子参数,
* 负责方块绘制,方块区外框绘制,字型绘制等
*/
class Draw{
SingleTetirs st;//俄罗斯砖块组单一类
//创建子
public Draw(SingleTetirs st){
this.st=st;//指定绘图区
}
//画出砖块组动作区地图外框
public void DrawMapFrame(int x,int y,int wid,int hig,int side){
//定义多边形坐标
int xx[][]={{x,x+wid,x+wid-side,x+side},//上
{x+wid-side,x+wid,x+wid,x+wid-side},//右
{x+side,x+wid-side,x+wid,x},//下
{x,x+side,x+side,x}};//左
int yy[][]={{y,y,y+side,y+side},//上
{y+side,y,y+hig,y+hig-side},//右
{y+hig-side,y+hig-side,y+hig,y+hig},//下
{y,y+side,y+hig-side,y+hig}};//左
//画出多边形
for(int i=0;i<=3;i++){
//不同边设定不同颜色
switch(i){
case 0:
st.g.setColor(new Color(150,150,150));
break;
case 1:
st.g.setColor(new Color(150,150,150));
break;
case 2:
st.g.setColor(new Color(180,180,180));
break;
case 3:
st.g.setColor(new Color(180,180,180));
break;
}
st.g.fillPolygon(xx[i],yy[i],4);
st.g.setColor(Color.black);
st.g.fillRect(x+side-1,y+side-1,wid-side*2+2,hig-side*2+2);
}
}
//画出砖块组
public void DrawBrickGroup(int x,int y,int type,int direct,Color c){
SuperBrick sb=(SuperBrick)st.BrickArray.get(type);
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if(sb.BRICK_ARRAY[direct][i][j]==1){
DrawBrick((i+x),(j+y),c);
}
}
}
}
//画出砖块组(清除前一个砖块组)
public void DrawBrickGroup(int fx,int fy,int fdirect){
//清除前一个砖块组
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if((i+st.NOW_BRICK_X)>=0 && (i+st.NOW_BRICK_X)<st.GRIDX &&
(j+st.NOW_BRICK_Y)>=0 && (j+st.NOW_BRICK_Y)<st.GRIDY){
if(st.NowBrick.BRICK_ARRAY[fdirect][i][j]==1){
DrawBrick(i+fx,j+fy,Color.black);
}
}
}
}
//画出现在砖块组
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if((i+st.NOW_BRICK_X)>=0 && (i+st.NOW_BRICK_X)<st.GRIDX &&
(j+st.NOW_BRICK_Y)>=0 && (j+st.NOW_BRICK_Y)<st.GRIDY){
if(st.NowBrick.BRICK_ARRAY[st.NOW_BRICK_DIRECT][i][j]==1){
DrawBrick(i+st.NOW_BRICK_X,
j+st.NOW_BRICK_Y,
st.NOW_BRICK_COLOR);
}
}
}
}
}
//画出单一砖块
public void DrawBrick(int x,int y,Color c){
st.g.setColor(Color.black);
st.g.drawRect(x*st.BRICK_WIDTH+st.MAPX,y*st.BRICK_WIDTH+st.MAPY,
st.BRICK_WIDTH-1,st.BRICK_WIDTH-1);
st.g.setColor(c);
st.g.fill3DRect(x*st.BRICK_WIDTH+st.MAPX+st.BRICK_SIDE,
y*st.BRICK_WIDTH+st.MAPY+st.BRICK_SIDE,
st.BRICK_WIDTH-st.BRICK_SIDE*2,
st.BRICK_WIDTH-st.BRICK_SIDE*2,true);
}
//画出字型
public void DrawFont(String str,int x,int y,int size,Color c,String fs){
Font f=new Font(fs,Font.BOLD,size);
st.g.setColor(c);
st.g.setFont(f);
st.g.drawString(str,x,y);
}
}
//====================================
class MoveThread extends Thread{
SingleTetirs s;
Graphics g;
Draw d;
Component c;
Image img;
Graphics sg;
public MoveThread(SingleTetirs s){
this.s=s;
this.g=s.g;
this.d=s.d;
this.c=s.c;
img=c.createImage(190,340);
sg=img.getGraphics();
}
public void run(){
for(int i=0;i<4;i++){
try{
sleep(50);
showNextBrickGroup(i);
g.drawImage(img,295,5,c);
}catch(Exception e){
e.printStackTrace();
}
}
}
//显示下一组砖块
public void showNextBrickGroup(int index){
sg.setColor(Color.black);
sg.fillRect(0,0,190,340);
for(int j=0;j<s.NextBrickArray.size();j++){
int m=((Integer)s.NextBrickArray.get(j)).intValue();
Color c=((Color)s.NextBrickColorArray.get(j));
DrawBrickGroup((2),((j)*4)-index,m,0,c);
}
}
//画出砖块组
public void DrawBrickGroup(int x,int y,int type,int direct,Color c){
SuperBrick sb=(SuperBrick)s.BrickArray.get(type);
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if(sb.BRICK_ARRAY[direct][i][j]==1){
DrawBrick((i+x),(j+y),c);
}
}
}
}
//画出单一砖块
public void DrawBrick(int x,int y,Color c){
sg.setColor(Color.black);
sg.drawRect(x*s.BRICK_WIDTH-9,y*s.BRICK_WIDTH,
s.BRICK_WIDTH-1,s.BRICK_WIDTH-1);
sg.setColor(c);
sg.fill3DRect(x*s.BRICK_WIDTH-9,
y*s.BRICK_WIDTH,
s.BRICK_WIDTH-s.BRICK_SIDE*2,
s.BRICK_WIDTH-s.BRICK_SIDE*2,true);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -