package Game1; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.Timer; public class Tetris extends JFrame { public Tetris(){ TetrisPanel tetris=new TetrisPanel(); this.addKeyListener(tetris.listener); add(tetris); setSize(220, 275); setLocation(400, 100); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setTitle("俄罗斯方块"); setResizable(false); } public static void main(String[] args) { Tetris te=new Tetris(); te.setVisible(true); } class TetrisPanel extends JPanel{ private int x,y; //用来表示方块位置 private int blockType; //用来表示方块形态,如:L型,J型,Z型。。。0-6 private int turnState; //用来表示每个形态的变化方法,以下每个形态4种变化0-3 private TimeListerner listener=new TimeListerner(); private Timer timer; private int delay; private int score; int map[][]=new int[13][23]; //表示地图,游戏背景 //以下用三维数组存储,第一维用取随机数来生成方块表示blockType,第二维用来表示方块旋转次数,三维代表方块矩阵 int shape[][][]=new int[][][]{ { //I型长条方块 {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0} }, //L型方块 { {1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0}, {1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, {1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0}, {0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0} }, //S型方块 { { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }, //Z型方块 { { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } }, //O型方块 { { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, //T型方块 { { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }, //J型方块 { { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }; public TetrisPanel(){ nextBlock(); newGame(); } public void down(){ //向下控制 if(crash(x,y+1,blockType,turnState)==0){ add( x, y, blockType, turnState); nextBlock(); } y++; repaint(); } public void upturn() { //按键上的控制(即变换形态) turnState=(turnState+crash(x, y, blockType, (turnState+1)%4))%4; repaint(); } public void left(){ //左控制 if(x>=0){ x-=+crash(x-1, y, blockType, turnState); repaint(); } } public void right(){ //右控制 if(x<8){ x+=crash(x+1, y, blockType, turnState); repaint(); } } //判断是否碰撞 public int crash(int x,int y,int blockType,int turnState){ for(int a=0;a<4;a++){ for(int b=0;b<4;b++){ if((shape[blockType][turnState][a*4+b] & map[x+b+1][y+a])==1){ return 0; } } } return 1; } //把增加的方块搞到地图上面去,用表示方块形状的三维数组和地图的二维数组控制,如果碰到,则把方块此时的坐标和地图的坐标相加,得出新的值(即新的地图) public void add(int x,int y,int blockType,int turnState){ for(int a=0;a<4;a++){ for(int b=0;b<4;b++){ if(shape[blockType][turnState][a*4+b]==1){ map[x + b + 1][y + a] = shape[blockType][turnState][a * 4 + b]; } } } TryDeline(); } private void newGame() { for(int i=0;i<12;i++){ //初始化地图,地图看成是由12*22的方块构成 for(int j=0;j<22;j++){ map[i][j]=0; map[11][j]=map[0][j]=3; //边界赋值3,用于下面画出边界,下面代码思想是如果map[i][j]=3,那么就画一个红色格子当分界线 } map[i][21]=3; //此处赋值最下面一层的值 } delay=1000; //速度初始值 timer=new Timer(delay, listener); timer.start(); nextBlock(); //下一个方块 repaint(); //刷新地图 } //消行的代码 private void TryDeline(){ //先遍历整个map看map中有没有一行整个都是满的,如果都是满的,那么map【a】【b】=1,与1(以下代码用的一个整形c)相&就是1;否则为0 for(int b=0;b<21;b++){ //表示多少行 int c=1; for(int a=0;a<12;a++){ //表示每列,用来看该行是否满的格子 c&=map[a][b]; } //以下是消除,如果满了(即c=1),就把上一行的赋给下一行, if(c==1){ for(int d=b;d>0;d--){ for(int e=1;e<11;e++){ map[e][d]=map[e][d-1]; } } //以下是分数的加法和速度的变化 score+=10; if(delay>500){ delay-=50; }else if(delay>200){ delay-=40; }else { delay=200; } } } } private void nextBlock() { blockType=(int) (Math.random()*1000)%7; //用随机数生成新的类型 turnState=(int) (Math.random()*1000)%4; //用随机数生成新类型中的形态 x=4; //表示生成位置的X坐标 y=0; //表示生成位置的Y坐标 if (crash(x, y, blockType, turnState) == 0) { timer.stop(); int option = JOptionPane.showConfirmDialog(this, "Game Over!!您的最后得分是:"+score); if (option == JOptionPane.OK_OPTION) { newGame(); score=0; } else if (option == JOptionPane.NO_OPTION) { System.exit(0); } } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.blue); //画出当前形态 for(int j=0;j<16;j++){ if(shape[blockType][turnState][j]==1){ g.fillRect((j%4+x+1)*10,(j/4+y)*10, 10, 10); } } //画地图 g.setColor(Color.red); for(int j=0;j<22;j++){ for(int i=0;i<12;i++){ if(map[i][j]==1){ g.fillRect(i*10, j*10, 10, 10); // 让堆积块有分界线 g.setColor(Color.green); g.drawRect(i * 10, j * 10, 10, 10); g.setColor(Color.red); }else if(map[i][j]==3){ g.drawRect(i*10, j*10, 10, 10); } } } //设置界面左右边的显示界面 g.setColor(Color.blue); g.setFont(new Font("aa", Font.BOLD, 15)); g.drawString("score="+score, 130, 20); g.setFont(new Font("aa", Font.ITALIC,13)); g.drawString("关爱残疾人", 130, 70); g.drawString("远离鲁阿鲁", 130, 90); g.drawString("俄罗斯方块", 130, 110); g.drawString("益身心健康", 130, 130); g.drawString("防受骗上当", 130, 150); g.drawString("这游戏益脑", 130, 170); } //以下是添加的键盘监听 class TimeListerner extends KeyAdapter implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { down(); } @Override public void keyPressed(KeyEvent e) { int keycode=e.getKeyCode(); switch (keycode) { case KeyEvent.VK_DOWN: //方向键下的监听 down(); //方法在上面 break; case KeyEvent.VK_UP: //方向键上的监听 upturn(); //方法在上面 break; case KeyEvent.VK_LEFT: //方向键左的监听 left(); break; case KeyEvent.VK_RIGHT: //方向键右的监听 right(); break; } } } } }
俄罗斯方块代码
猜你喜欢
转载自blog.csdn.net/asd529735325/article/details/50925064
今日推荐
周排行