package realgame;
import javax.swing.UIManager;
import java.awt.*;
public class Game {
boolean packFrame = false;
//Construct the application
public Game() {
GameFrame frame = new GameFrame();
//Validate frames that have preset sizes
//Pack frames that have useful preferred size info, e.g. from their layout
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
//Center the window
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
}
//Main method
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
}
catch(Exception e) {
e.printStackTrace();
}
new Game();
}
}
//====================================第二个文件GameFrame.java编程时请另建一文件,将下面的内容放入.
package realgame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.Timer;
import java.awt.geom.*;
class GameFrame extends JFrame{
private static final int WIDTH=225;
private static final int HEIGHT=295;
GamePanel gamePanel;
public GameFrame(){
setTitle("查色盲!俄罗斯方块");
setSize(WIDTH,HEIGHT);
this.setResizable(false);
GamePanel gamePanel=new GamePanel();
Container contentPane=getContentPane();
contentPane.add(gamePanel);
// gamePanel.start();
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
this.setResizable(false);
}
}
class GamePanel extends JPanel{
private static int clockInterval=500;
private static final int ROWS=20;
private static final int COLS=10;
private static int keyEventValid=1;
Timer t;
private static int top=ROWS-1;
private static int score;
private int[][] screen=new int[ROWS][COLS];//原有屏幕上的信息,得分情况来自于此
private int[][] view=new int[ROWS][COLS];//块在screen显示所看到的视图
private Block presentBlock;//当前活动块
private Block nextBlock;//下一个块,以作预览
private String stop="";
//块在屏幕上的位置
private int row;
private int col;
private int preCol;
public GamePanel(){
KeyHandler listener =new KeyHandler();
addKeyListener(listener);
nextBlock=new Block(0);
col=(int)(Math.random()*(COLS-nextBlock.maxCol));
preCol=col;
this.setBackground(Color.BLACK);
this.setLayout(new BorderLayout());
ControlPanel cp=new ControlPanel();
cp.addKeyListener(listener);
cp.jl.addKeyListener(listener);
cp.js.addKeyListener(listener);
cp.startJB.addKeyListener(listener);
cp.endGame.addKeyListener(listener);
this.add(BorderLayout.SOUTH,cp);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
//首先画出显示区的大框
drawBigRec(g2);
//依view的内容画出相应的格子
for(int i=0;i<view.length;i++)
for(int j=0;j<view[i].length;j++)
if (view[i][j]==1) drawAnElem(i,j,g2,0,0);
//画出预览区
final float xPos=140.0F;
final float yPos=60.0F;
Font f=new Font("Serif",Font.BOLD,18);
g2.setFont(f);
g2.setPaint(Color.red);
g2.drawString("SCORE",xPos,yPos);
g2.setPaint(Color.green);
g2.drawString(""+score,xPos,yPos+20);
g2.setPaint(Color.green);
g2.drawString(stop,xPos,yPos-30);
final double preXPos=140.0F;
final double preYPos=140.0F;
double preEdge=60.0;
Rectangle2D rect=new Rectangle2D.Double(preXPos,preYPos,preEdge,preEdge);
g2.setColor(Color.orange);
g2.fill(rect);
Rectangle2D innerRect=new Rectangle2D.Double(preXPos+10,preYPos+10,preEdge-20,preEdge-20);
g2.setColor(Color.white);
g2.fill(innerRect);
for(int i=0;i<nextBlock.maxRow;i++)
for(int j=0;j<nextBlock.maxCol;j++)
if(nextBlock.bodyInfo[i][j]==1)
drawAnElem(i,j,g2,preXPos,preYPos);
}//~panel的绘制结束
public boolean moveLeft(){
return(go(row,col-1));
}
public boolean moveRight(){
return(go(row,col+1));
}
public boolean moveDown(){
return(go(row+1,col));
}
//如果发生碰撞则返回true;
private boolean crash(int r,int c,Block temp){
boolean flag=false;
if((r+temp.maxRow>ROWS)||(c+temp.maxCol>COLS)) return true;
for(int i=0;i<temp.maxRow;i++)
for(int j=0;j<temp.maxCol;j++)
if((temp.bodyInfo[i][j]==1)&&(screen[r+i][c+j]==1))
flag=true;
return flag;
}
private boolean go(int r,int c){
boolean flag=true;
if(((r+presentBlock.maxRow)>ROWS)||((c+presentBlock.maxCol)>COLS)||(c<0))
return false;
for(int i=0;i<presentBlock.maxRow;i++)
for(int j=0;j<presentBlock.maxCol;j++)
if((presentBlock.bodyInfo[i][j]==1)&&(screen[r+i][c+j]==1))
flag=false;
if(flag){
row=r;col=c;
setView();
}
return flag;
}
//画出一个单元格;
private void drawAnElem(int i,int j,Graphics2D g2,double xPos,double yPos){
final int edge=10;
final int margin=10;
final int innerMargin=1;
Rectangle2D rect=new Rectangle2D.Double(xPos+margin+j*10,yPos+margin+i*10,edge,edge);
g2.setPaint(Color.red);
g2.draw(rect);
rect=new Rectangle2D.Double(xPos+margin+j*10+innerMargin,yPos+margin+i*10+innerMargin,
edge-innerMargin,edge-innerMargin
);
int colorChoser=0;
colorChoser=(int)(Math.random()*11);
if (colorChoser==0)g2.setPaint(Color.blue);
else if(colorChoser==1) g2.setPaint(Color.green);
else if(colorChoser==2) g2.setPaint(Color.orange);
else if(colorChoser==3) g2.setPaint(Color.yellow);
else if(colorChoser==4) g2.setPaint(Color.magenta);
else if(colorChoser==5) g2.setPaint(Color.red);
else if(colorChoser==6) g2.setPaint(Color.yellow);
else if(colorChoser==7) g2.setPaint(Color.CYAN);
else if(colorChoser==8) g2.setPaint(new Color(200,100,150));
else if(colorChoser==9) g2.setPaint(Color.GREEN);
else if(colorChoser==10) g2.setPaint(Color.PINK);
g2.fill(rect);
}
//画出显示区的外框
private void drawBigRec(Graphics2D g2){
final double REC_WIDTH=120;
final double REC_HEIGHT=220;
Rectangle2D rect=new Rectangle2D.Double(0,0,REC_WIDTH,REC_HEIGHT);
Rectangle2D innerRect=new Rectangle2D.Double(10,10,REC_WIDTH-20,REC_HEIGHT-20);
g2.setPaint(Color.orange);
g2.fill(rect);
g2.setPaint(Color.white);
g2.fill(innerRect);
}
//设置视图
private void setView(){
//将screen中的内容复制到view中
for(int i=0;i<screen.length;i++)
for(int j=0;j<screen[i].length;j++)
view[i][j]=screen[i][j];
//将block投影到view中;
for(int i=0;i<presentBlock.maxRow;i++)
for(int j=0;j<presentBlock.maxCol;j++)
if(presentBlock.bodyInfo[i][j]==1)
view[i+row][j+col]=presentBlock.bodyInfo[i][j];
//每次设置视图后要求画面重绘
repaint();
}
//事件处理
private class KeyHandler implements KeyListener{
Block temp=null;
public void keyPressed(KeyEvent event){
int keyCode =event.getKeyCode();
if(keyCode==KeyEvent.VK_LEFT) {
if(keyEventValid==1)
if(moveLeft()) setView();}
else if(keyCode==KeyEvent.VK_RIGHT) {
if(keyEventValid==1)
if(moveRight()) setView();}
else if(keyCode==KeyEvent.VK_DOWN) {
if(keyEventValid==1)
if(moveDown()) setView();}
else if(keyCode==KeyEvent.VK_UP){
if(keyEventValid==1){
temp=new Block(presentBlock.bodyType);
temp.rotate();
if (!crash(row,col,temp))
{
presentBlock.rotate();
setView();
}
temp=null;
} }//~UP
}
public void keyReleased(KeyEvent event){}
public void keyTyped(KeyEvent event){}
}
public boolean isFocusTraversable(){
return true;
}
private int winScore(){
int inc=0;
int cur=ROWS-1;
while(cur>=top){
if(allDone(cur)){
inc+=100;
score+=100;
removeMe(cur,top);
top++;
}else cur--;
}//~while
return inc;
}
private boolean allDone(int R){
boolean flag=true;
for(int c=0;c<COLS;c++)
if(screen[R][c]==0) flag=false;
return flag;
}
private void removeMe(int R,int T){
for(int r=R;r>T;r--){
for(int c=0;c<COLS;c++)
screen[r][c]=screen[r-1][c];//将上方的向下座
}
for(int c=0;c<COLS;c++)
screen[T][c]=0;//清除第T行;
}
private class RegularGo implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean flag=moveDown();
if(!flag){
keyEventValid=0;//先给键盘上锁
anchor();
setTop();
int tempScore=winScore();
if((tempScore>=100)&&(tempScore)<300)
stop="嗯加油";
else if (tempScore>=300)
stop="不错啊";
else
stop="";
setView();
presentBlock=nextBlock;
row=0;
//保证每次进入点不同
do{col=(int)(Math.random()*(COLS-presentBlock.maxCol));}
while(col==preCol);
preCol=col;
keyEventValid=1;
nextBlock=new Block(0);
setView();
System.gc();
}
if(top==0) {keyEventValid=0;stop="玩完了";setView();t.stop();}
}
}
public void start(){
keyEventValid=1;
for(int r=0;r<ROWS;r++)
for(int c=0;c<COLS;c++)
screen[r][c]=0;
top=ROWS-1;
score=0;
stop="开始了";
// nextBlock=new Block(0);
presentBlock=nextBlock;
nextBlock=new Block(0);
repaint();
RegularGo go=new RegularGo();
t=new Timer(clockInterval,go);
t.start();
}//~start
private void anchor(){
for(int r=0;r<presentBlock.maxRow;r++)
for(int c=0;c<presentBlock.maxCol;c++)
if(presentBlock.bodyInfo[r][c]==1)
screen[row+r][col+c]=1;
}
private void setTop(){
int myTop=0;
int c=0;
while(myTop<ROWS-1){
c=0;
while(c<COLS){
if (screen[myTop][c]==1) break;
else c++;
}
if (c<COLS) break;
else myTop++;
}
top=myTop;
}//setTop
private void setSpeed(int speed){
t.setDelay(clockInterval);
}
private class ControlPanel extends JPanel{
JLabel jl=new JLabel(" 调速");
JSlider js=new JSlider(1,5,1);
JButton startJB=new JButton("开始");
JButton endGame=new JButton("结束");
public ControlPanel(){
setBackground(Color.orange);
js.setBackground(Color.orange);
startJB.setBackground(Color.orange);
endGame.setBackground(Color.orange);
setLayout(new GridLayout(2,2));
add(jl);
add(js);
js.addChangeListener(new speedTune());
Font font=new Font("Serif",Font.PLAIN,12);
add(startJB);
jl.setFont(font);
startJB.setFont(font);
startJB.addActionListener(new startAction());
add(endGame);
endGame.setFont(font);
endGame.addActionListener(new endAction());
}
private class startAction implements ActionListener{
public void actionPerformed(ActionEvent event){
start();
}
}
private class endAction implements ActionListener{
public void actionPerformed(ActionEvent event){
System.exit(3);
}
}
private class speedTune implements ChangeListener{
public void stateChanged(ChangeEvent event){
JSlider slider =(JSlider)event.getSource();
clockInterval=1000/slider.getValue();
if(t!=null)
setSpeed(slider.getValue());
startJB.requestFocus();
}
}
}//~CP
}//~
class Block{
public int[][] bodyInfo= new int[4][4];
public int maxRow;
public int maxCol;
public int bodyType;
public Block(int shape){
final int TYPES=20;
int i;
if(shape==0)
i=(int)(Math.random()*TYPES)+1;
else
i=shape;
setBody(i);
bodyType=i;
}//~con
//setBody中应设定bodyType
private void setBody(int i){
switch(i){
case 1://(竖长条形)
for(int r=0;r<bodyInfo.length;r++)
bodyInfo[r][0]=1;
maxRow=4;
maxCol=1;
break;
case 2://(横长条形)
for(int c=0;c<bodyInfo[0].length;c++)
bodyInfo[0][c]=1;
maxRow=1;
maxCol=4;
break;
case 3://顺闪电形
bodyInfo[0][0]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[2][1]=1;
maxRow=3;
maxCol=2;
break;
case 4://顺闪平形
bodyInfo[0][1]=1;bodyInfo[0][2]=1;
bodyInfo[1][0]=1;bodyInfo[1][1]=1;
maxRow=2;
maxCol=3;
break;
case 5://反闪电形
bodyInfo[0][1]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[2][0]=1;
maxRow=3;
maxCol=2;
break;
case 6://反闪平形
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[1][1]=1;bodyInfo[1][2]=1;
maxRow=2;
maxCol=3;
break;
case 7://土形
bodyInfo[0][1]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[1][2]=1;
maxRow=2;
maxCol=3;
break;
case 8://土形(90)
bodyInfo[0][0]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[2][0]=1;
maxRow=3;
maxCol=2;
break;
case 9://土形(180)
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[0][2]=1;bodyInfo[1][1]=1;
maxRow=2;
maxCol=3;
break;
case 10://土形(270)
bodyInfo[0][1]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[2][1]=1;
maxRow=3;
maxCol=2;
break;
case 11://反7形
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[1][0]=1;bodyInfo[2][0]=1;
maxRow=3;
maxCol=2;
break;
case 12://反7形(90)
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[0][2]=1;bodyInfo[1][2]=1;
maxRow=2;
maxCol=3;
break;
case 13://反7形(180)
bodyInfo[0][1]=1;bodyInfo[1][1]=1;
bodyInfo[2][1]=1;bodyInfo[2][0]=1;
maxRow=3;
maxCol=2;
break;
case 14://反7形(270)
bodyInfo[0][0]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[1][2]=1;
maxRow=2;
maxCol=3;
break;
case 15://7字形
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[1][1]=1;bodyInfo[2][1]=1;
maxRow=3;
maxCol=2;
break;
case 16://7字型(90)
bodyInfo[0][2]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[1][2]=1;
maxRow=2;
maxCol=3;
break;
case 17://7字形(180)
bodyInfo[0][0]=1;bodyInfo[1][0]=1;
bodyInfo[2][0]=1;bodyInfo[2][1]=1;
maxRow=3;
maxCol=2;
break;
case 18://7字形(270)
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[0][2]=1;bodyInfo[1][0]=1;
maxRow=2;
maxCol=3;
break;
case 19://田字形
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[1][0]=1;bodyInfo[1][1]=1;
maxRow=2;
maxCol=2;
break;
case 20://田字型
bodyInfo[0][0]=1;bodyInfo[0][1]=1;
bodyInfo[1][0]=1;bodyInfo[1][1]=1;
maxRow=2;
maxCol=2;
break;
/* case 21:
for(int c=0;c<bodyInfo[0].length;c++)
bodyInfo[0][c]=1;
maxRow=1;
maxCol=4;
break;
case 22:
bodyInfo[0][0]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[2][1]=1;
maxRow=3;
maxCol=2;
break;
case 23:
bodyInfo[0][1]=1;bodyInfo[1][0]=1;
bodyInfo[1][1]=1;bodyInfo[2][0]=1;
maxRow=3;
maxCol=2;
break;
*/
//如果你想加入更多的块形状,只要在这里加就是了,注意把bodyType的变量的值调为你的块种类数啊。
}
}//~setBody
//根据bodyType作相应的变换
public void rotate(){
switch(bodyType){
case 1: clear();setBody(2); bodyType=2;break;
case 2: clear();setBody(1); bodyType=1;break;
case 3: clear();setBody(4); bodyType=4;break;
case 4: clear();setBody(3); bodyType=3;break;
case 5: clear();setBody(6); bodyType=6;break;
case 6: clear();setBody(5); bodyType=5;break;
case 7: clear();setBody(8); bodyType=8;break;
case 8: clear();setBody(9); bodyType=9;break;
case 9: clear();setBody(10); bodyType=10;break;
case 10:clear();setBody(7); bodyType=7;break;
case 11:clear();setBody(12); bodyType=12;break;
case 12:clear();setBody(13); bodyType=13;break;
case 13:clear();setBody(14); bodyType=14;break;
case 14:clear();setBody(11); bodyType=11;break;
case 15:clear();setBody(16); bodyType=16;break;
case 16:clear();setBody(17); bodyType=17;break;
case 17:clear();setBody(18); bodyType=18;break;
case 18:clear();setBody(15); bodyType=15;break;
case 19:break;
case 20:break;
/* case 21:clear();setBody(1); bodyType=1;break;
case 22:clear();setBody(4); bodyType=4;break;
case 23:clear();setBody(6); bodyType=6;break;
*/
}
}
private void clear(){
for(int r=0;r<bodyInfo.length;r++)
for(int c=0;c<bodyInfo[r].length;c++)
bodyInfo[r][c]=0;
}
}