TETRIS 项目开发笔记

  java学习一个月了,没有什么进展,期间又是复习Linux,又是看Android,瞻前顾后,感觉自己真的是贪得无厌,

学习的东西广而不精,所以写出的文章也就只能泛泛而谈。五一小长假,哪里都没有去,也不想去,刚刚无聊刷新了下

朋友圈,朋友们不是在玩,就是在吃,突然一下子感觉自己老了许多。岁月真是把杀猪刀,夺走了我们的青春,但却无

法夺走我们的激情。

  好好复习了!

  在老师引领下,算是把人生中的第一个Java项目敲完了,感觉对于学习OOP的朋友,应该有所帮助,先做个笔记吧

等后期有时间再添些自己的Feature。

TETRIS 项目开发笔记

package com.manue1.tetris;



import javax.swing.JFrame;



/**

 * 游戏窗口

 * @author Manue1

 * @version 1.0

 *

 */

public class GameFrame extends JFrame{

  

    private static final long serialVersionUID = 1L;

    private Tetris tetris;

    public GameFrame(){

        

        tetris =new Tetris();

        add(tetris);

        setSize(530,580);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setLocationRelativeTo(null);

    }

  public static void main(String[] args){

      GameFrame frame =new GameFrame();

      frame.setVisible(true);

      frame.tetris.action();           //创建4个格子



  }



}
 1 package com.manue1.tetris;

 2 

 3 import java.awt.image.BufferedImage;

 4 

 5  /**

 6   * 定义格子

 7   * @author Manue1

 8   */

 9 public class Cell extends Object{

10     private int row; int col;

11     private BufferedImage image;

12     

13     public Cell(int row, int col, BufferedImage image) {

14         super();

15         this.row = row;

16         this.col = col;

17         this.image = image;

18     }

19 

20     public int getRow() {

21         return row;

22     }

23 

24     public void setRow(int row) {

25         this.row = row;

26     }

27 

28     public int getCol() {

29         return col;

30     }

31 

32     public void setCol(int col) {

33         this.col = col;

34     }

35 

36     public BufferedImage getImage() {

37         return image;

38     }

39 

40     public void setImage(BufferedImage image) {

41         this.image = image;

42     }

43 

44     @Override

45     public String toString() {

46         return "Cell [col=" + col + ", image=" + image + ", row=" + row + "]";

47     }

48     

49     

50     public void moveLeft(){

51         col--;

52     }

53     public void moveRight(){

54         col++;

55     }

56     public void moveDrop(){

57         row++;

58     }

59 

60     

61 }
定义格子
  1 package com.manue1.tetris;

  2 import java.util.Arrays;

  3 import java.util.Random;

  4 

  5 /**

  6  * 4格方块 

  7  * 只能被子类使用

  8  * @author Manue1

  9  */

 10 public abstract class Tetromino {

 11 

 12     protected Cell[] cells =new Cell[4];//{^,^,^,^}

 13     

 14     /*旋转状态

 15      * 

 16      */

 17     protected State[] states;

 18     /* 旋转状态的序号

 19      * 

 20      */

 21     protected int index =10000;

 22     /*内部类

 23      * 

 24      */

 25     protected class State {

 26         int row0, col0, row1, col1, row2, col2, row3, col3;

 27         public State(int row0, int col0, int row1, int col1, int row2,

 28                 int col2, int row3, int col3) {

 29             this.row0 = row0;

 30             this.col0 = col0;

 31             this.row1 = row1;

 32             this.col1 = col1;

 33             this.row2 = row2;

 34             this.col2 = col2;

 35             this.row3 = row3;

 36             this.col3 = col3;

 37         }

 38     }

 39     /** 向右转 */

 40     public void rotateRight() {

 41     

 42         index++;

 43         State s = states[index % states.length];

 44         Cell o = cells[0];

 45         int row = o.getRow();

 46         int col = o.getCol();

 47         cells[1].setRow(row + s.row1);

 48         cells[1].setCol(col + s.col1);

 49         cells[2].setRow(row + s.row2);

 50         cells[2].setCol(col + s.col2);

 51         cells[3].setRow(row + s.row3);

 52         cells[3].setCol(col + s.col3);

 53     }

 54     

 55     /** 向左转 */

 56     public void rotateLeft() {

 57         index--;

 58         State s = states[index % states.length];

 59         Cell o = cells[0];

 60         int row = o.getRow();

 61         int col = o.getCol();

 62         cells[1].setRow(row + s.row1);

 63         cells[1].setCol(col + s.col1);

 64         cells[2].setRow(row + s.row2);

 65         cells[2].setCol(col + s.col2);

 66         cells[3].setRow(row + s.row3);

 67         cells[3].setCol(col + s.col3);

 68     }

 69     

 70     

 71     

 72     //工厂方法,随机产生4格方块

 73 

 74     public static Tetromino randomOne(){

 75         Random random =new Random();

 76         int type =random.nextInt(7);

 77         switch(type){

 78         case 0:

 79             return new T();

 80         case 1:

 81             return new I();

 82         case 2:

 83             return new S();

 84         case 3:

 85             return new J();

 86         case 4:

 87             return new L();

 88         case 5:

 89             return new Z();

 90         case 6:

 91             return new O();

 92         }

 93         

 94         return null;

 95         

 96     }

 97     

 98     

 99     //方块下落  左右移动 一个格子

100     public void moveRight(){

101         for(int i=0;i<cells.length ;i++){

102             cells[i].moveRight();

103         }

104     }

105     public void moveLeft(){

106         for(int i=0;i<cells.length ;i++){

107             cells[i].moveLeft();

108         }

109     }

110     public void sofeDrop(){

111         for(int i=0;i<cells.length ;i++){

112             cells[i].moveDrop();

113         }

114     }

115     //显示方块中每个格子的行列信息

116     public String toString(){

117         return Arrays.toString(cells);

118     }

119 

120 }

121 

122 // 定义七类格子

123 class T extends Tetromino{

124     public T(){

125         cells[0]=new Cell(0,4,Tetris.T);

126         cells[1]=new Cell(0,3,Tetris.T);

127         cells[2]=new Cell(0,5,Tetris.T);

128         cells[3]=new Cell(1,4,Tetris.T);

129         states = new State[4];

130         states[0] = new State(0, 0, 0, -1, 0, 1, 1, 0);

131         states[1] = new State(0, 0, -1, 0, 1, 0, 0, -1);

132         states[2] = new State(0, 0, 0, 1, 0, -1, -1, 0);

133         states[3] = new State(0, 0, 1, 0, -1, 0, 0, 1);

134     }

135 }

136 class S extends Tetromino{

137     public S(){

138         cells[0]=new Cell(0,4,Tetris.S);

139         cells[1]=new Cell(0,5,Tetris.S);

140         cells[2]=new Cell(1,3,Tetris.S);

141         cells[3]=new Cell(1,4,Tetris.S);

142         

143         

144         states = new State[] { new State(0, 0, 0, -1, -1, 0, -1, 1),

145                 new State(0, 0, -1, 0, 0, 1, 1, 1) };

146         

147     }

148 }

149 class Z extends Tetromino{

150      public Z() {

151             cells[0] = new Cell(1, 4, Tetris.Z);

152             cells[1] = new Cell(0, 3, Tetris.Z);

153             cells[2] = new Cell(0, 4, Tetris.Z);

154             cells[3] = new Cell(1, 5, Tetris.Z);

155             

156             states = new State[] { new State(0, 0, -1, -1, -1, 0, 0, 1),

157                     new State(0, 0, -1, 1, 0, 1, 1, 0) };

158         }

159 }

160 class O extends Tetromino{

161      public O() {

162             cells[0] = new Cell(0, 4, Tetris.O);

163             cells[1] = new Cell(0, 5, Tetris.O);

164             cells[2] = new Cell(1, 4, Tetris.O);

165             cells[3] = new Cell(1, 5, Tetris.O);

166             states = new State[] { new State(0, 0, 0, 1, 1, 0, 1, 1),

167                     new State(0, 0, 0, 1, 1, 0, 1, 1) };

168         }

169 }

170 class J extends Tetromino{

171     public J() {

172         cells[0] = new Cell(0, 4, Tetris.J);

173         cells[1] = new Cell(0, 3, Tetris.J);

174         cells[2] = new Cell(0, 5, Tetris.J);

175         cells[3] = new Cell(1, 5, Tetris.J);

176         

177         states = new State[] { new State(0, 0, 0, -1, 0, 1, 1, 1),

178                 new State(0, 0, -1, 0, 1, 0, 1, -1),

179                 new State(0, 0, 0, 1, 0, -1, -1, -1),

180                 new State(0, 0, 1, 0, -1, 0, -1, 1) };

181     }

182 }

183 class L extends Tetromino{

184     public L() {

185         cells[0] = new Cell(0, 4, Tetris.L);

186         cells[1] = new Cell(0, 3, Tetris.L);

187         cells[2] = new Cell(0, 5, Tetris.L);

188         cells[3] = new Cell(1, 3, Tetris.L);

189         

190         states = new State[] { new State(0, 0, 0, 1, 0, -1, -1, 1),

191                 new State(0, 0, 1, 0, -1, 0, 1, 1),

192                 new State(0, 0, 0, -1, 0, 1, 1, -1),

193                 new State(0, 0, -1, 0, 1, 0, -1, -1) };

194     }

195 }

196 class I extends Tetromino{

197      public I() {

198             cells[0] = new Cell(0, 4, Tetris.I);

199             cells[1] = new Cell(0, 3, Tetris.I);

200             cells[2] = new Cell(0, 5, Tetris.I);

201             cells[3] = new Cell(0, 6, Tetris.I);

202             

203             states = new State[] { new State(0, 0, 0, -1, 0, 1, 0, 2),

204                     new State(0, 0, -1, 0, 1, 0, 2, 0) };

205         }

206 }
七中方块
  1 package com.manue1.tetris;

  2 import java.awt.Color;

  3 import java.awt.Font;

  4 import java.awt.Graphics;

  5 import java.awt.event.KeyAdapter;

  6 import java.awt.event.KeyEvent;

  7 import java.awt.image.BufferedImage;

  8 import java.util.Arrays;

  9 import java.util.Timer;

 10 import java.util.TimerTask;

 11 

 12 import javax.swing.JPanel;

 13 import javax.imageio.ImageIO;

 14 

 15 /**

 16  * 俄罗斯方块面板

 17  * @author Manue1

 18  * @version 1.0

 19  */

 20 public class Tetris extends JPanel {

 21 

 22 

 23     private static final long serialVersionUID = 1L;

 24     /*

 25      * 分数 墙 正在 下落的方块 下一个方块

 26      */

 27     public static final int FONT_COLOR=0x667799;

 28     public static final int FONT_SIZE=30;

 29     private int score;

 30     private int lines; // 销毁的行数

 31     private Cell[][] wall = new Cell[ROWS][COLS]; //

 32     private Tetromino tetromino; // 正在下落的四格方块

 33     private Tetromino nextOne;

 34     public static final int ROWS = 20; // 行数

 35     public static final int COLS = 10; // 列数

 36 

 37     /*

 38      * 背景图片

 39      */

 40     private static BufferedImage background;

 41     private static BufferedImage overImage;

 42     public static BufferedImage T;

 43     public static BufferedImage S;

 44     public static BufferedImage I;

 45     public static BufferedImage L;

 46     public static BufferedImage J;

 47     public static BufferedImage O;

 48     public static BufferedImage Z;

 49 

 50     /*

 51      * 静态代码块

 52      */

 53     static {

 54         try { // 从Tetris类所在的包中读取图片文件到内存对象

 55             background = ImageIO.read(Tetris.class.getResource("tetris.png"));

 56             overImage = ImageIO.read(Tetris.class.getResource("game-over.png"));

 57             T = ImageIO.read(Tetris.class.getResource("T.png"));

 58             I = ImageIO.read(Tetris.class.getResource("I.png"));

 59             S = ImageIO.read(Tetris.class.getResource("S.png"));

 60             Z = ImageIO.read(Tetris.class.getResource("Z.png"));

 61             J = ImageIO.read(Tetris.class.getResource("J.png"));

 62             L = ImageIO.read(Tetris.class.getResource("L.png"));

 63             O = ImageIO.read(Tetris.class.getResource("O.png"));

 64 

 65         } catch (Exception e) {

 66             e.printStackTrace();

 67         }

 68     }

 69 

 70     // 在Tetris类中重写 绘制方法 绘制背景图片

 71     public void paint(Graphics g) {

 72         g.drawImage(background, 0, 0, null);

 73         g.translate(15, 15); // 坐标系平移

 74         paintWall(g); // 画墙

 75         paintTetromino(g);

 76         paintnextOne(g);

 77         paintScore(g);//绘制分数

 78         if (gameOver) {

 79             g.drawImage(overImage, 0, 0, null);

 80         }

 81     }

 82 

 83     /*

 84      * 在Tetris添加启动方法action()

 85      */

 86     public void action() {

 87         wall = new Cell[ROWS][COLS];

 88         tetromino = Tetromino.randomOne();

 89         nextOne = Tetromino.randomOne();

 90          

 91         /* 处理键盘按下事件, 在按下按键时候执行下落方法

 92          * 监听键盘事件   创建监听器对象,   注册监听器

 93          */

 94         

 95         this.addKeyListener(new KeyAdapter() {

 96             public void keyPressed(KeyEvent e) {

 97                 int key = e.getKeyCode();// [c]

 98 

 99                 if (key == KeyEvent.VK_Q) {//Q表示退出

100                     System.exit(0);// 结束Java进程

101                 }

102                 if (gameOver) {

103                     if (key == KeyEvent.VK_S) {//S表示开始

104                         startAction();

105                         repaint();

106                     }

107                     return;

108                 }

109                 if (pause) {// pause = true

110                     if (key == KeyEvent.VK_C) {//C表示继续

111                         continueAction();

112                         repaint();

113                     }

114                     return;

115                 }

116                 

117                 

118                 

119                 

120                 switch (key) {

121                 case KeyEvent.VK_DOWN:

122                     //tetromino.sofeDrop();

123                     softDropAction();

124                     

125                     break;

126                 case KeyEvent.VK_RIGHT:

127                     //tetromino.moveRight();

128                     moveRightAction();

129                     break;

130                 case KeyEvent.VK_LEFT:

131                     //tetromino.moveLeft();

132                     moveLeftAction();

133                     break;

134                 case KeyEvent.VK_SPACE :

135                    

136                     hardDropAction();

137                     break;

138                 case KeyEvent.VK_UP:

139                     rotateRightAction();

140                     break;

141                 case KeyEvent.VK_P://按键盘上的P表示暂停

142                     pauseAction();

143                     break;

144                 }

145                 repaint();// 再画一次!

146             }

147         });

148         

149         this.requestFocus();  //为面板请求焦点

150     

151         this.setFocusable(true); //面板可以获得焦点

152         /*

153          * 计时器 自动下落

154          */

155         timer = new Timer();

156         timer.schedule(

157                 new TimerTask(){

158             public void run(){

159                 //tetromino.sofeDrop();

160                 softDropAction();

161                 repaint();

162             }

163         },1000,1000);

164       

165         

166     }

167 

168     public static final int CELL_SIZE = 26;

169 

170     /*

171      * 画墙

172      */

173 

174     private void paintWall(Graphics g) {

175         for (int row = 0; row < wall.length; row++) {

176             Cell[] line = wall[row];

177             // line 代表墙上的每一行

178             for (int col = 0; col < line.length; col++) {

179                 Cell cell = line[col];

180                 // cell 代表墙上的每个格子

181                 int x = col * CELL_SIZE;

182                 int y = row * CELL_SIZE;

183                 if (cell == null) {

184                     g.drawRect(x, y, CELL_SIZE, CELL_SIZE);

185 

186                 } else {

187                     g.drawImage(cell.getImage(), x - 1, y - 1, null);

188 

189                 }

190                 // g.drawString(row+","+col, x,y+CELL_SIZE);

191             }

192         }

193     }

194 

195     /*

196      * 正在下落 方块

197      */

198     public void paintTetromino(Graphics g) {

199         if (tetromino == null) {return;} // 如果是空 直接不执行了 输入数据的有效性检测

200         Cell[] cells = tetromino.cells;

201         for (int i = 0; i < cells.length; i++) {

202             Cell cell = cells[i];

203             int x = cell.getCol() * CELL_SIZE;

204             int y = cell.getRow() * CELL_SIZE;

205             g.drawImage(cell.getImage(), x, y, null);

206         }

207     }

208     /*

209      * 下一个下落的方块

210      */

211     public void paintnextOne(Graphics g) {

212         if (nextOne == null) {return;} // 如果是空 直接不执行了 输入数据的有效性检测

213         Cell[] cells = nextOne.cells;

214         for (int i = 0; i < cells.length; i++) {

215             Cell cell = cells[i];

216             int x = (cell.getCol()+10) * CELL_SIZE;

217             int y = (cell.getRow()+1) * CELL_SIZE;

218             g.drawImage(cell.getImage(), x, y, null);

219         }

220     }

221     

222     /*在Tetris类中添加方法

223      * 检测正在下路方块是否出界

224      */

225      /** 检查当前正在下落的方块是否出界了 */

226     private boolean outOfBounds() {

227         Cell[] cells = tetromino.cells;

228         for (int i = 0; i < cells.length; i++) {

229             Cell cell = cells[i];

230             int col = cell.getCol();

231             if (col < 0 || col >= COLS) {

232                 return true;

233             }

234         }

235         return false;

236     }

237     /** 检查正在下落的方块是否与墙上的砖块重叠 */

238     private boolean coincide() {

239         Cell[] cells = tetromino.cells;

240         for (int i = 0; i < cells.length; i++) {

241             Cell cell = cells[i];

242             int row = cell.getRow();

243             int col = cell.getCol();

244             // 如果墙的row,col位置上有格子,就重叠了!

245             if (row >= 0 && row < ROWS && col >= 0 && col <= COLS

246                     && wall[row][col] != null) {

247                 return true;// 重叠

248             }

249         }

250         return false;

251     }

252     /** 在Tetris 类上添加方法, 向右移动的流程控制 */

253     public void moveRightAction() {

254         // 尝试先向右移动, 如果发现超出了边界, 就

255         // 向左移动, 修正回来.

256         tetromino.moveRight();// coincide重叠

257         if (outOfBounds() || coincide()) {

258             tetromino.moveLeft();

259         }

260     }

261     public void moveLeftAction() {

262         tetromino.moveLeft();

263         if (outOfBounds() || coincide()) {

264             tetromino.moveRight();

265         }

266     }

267    

268     

269     

270     

271     

272     

273     /* 下落流程控制

274      * 

275      */

276   

277     public void softDropAction() {

278         if (canDrop()) {

279             tetromino.sofeDrop();

280         } else {

281             landIntoWall();

282             destoryLines();

283                 checkGameOverAction();

284             tetromino = nextOne;

285             nextOne = Tetromino.randomOne();

286         }

287     }

288     public void hardDropAction(){

289         while(canDrop()){

290             tetromino.sofeDrop();

291         }

292          landIntoWall();

293          destoryLines();

294              checkGameOverAction();

295          tetromino = nextOne;

296          nextOne = Tetromino.randomOne();

297         

298     }

299     

300    

301     

302     

303     private static int[] scoreTable={0,1,10,50,100};

304    

305     

306     /* 调用删除行方法。循环让上面所有的行落下来

307 

308      */

309     private void destoryLines() {

310         int lines = 0;

311         for (int row = 0; row < wall.length; row++) {

312             if (fullCells(row)) {

313                 deleteRow(row);

314                 lines++;

315             }

316         }

317         this.score += scoreTable[lines];

318         this.lines += lines;

319     }

320 

321  

322     /*

323      * 删除行

324      */

325     private void deleteRow(int row) {

326         for (int i = row; i >= 1; i--) {

327             System.arraycopy(wall[i - 1], 0, wall[i], 0, COLS);

328         }

329         Arrays.fill(wall[0], null);

330     }

331 

332     

333     /* 判断行是否被填充

334      * 

335     */

336     private boolean fullCells(int row){

337         Cell[] line =wall[row];

338          /*

339         for(Cell cell : line){

340             if(cell==null) return false;

341            }

342          */

343         for(int i=0;i<line.length;i++){

344             if(line[i]==null)return false;

345         }

346          return true;

347     }

348      

349     

350   

351     /*下落到最低行停止

352      * 

353      */

354     private void landIntoWall(){

355         Cell[] cells=tetromino.cells;

356         for(int i=0;i<cells.length;i++){

357             Cell cell = cells[i];

358             int row,col;

359             row=cell.getRow();

360             col=cell.getCol();

361             wall[row][col]=cell;

362         }

363     }

364 

365     

366     private boolean canDrop() {

367         Cell[] cells = tetromino.cells;

368         for (int i = 0; i < cells.length; i++) {

369             Cell cell = cells[i];

370             int row = cell.getRow();

371             if (row == ROWS - 1) {

372                 return false;

373             }

374         }

375         for (Cell cell : cells) {// Java 5 以后可以使用

376             int row = cell.getRow() + 1;

377             int col = cell.getCol();

378             if (row >= 0 && row < ROWS && col >= 0 && col <= COLS

379                     && wall[row][col] != null) {

380                 return false;

381             }

382         }

383         return true;

384     }

385 

386     /*绘制分数

387      * 

388      */

389     private void paintScore(Graphics g) {

390         int x = 290;

391         int y = 160;

392         g.setColor(new Color(FONT_COLOR));

393         Font font = g.getFont();// 取得g当前字体

394         font = new Font(font.getName(), font.getStyle(), FONT_SIZE);

395         g.setFont(font);// 更改了g的字体

396         String str = "SCORE:" + score;

397         g.drawString(str, x, y);

398         y += 56;

399         str = "LINES:" + lines;

400         g.drawString(str, x, y);

401         y += 56;

402         str = "[P]Pause";

403         if (pause) {

404             str = "[C]Continue";

405         }

406         if (gameOver) {

407             str = "[S]Start!";

408         }

409         g.drawString(str, x, y);

410 

411      

412     }

413 

414     

415     

416     /** 在Tetris类中添加 旋转流程控制方法 */

417     public void rotateRightAction() {

418         tetromino.rotateRight();

419         if (outOfBounds() || coincide()) {

420             tetromino.rotateLeft();

421         }

422     }

423     

424     

425     

426   /* 

427    * 流程处理

428    */

429     private Timer timer;

430     private boolean pause;//是否为暂停状态

431     private boolean gameOver;//是否为游戏结束状态

432     private long interval = 600;// 间隔时间

433     

434     

435     /** 在Tetris类中添加 开始流程控制 */

436     public void startAction() {

437         pause = false;

438         gameOver = false;

439         score = 0;

440         lines = 0;

441         clearWall();

442         tetromino = Tetromino.randomOne();

443         nextOne = Tetromino.randomOne();

444         timer = new Timer();

445         timer.schedule(new TimerTask() {

446             public void run() {

447                 softDropAction();

448                 repaint();

449             }

450         }, interval, interval);

451     }

452     /**

453      * 清除墙上的方块

454      */

455     private void clearWall() {

456         for (Cell[] line : wall) {

457             Arrays.fill(line, null);

458         }

459     }

460     /**

461      * 暂停

462      */

463     public void pauseAction() {

464         timer.cancel();

465         pause = true;

466     }

467     /**

468      * 继续

469      */

470     public void continueAction() {

471         timer = new Timer();

472         timer.schedule(new TimerTask() {

473             @Override

474             public void run() {

475                 softDropAction();

476                 repaint();

477             }

478         }, interval, interval);

479         pause = false;

480     }

481     /**

482      * 游戏结束

483      */

484     public void checkGameOverAction() {

485         if (wall[0][4] != null) {

486             timer.cancel();

487             gameOver = true;

488         }

489     }

490 }
面板操作

 

你可能感兴趣的:(开发)