Java项目--俄罗斯方块
Posted 范仁义
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java项目--俄罗斯方块相关的知识,希望对你有一定的参考价值。
Java项目--俄罗斯方块
百度盘链接
链接:http://pan.baidu.com/s/1mhQ9SYc 密码:9ujo
一、心得
二、游戏实例
游戏截图
目录结构
三、代码
1、主界面 Tetris.java
1 package com.hsj.tetris; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.Image; 7 import java.awt.event.KeyAdapter; 8 import java.awt.event.KeyEvent; 9 import java.util.Arrays; 10 import java.util.Timer; 11 import java.util.TimerTask; 12 13 import javax.imageio.ImageIO; 14 import javax.swing.JFrame; 15 import javax.swing.JPanel; 16 /** 17 * 俄罗斯方块游戏面板 18 * 19 */ 20 public class Tetris extends JPanel { 21 /** 正在下落方块 */ 22 private Tetromino tetromino; 23 /** 下一个下落方块 */ 24 private Tetromino nextOne; 25 /** 行数 */ 26 public static final int ROWS = 20; 27 /** 列数 */ 28 public static final int COLS = 10; 29 /** 墙 */ 30 private Cell[][] wall = new Cell[ROWS][COLS]; 31 /** 消掉的行数 */ 32 private int lines; 33 /** 分数 */ 34 private int score; 35 36 public static final int CELL_SIZE = 26; 37 38 private static Image background;//背景图片 39 public static Image I; 40 public static Image J; 41 public static Image L; 42 public static Image S; 43 public static Image Z; 44 public static Image O; 45 public static Image T; 46 static{//加载静态资源的,加载图片 47 //建议将图片放到 Tetris.java 同包中! 48 //从包中加载图片对象,使用Swing API实现 49 // Toolkit toolkit = Toolkit.getDefaultToolkit(); 50 // background = toolkit.getImage( 51 // Tetris.class.getResource("tetris.png")); 52 // T = toolkit.getImage(Tetris.class.getResource("T.png")); 53 // S = toolkit.getImage(Tetris.class.getResource("S.png")); 54 // Z = toolkit.getImage(Tetris.class.getResource("Z.png")); 55 // L = toolkit.getImage(Tetris.class.getResource("L.png")); 56 // J = toolkit.getImage(Tetris.class.getResource("J.png")); 57 // I = toolkit.getImage(Tetris.class.getResource("I.png")); 58 // O = toolkit.getImage(Tetris.class.getResource("O.png")); 59 //import javax.imageio.ImageIO; 60 try{ 61 background = ImageIO.read( 62 Tetris.class.getResource("tetris.png")); 63 T=ImageIO.read(Tetris.class.getResource("T.png")); 64 I=ImageIO.read(Tetris.class.getResource("I.png")); 65 S=ImageIO.read(Tetris.class.getResource("S.png")); 66 Z=ImageIO.read(Tetris.class.getResource("Z.png")); 67 L=ImageIO.read(Tetris.class.getResource("L.png")); 68 J=ImageIO.read(Tetris.class.getResource("J.png")); 69 O=ImageIO.read(Tetris.class.getResource("O.png")); 70 }catch(Exception e){ 71 e.printStackTrace(); 72 } 73 } 74 75 public void action(){ 76 //tetromino = Tetromino.randomTetromino(); 77 //nextOne = Tetromino.randomTetromino(); 78 //wall[19][2] = new Cell(19,2,Tetris.T); 79 startAction(); 80 repaint(); 81 KeyAdapter l = new KeyAdapter() { 82 public void keyPressed(KeyEvent e) { 83 int key = e.getKeyCode(); 84 if(key == KeyEvent.VK_Q){ 85 System.exit(0);//退出当前的Java进程 86 } 87 if(gameOver){ 88 if(key==KeyEvent.VK_S){ 89 startAction(); 90 } 91 return; 92 } 93 //如果暂停并且按键是[C]就继续动作 94 if(pause){//pause = false 95 if(key==KeyEvent.VK_C){ continueAction(); } 96 return; 97 } 98 //否则处理其它按键 99 switch(key){ 100 case KeyEvent.VK_RIGHT: moveRightAction(); break; 101 case KeyEvent.VK_LEFT: moveLeftAction(); break; 102 case KeyEvent.VK_DOWN: softDropAction() ; break; 103 case KeyEvent.VK_UP: rotateRightAction() ; break; 104 case KeyEvent.VK_Z: rotateLeftAction() ; break; 105 case KeyEvent.VK_SPACE: hardDropAction() ; break; 106 case KeyEvent.VK_P: pauseAction() ; break; 107 } 108 repaint(); 109 } 110 }; 111 this.requestFocus(); 112 this.addKeyListener(l); 113 } 114 115 public void paint(Graphics g){ 116 g.drawImage(background, 0, 0, null);//使用this 作为观察者 117 g.translate(15, 15);//平移绘图坐标系 118 paintTetromino(g);//绘制正在下落的方块 119 paintWall(g);//画墙 120 paintNextOne(g); 121 paintScore(g); 122 } 123 public static final int FONT_COLOR = 0x667799; 124 public static final int FONT_SIZE = 0x20; 125 private void paintScore(Graphics g) { 126 Font f = getFont();//获取当前的 面板默认字体 127 Font font = new Font( 128 f.getName(), Font.BOLD, FONT_SIZE); 129 int x = 290; 130 int y = 162; 131 g.setColor(new Color(FONT_COLOR)); 132 g.setFont(font); 133 String str = "SCORE:"+this.score; 134 g.drawString(str, x, y); 135 y+=56; 136 str = "LINES:"+this.lines; 137 g.drawString(str, x, y); 138 y+=56; 139 str = "[P]Pause"; 140 if(pause){str = "[C]Continue";} 141 if(gameOver){ str = "[S]Start!";} 142 g.drawString(str, x, y); 143 } 144 145 private void paintNextOne(Graphics g) { 146 Cell[] cells = nextOne.getCells(); 147 for(int i=0; i<cells.length; i++){ 148 Cell c = cells[i]; 149 int x = (c.getCol()+10) * CELL_SIZE-1; 150 int y = (c.getRow()+1) * CELL_SIZE-1; 151 g.drawImage(c.getImage(), x, y, null); 152 } 153 } 154 155 private void paintTetromino(Graphics g) { 156 Cell[] cells = tetromino.getCells(); 157 for(int i=0; i<cells.length; i++){ 158 Cell c = cells[i]; 159 int x = c.getCol() * CELL_SIZE-1; 160 int y = c.getRow() * CELL_SIZE-1; 161 //g.setColor(new Color(c.getColor())); 162 //g.fillRect(x, y, CELL_SIZE, CELL_SIZE); 163 g.drawImage(c.getImage(), x, y, null); 164 } 165 } 166 167 //在 Tetris 类 中添加 方法 paintWall 168 private void paintWall(Graphics g){ 169 for(int row=0; row<wall.length; row++){ 170 //迭代每一行, i = 0 1 2 ... 19 171 Cell[] line = wall[row]; 172 //line.length = 10 173 for(int col=0; col<line.length; col++){ 174 Cell cell = line[col]; 175 int x = col*CELL_SIZE; 176 int y = row*CELL_SIZE; 177 if(cell==null){ 178 //g.setColor(new Color(0)); 179 //画方形 180 //g.drawRect(x, y, CELL_SIZE, CELL_SIZE); 181 }else{ 182 g.drawImage(cell.getImage(), x-1, y-1, null); 183 } 184 } 185 } 186 } 187 /** 188 * 在 Tetris(俄罗斯方块) 类中增加方法 189 * 这个方法的功能是:软下落的动作 控制流程 190 * 完成功能:如果能够下落就下落,否则就着陆到墙上, 191 * 而新的方块出现并开始落下。 192 */ 193 public void softDropAction(){ 194 if(tetrominoCanDrop()){ 195 tetromino.softDrop(); 196 }else{ 197 tetrominoLandToWall(); 198 destroyLines();//破坏满的行 199 checkGameOver(); 200 tetromino = nextOne; 201 nextOne = Tetromino.randomTetromino(); 202 } 203 } 204 /** 销毁已经满的行,并且计分 205 * 1)迭代每一行 206 * 2)如果(检查)某行满是格子了 就销毁这行 207 **/ 208 public void destroyLines(){ 209 int lines = 0; 210 for(int row = 0; row<wall.length; row++){ 211 if(fullCells(row)){ 212 deleteRow(row); 213 lines++; 214 } 215 } 216 // lines = ? 217 this.lines += lines;//0 1 2 3 4 218 this.score += SCORE_TABLE[lines]; 219 } 220 private static final int[] SCORE_TABLE={0,1,10,30,200}; 221 // 0 1 2 3 4 222 223 public boolean fullCells(int row){ 224 Cell[] line = wall[row]; 225 for(int i=0; i<line.length; i++){ 226 if(line[i]==null){//如果有空格式就不是满行 227 return false; 228 } 229 } 230 return true; 231 } 232 public void deleteRow(int row){ 233 for(int i=row; i>=1; i--){ 234 //复制 [i-1] -> [i] 235 System.arraycopy(wall[i-1], 0, wall[i], 0, COLS); 236 } 237 Arrays.fill(wall[0], null); 238 } 239 240 /** 检查当前的4格方块能否继续下落 */ 241 public boolean tetrominoCanDrop(){ 242 Cell[] cells = tetromino.getCells(); 243 for(int i = 0; i<cells.length; i++){ 244 Cell cell = cells[i]; 245 int row = cell.getRow(); int col = cell.getCol(); 246 if(row == ROWS-1){return false;}//到底就不能下降了 247 } 248 for(int i = 0; i<cells.length; i++){ 249 Cell cell = cells[i]; 250 int row = cell.getRow(); int col = cell.getCol(); 251 if(wall[row+1][col] != null){ 252 return false;//下方墙上有方块就不能下降了 253 } 254 } 255 return true; 256 } 257 /** 4格方块着陆到墙上 */ 258 public void tetrominoLandToWall(){ 259 Cell[] cells = tetromino.getCells(); 260 for(int i=0; i<cells.length; i++){ 261 Cell cell = cells[i]; 262 int row = cell.getRow(); 263 int col = cell.getCol(); 264 wall[row][col] = cell; 265 } 266 } 267 268 public void moveRightAction(){ 269 tetromino.moveRight(); 270 if(outOfBound() || coincide()){ 271 tetromino.moveLeft(); 272 } 273 } 274 public void moveLeftAction(){ 275 tetromino.moveLeft(); 276 if(outOfBound() || coincide()){ 277 tetromino.moveRight(); 278 } 279 } 280 /** ... */ 281 private boolean outOfBound(){ 282 Cell[] cells = tetromino.getCells(); 283 for(int i=0; i<cells.length; i++){ 284 Cell cell = cells[i]; 285 int col = cell.getCol(); 286 if(col<0 || col>=COLS){ 287 return true;//出界了 288 } 289 } 290 return false; 291 } 292 private boolean coincide(){ 293 Cell[] cells = tetromino.getCells(); 294 //for each 循环、迭代,简化了"数组迭代书写" 295 for(Cell cell: cells){//Java 5 以后提供增强版for循环 296 int row = cell.getRow(); 297 int col = cell.getCol(); 298 if(row<0 || row>=ROWS || col<0 || col>=COLS || 299 wall[row][col]!=null){ 300 return true; //墙上有格子对象,发生重合 301 } 302 } 303 return false; 304 } 305 /** 向右旋转动作 */ 306 public void rotateRightAction(){ 307 //旋转之前 308 //System.out.println(tetromino); 309 tetromino.rotateRight(); 310 //System.out.println(tetromino); 311 //旋转之后 312 if(outOfBound() || coincide()){ 313 tetromino.rotateLeft(); 314 } 315 } 316 317 /** Tetris 类中添加的方法 */ 318 public void rotateLeftAction(){ 319 tetromino.rotateLeft(); 320 if(outOfBound() || coincide()){ 321 tetromino.rotateRight(); 322 } 323 } 324 public void hardDropAction(){ 325 while(tetrominoCanDrop()){ 326 tetromino.softDrop(); 327 } 328 tetrominoLandToWall(); 329 destroyLines(); 330 checkGameOver(); 331 tetromino = nextOne; 332 nextOne = Tetromino.randomTetromino(); 333 } 334 335 private boolean pause; 336 private boolean gameOver; 337 private Timer timer; 338 /** Tetris 类中添加的方法, 用于启动游戏 */ 339 public void startAction(){ 340 clearWall(); 341 tetromino = Tetromino.randomTetromino(); 342 nextOne = Tetromino.randomTetromino(); 343 lines = 0; score = 0; pause=false; gameOver=false; 344 timer = new Timer(); 345 timer.schedule(new TimerTask(){ 346 public void run() { 347 softDropAction(); 348 repaint(); 349 } 350 }, 700, 700); 351 } 352 353 private void clearWall(){ 354 //将墙的每一行的每个格子清理为null 355 for(int row=0; row<ROWS; row++){ 356 Arrays.fill(wall[row], null); 357 } 358 } 359 360 /** 在Tetris 类中添加方法 */ 361 public void pauseAction(){ 362 timer.cancel(); //停止定时器 363 pause = true; 364 repaint(); 365 } 366 public void continueAction(){ 367 timer = new Timer(); 368 timer.schedule(new TimerTask() { 369 public void run() { 370 softDropAction(); 371 repaint(); 372 } 373 }, 700, 700); 374 pause =以上是关于Java项目--俄罗斯方块的主要内容,如果未能解决你的问题,请参考以下文章