一个俄罗斯方块的源码

  1. package mypack;  
  2.   
  3. import java.awt.*;  
  4. import java.awt.event.*;  
  5.   
  6. //俄罗斯方块类   
  7. public class ERS_Block extends Frame {  
  8.     /** 
  9.      *  
  10.      */  
  11.     private static final long serialVersionUID = -1443760309099067025L;  
  12.   
  13.     public static boolean isPlay = false;  
  14.   
  15.     public static int level = 1, score = 0;  
  16.   
  17.     public static TextField scoreField, levelField;  
  18.   
  19.     public static MyTimer timer;  
  20.   
  21.     GameCanvas gameScr;  
  22.   
  23.     public static void main(String[] argus) {  
  24.         ERS_Block ers = new ERS_Block("俄罗斯方块游戏 V1.0 Author:Vincent");  
  25.         WindowListener win_listener = new WinListener();  
  26.         ers.addWindowListener(win_listener);  
  27.     }  
  28.   
  29.     // 俄罗斯方块类的构造方法  
  30.     ERS_Block(String title) {  
  31.         super(title);  
  32.   
  33.         setSize(600480);  
  34.         setLayout(new GridLayout(12));  
  35.   
  36.         gameScr = new GameCanvas();  
  37.         gameScr.addKeyListener(gameScr);  
  38.   
  39.         timer = new MyTimer(gameScr);  
  40.         timer.setDaemon(true);  
  41.         timer.start();  
  42.         timer.suspend();  
  43.   
  44.         add(gameScr);  
  45.   
  46.         Panel rightScr = new Panel();  
  47.         rightScr.setLayout(new GridLayout(21030));  
  48.         rightScr.setSize(120500);  
  49.         add(rightScr);  
  50.   
  51.         // 右边信息窗体的布局  
  52.         MyPanel infoScr = new MyPanel();  
  53.         infoScr.setLayout(new GridLayout(4105));  
  54.         infoScr.setSize(120300);  
  55.         rightScr.add(infoScr);  
  56.   
  57.         // 定义标签和初始值  
  58.         Label scorep = new Label("分数:", Label.LEFT);  
  59.         Label levelp = new Label("级数:", Label.LEFT);  
  60.         scoreField = new TextField(8);  
  61.         levelField = new TextField(8);  
  62.         scoreField.setEditable(false);  
  63.         levelField.setEditable(false);  
  64.         infoScr.add(scorep);  
  65.         infoScr.add(scoreField);  
  66.         infoScr.add(levelp);  
  67.         infoScr.add(levelField);  
  68.         scorep.setSize(new Dimension(2060));  
  69.         scoreField.setSize(new Dimension(2060));  
  70.         levelp.setSize(new Dimension(2060));  
  71.         levelField.setSize(new Dimension(2060));  
  72.         scoreField.setText("0");  
  73.         levelField.setText("1");  
  74.   
  75.         // 右边控制按钮窗体的布局  
  76.         MyPanel controlScr = new MyPanel();  
  77.         controlScr.setLayout(new GridLayout(5105));  
  78.         rightScr.add(controlScr);  
  79.   
  80.         // 定义按钮play  
  81.         Button play_b = new Button("开始游戏");  
  82.         play_b.setSize(new Dimension(50200));  
  83.         play_b.addActionListener(new Command(Command.button_play, gameScr));  
  84.   
  85.         // 定义按钮Level UP  
  86.         Button level_up_b = new Button("提高级数");  
  87.         level_up_b.setSize(new Dimension(50200));  
  88.         level_up_b.addActionListener(new Command(Command.button_levelup,  
  89.                 gameScr));  
  90.   
  91.         // 定义按钮Level Down  
  92.         Button level_down_b = new Button("降低级数");  
  93.         level_down_b.setSize(new Dimension(50200));  
  94.         level_down_b.addActionListener(new Command(Command.button_leveldown,  
  95.                 gameScr));  
  96.   
  97.         // 定义按钮Level Pause  
  98.         Button pause_b = new Button("游戏暂停");  
  99.         pause_b.setSize(new Dimension(50200));  
  100.         pause_b.addActionListener(new Command(Command.button_pause, gameScr));  
  101.   
  102.         // 定义按钮Quit  
  103.         Button quit_b = new Button("退出游戏");  
  104.         quit_b.setSize(new Dimension(50200));  
  105.         quit_b.addActionListener(new Command(Command.button_quit, gameScr));  
  106.   
  107.         controlScr.add(play_b);  
  108.         controlScr.add(level_up_b);  
  109.         controlScr.add(level_down_b);  
  110.         controlScr.add(pause_b);  
  111.         controlScr.add(quit_b);  
  112.         setVisible(true);  
  113.         gameScr.requestFocus();  
  114.     }  
  115. }  
  116.   
  117. // 重写MyPanel类,使Panel的四周留空间  
  118. class MyPanel extends Panel {  
  119.     public Insets getInsets() {  
  120.         return new Insets(30503050);  
  121.     }  
  122. }  
  123.   
  124. // 游戏画布类  
  125. class GameCanvas extends Canvas implements KeyListener {  
  126.     final int unitSize = 30// 小方块边长  
  127.   
  128.     int rowNum; // 正方格的行数  
  129.   
  130.     int columnNum; // 正方格的列数  
  131.   
  132.     int maxAllowRowNum; // 允许有多少行未削  
  133.   
  134.     int blockInitRow; // 新出现块的起始行坐标  
  135.   
  136.     int blockInitCol; // 新出现块的起始列坐标  
  137.   
  138.     int[][] scrArr; // 屏幕数组  
  139.   
  140.     Block b; // 对方快的引用  
  141.   
  142.     // 画布类的构造方法  
  143.     GameCanvas() {  
  144.         rowNum = 15;  
  145.         columnNum = 10;  
  146.         maxAllowRowNum = rowNum - 2;  
  147.         b = new Block(this);  
  148.         blockInitRow = rowNum - 1;  
  149.         blockInitCol = columnNum / 2 - 2;  
  150.         scrArr = new int[32][32];  
  151.     }  
  152.   
  153.     // 初始化屏幕,并将屏幕数组清零的方法  
  154.     void initScr() {  
  155.         for (int i = 0; i < rowNum; i++)  
  156.             for (int j = 0; j < columnNum; j++)  
  157.                 scrArr[i][j] = 0;  
  158.         b.reset();  
  159.         repaint();  
  160.     }  
  161.   
  162.     // 重新刷新画布方法  
  163.     public void paint(Graphics g) {  
  164.         for (int i = 0; i < rowNum; i++)  
  165.             for (int j = 0; j < columnNum; j++)  
  166.                 drawUnit(i, j, scrArr[i][j]);  
  167.     }  
  168.   
  169.     // 画方块的方法  
  170.     public void drawUnit(int row, int col, int type) {  
  171.         scrArr[row][col] = type;  
  172.         Graphics g = getGraphics();  
  173.         switch (type) { // 表示画方快的方法  
  174.         case 0:  
  175.             g.setColor(Color.black);  
  176.             break// 以背景为颜色画  
  177.         case 1:  
  178.             g.setColor(Color.blue);  
  179.             break// 画正在下落的方块  
  180.         case 2:  
  181.             g.setColor(Color.magenta);  
  182.             break// 画已经落下的方法  
  183.         }  
  184.         g.fill3DRect(col * unitSize, getSize().height - (row + 1) * unitSize,  
  185.                 unitSize, unitSize, true);  
  186.         g.dispose();  
  187.     }  
  188.   
  189.     public Block getBlock() {  
  190.         return b; // 返回block实例的引用  
  191.     }  
  192.   
  193.     // 返回屏幕数组中(row,col)位置的属性值  
  194.     public int getScrArrXY(int row, int col) {  
  195.         if (row < 0 || row >= rowNum || col < 0 || col >= columnNum)  
  196.             return (-1);  
  197.         else  
  198.             return (scrArr[row][col]);  
  199.     }  
  200.   
  201.     // 返回新块的初始行坐标方法  
  202.     public int getInitRow() {  
  203.         return (blockInitRow); // 返回新块的初始行坐标  
  204.     }  
  205.   
  206.     // 返回新块的初始列坐标方法  
  207.     public int getInitCol() {  
  208.         return (blockInitCol); // 返回新块的初始列坐标  
  209.     }  
  210.   
  211.     // 满行删除方法  
  212.     void deleteFullLine() {  
  213.         int full_line_num = 0;  
  214.         int k = 0;  
  215.         for (int i = 0; i < rowNum; i++) {  
  216.             boolean isfull = true;  
  217.   
  218.             L1: for (int j = 0; j < columnNum; j++)  
  219.                 if (scrArr[i][j] == 0) {  
  220.                     k++;  
  221.                     isfull = false;  
  222.                     break L1;  
  223.                 }  
  224.             if (isfull)  
  225.                 full_line_num++;  
  226.             if (k != 0 && k - 1 != i && !isfull)  
  227.                 for (int j = 0; j < columnNum; j++) {  
  228.                     if (scrArr[i][j] == 0)  
  229.                         drawUnit(k - 1, j, 0);  
  230.                     else  
  231.                         drawUnit(k - 1, j, 2);  
  232.                     scrArr[k - 1][j] = scrArr[i][j];  
  233.                 }  
  234.         }  
  235.         for (int i = k - 1; i < rowNum; i++) {  
  236.             for (int j = 0; j < columnNum; j++) {  
  237.                 drawUnit(i, j, 0);  
  238.                 scrArr[i][j] = 0;  
  239.             }  
  240.         }  
  241.         ERS_Block.score += full_line_num;  
  242.         ERS_Block.scoreField.setText("" + ERS_Block.score);  
  243.     }  
  244.   
  245.     // 判断游戏是否结束方法  
  246.     boolean isGameEnd() {  
  247.         for (int col = 0; col < columnNum; col++) {  
  248.             if (scrArr[maxAllowRowNum][col] != 0)  
  249.                 return true;  
  250.         }  
  251.         return false;  
  252.     }  
  253.   
  254.     public void keyTyped(KeyEvent e) {  
  255.     }  
  256.   
  257.     public void keyReleased(KeyEvent e) {  
  258.     }  
  259.   
  260.     // 处理键盘输入的方法  
  261.     public void keyPressed(KeyEvent e) {  
  262.         if (!ERS_Block.isPlay)  
  263.             return;  
  264.         switch (e.getKeyCode()) {  
  265.         case KeyEvent.VK_DOWN:  
  266.             b.fallDown();  
  267.             break;  
  268.         case KeyEvent.VK_LEFT:  
  269.             b.leftMove();  
  270.             break;  
  271.         case KeyEvent.VK_RIGHT:  
  272.             b.rightMove();  
  273.             break;  
  274.         case KeyEvent.VK_SPACE:  
  275.             b.leftTurn();  
  276.             break;  
  277.         }  
  278.     }  
  279. }  
  280.   
  281. // 处理控制类  
  282. class Command implements ActionListener {  
  283.     static final int button_play = 1// 给按钮分配编号  
  284.   
  285.     static final int button_levelup = 2;  
  286.   
  287.     static final int button_leveldown = 3;  
  288.   
  289.     static final int button_quit = 4;  
  290.   
  291.     static final int button_pause = 5;  
  292.   
  293.     static boolean pause_resume = true;  
  294.   
  295.     int curButton; // 当前按钮  
  296.   
  297.     GameCanvas scr;  
  298.   
  299.     // 控制按钮类的构造方法  
  300.     Command(int button, GameCanvas scr) {  
  301.         curButton = button;  
  302.         this.scr = scr;  
  303.     }  
  304.   
  305.     // 按钮执行方法  
  306.     public void actionPerformed(ActionEvent e) {  
  307.         switch (curButton) {  
  308.         case button_play:  
  309.             if (!ERS_Block.isPlay) {  
  310.                 scr.initScr();  
  311.                 ERS_Block.isPlay = true;  
  312.                 ERS_Block.score = 0;  
  313.                 ERS_Block.scoreField.setText("0");  
  314.                 ERS_Block.timer.resume();  
  315.             }  
  316.             scr.requestFocus();  
  317.             break;  
  318.         case button_levelup:  
  319.             if (ERS_Block.level < 10) {  
  320.                 ERS_Block.level++;  
  321.                 ERS_Block.levelField.setText("" + ERS_Block.level);  
  322.                 ERS_Block.score = 0;  
  323.                 ERS_Block.scoreField.setText("" + ERS_Block.score);  
  324.             }  
  325.             scr.requestFocus();  
  326.             break;  
  327.         case button_leveldown:  
  328.             if (ERS_Block.level > 1) {  
  329.                 ERS_Block.level--;  
  330.                 ERS_Block.levelField.setText("" + ERS_Block.level);  
  331.                 ERS_Block.score = 0;  
  332.                 ERS_Block.scoreField.setText("" + ERS_Block.score);  
  333.             }  
  334.             scr.requestFocus();  
  335.             break;  
  336.         case button_pause:  
  337.             if (pause_resume) {  
  338.                 ERS_Block.timer.suspend();  
  339.                 pause_resume = false;  
  340.             } else {  
  341.                 ERS_Block.timer.resume();  
  342.                 pause_resume = true;  
  343.             }  
  344.             scr.requestFocus();  
  345.             break;  
  346.         case button_quit:  
  347.             System.exit(0);  
  348.         }  
  349.     }  
  350. }  
  351.   
  352. // 方块类  
  353. class Block {  
  354.     static int[][] pattern = {  
  355.             { 0x0f000x44440x0f000x4444 },// 用十六进至表示,本行表示长条四种状态  
  356.             { 0x04e00x04640x00e40x04c4 },  
  357.             { 0x46200x6c000x46200x6c00 },  
  358.             { 0x26400xc6000x26400xc600 },  
  359.             { 0x62200x17000x22300x0740 },  
  360.             { 0x64400x0e200x44c00x8e00 },  
  361.             { 0x06600x06600x06600x0660 } };  
  362.   
  363.     int blockType; // 块的模式号(0-6)  
  364.   
  365.     int turnState; // 块的翻转状态(0-3)  
  366.   
  367.     int blockState; // 快的下落状态  
  368.   
  369.     int row, col; // 块在画布上的坐标  
  370.   
  371.     GameCanvas scr;  
  372.   
  373.     // 块类的构造方法  
  374.     Block(GameCanvas scr) {  
  375.         this.scr = scr;  
  376.         blockType = (int) (Math.random() * 1000) % 7;  
  377.         turnState = (int) (Math.random() * 1000) % 4;  
  378.         blockState = 1;  
  379.         row = scr.getInitRow();  
  380.         col = scr.getInitCol();  
  381.     }  
  382.   
  383.     // 重新初始化块,并显示新块  
  384.     public void reset() {  
  385.         blockType = (int) (Math.random() * 1000) % 7;  
  386.         turnState = (int) (Math.random() * 1000) % 4;  
  387.         blockState = 1;  
  388.         row = scr.getInitRow();  
  389.         col = scr.getInitCol();  
  390.         dispBlock(1);  
  391.     }  
  392.   
  393.     // 实现“块”翻转的方法  
  394.     public void leftTurn() {  
  395.         if (assertValid(blockType, (turnState + 1) % 4, row, col)) {  
  396.             dispBlock(0);  
  397.             turnState = (turnState + 1) % 4;  
  398.             dispBlock(1);  
  399.         }  
  400.     }  
  401.   
  402.     // 实现“块”的左移的方法  
  403.     public void leftMove() {  
  404.         if (assertValid(blockType, turnState, row, col - 1)) {  
  405.             dispBlock(0);  
  406.             col--;  
  407.             dispBlock(1);  
  408.         }  
  409.     }  
  410.   
  411.     // 实现块的右移  
  412.     public void rightMove() {  
  413.         if (assertValid(blockType, turnState, row, col + 1)) {  
  414.             dispBlock(0);  
  415.             col++;  
  416.             dispBlock(1);  
  417.         }  
  418.     }  
  419.   
  420.     // 实现块落下的操作的方法  
  421.     public boolean fallDown() {  
  422.         if (blockState == 2)  
  423.             return (false);  
  424.         if (assertValid(blockType, turnState, row - 1, col)) {  
  425.             dispBlock(0);  
  426.             row--;  
  427.             dispBlock(1);  
  428.             return (true);  
  429.         } else {  
  430.             blockState = 2;  
  431.             dispBlock(2);  
  432.             return (false);  
  433.         }  
  434.     }  
  435.   
  436.     // 判断是否正确的方法  
  437.     boolean assertValid(int t, int s, int row, int col) {  
  438.         int k = 0x8000;  
  439.         for (int i = 0; i < 4; i++) {  
  440.             for (int j = 0; j < 4; j++) {  
  441.                 if ((int) (pattern[t][s] & k) != 0) {  
  442.                     int temp = scr.getScrArrXY(row - i, col + j);  
  443.                     if (temp < 0 || temp == 2)  
  444.                         return false;  
  445.                 }  
  446.                 k = k >> 1;  
  447.             }  
  448.         }  
  449.         return true;  
  450.     }  
  451.   
  452.     // 同步显示的方法  
  453.     public synchronized void dispBlock(int s) {  
  454.         int k = 0x8000;  
  455.         for (int i = 0; i < 4; i++) {  
  456.             for (int j = 0; j < 4; j++) {  
  457.                 if (((int) pattern[blockType][turnState] & k) != 0) {  
  458.                     scr.drawUnit(row - i, col + j, s);  
  459.                 }  
  460.                 k = k >> 1;  
  461.             }  
  462.         }  
  463.     }  
  464. }  
  465.   
  466. // 定时线程  
  467. class MyTimer extends Thread {  
  468.     GameCanvas scr;  
  469.   
  470.     public MyTimer(GameCanvas scr) {  
  471.         this.scr = scr;  
  472.     }  
  473.   
  474.     public void run() {  
  475.         while (true) {  
  476.             try {  
  477.                 sleep((10 - ERS_Block.level + 1) * 100);  
  478.             } catch (InterruptedException e) {  
  479.             }  
  480.             if (!scr.getBlock().fallDown()) {  
  481.                 scr.deleteFullLine();  
  482.                 if (scr.isGameEnd()) {  
  483.                     ERS_Block.isPlay = false;  
  484.                     suspend();  
  485.                 } else  
  486.                     scr.getBlock().reset();  
  487.             }  
  488.         }  
  489.     }  
  490. }  
  491.   
  492. class WinListener extends WindowAdapter {  
  493.     public void windowClosing(WindowEvent l) {  
  494.         System.exit(0);  
  495.     }  
  496. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值