Java:用Java写俄罗斯方块太好玩了
生活随笔
收集整理的這篇文章主要介紹了
Java:用Java写俄罗斯方块太好玩了
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?一、界面如下:
?二、代碼實例如下:
1. 主界面?Tetris.java
package com.hsj.tetris;import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Arrays; import java.util.Timer; import java.util.TimerTask;import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; /*** 俄羅斯方塊游戲面板**/ public class Tetris extends JPanel {/** 正在下落方塊 */private Tetromino tetromino;/** 下一個下落方塊 */private Tetromino nextOne;/** 行數 */public static final int ROWS = 20;/** 列數 */public static final int COLS = 10;/** 墻 */private Cell[][] wall = new Cell[ROWS][COLS];/** 消掉的行數 */private int lines;/** 分數 */private int score;public static final int CELL_SIZE = 26;private static Image background;//背景圖片public static Image I;public static Image J;public static Image L;public static Image S;public static Image Z;public static Image O;public static Image T;static{//加載靜態資源的,加載圖片//建議將圖片放到 Tetris.java 同包中!//從包中加載圖片對象,使用Swing API實現 // Toolkit toolkit = Toolkit.getDefaultToolkit(); // background = toolkit.getImage( // Tetris.class.getResource("tetris.png")); // T = toolkit.getImage(Tetris.class.getResource("T.png")); // S = toolkit.getImage(Tetris.class.getResource("S.png")); // Z = toolkit.getImage(Tetris.class.getResource("Z.png")); // L = toolkit.getImage(Tetris.class.getResource("L.png")); // J = toolkit.getImage(Tetris.class.getResource("J.png")); // I = toolkit.getImage(Tetris.class.getResource("I.png")); // O = toolkit.getImage(Tetris.class.getResource("O.png"));//import javax.imageio.ImageIO;try{background = ImageIO.read(Tetris.class.getResource("tetris.png"));T=ImageIO.read(Tetris.class.getResource("T.png"));I=ImageIO.read(Tetris.class.getResource("I.png"));S=ImageIO.read(Tetris.class.getResource("S.png"));Z=ImageIO.read(Tetris.class.getResource("Z.png"));L=ImageIO.read(Tetris.class.getResource("L.png"));J=ImageIO.read(Tetris.class.getResource("J.png"));O=ImageIO.read(Tetris.class.getResource("O.png"));}catch(Exception e){e.printStackTrace();}}public void action(){//tetromino = Tetromino.randomTetromino();//nextOne = Tetromino.randomTetromino();//wall[19][2] = new Cell(19,2,Tetris.T);startAction();repaint();KeyAdapter l = new KeyAdapter() {public void keyPressed(KeyEvent e) {int key = e.getKeyCode();if(key == KeyEvent.VK_Q){System.exit(0);//退出當前的Java進程}if(gameOver){if(key==KeyEvent.VK_S){startAction();}return;}//如果暫停并且按鍵是[C]就繼續動作if(pause){//pause = falseif(key==KeyEvent.VK_C){ continueAction(); }return;}//否則處理其它按鍵switch(key){case KeyEvent.VK_RIGHT: moveRightAction(); break;case KeyEvent.VK_LEFT: moveLeftAction(); break;case KeyEvent.VK_DOWN: softDropAction() ; break;case KeyEvent.VK_UP: rotateRightAction() ; break;case KeyEvent.VK_Z: rotateLeftAction() ; break;case KeyEvent.VK_SPACE: hardDropAction() ; break;case KeyEvent.VK_P: pauseAction() ; break;}repaint();}};this.requestFocus();this.addKeyListener(l);}public void paint(Graphics g){g.drawImage(background, 0, 0, null);//使用this 作為觀察者g.translate(15, 15);//平移繪圖坐標系paintTetromino(g);//繪制正在下落的方塊paintWall(g);//畫墻paintNextOne(g);paintScore(g);}public static final int FONT_COLOR = 0x667799;public static final int FONT_SIZE = 0x20;private void paintScore(Graphics g) {Font f = getFont();//獲取當前的 面板默認字體Font font = new Font(f.getName(), Font.BOLD, FONT_SIZE);int x = 290;int y = 162;g.setColor(new Color(FONT_COLOR));g.setFont(font);String str = "SCORE:"+this.score;g.drawString(str, x, y);y+=56;str = "LINES:"+this.lines;g.drawString(str, x, y);y+=56;str = "[P]Pause";if(pause){str = "[C]Continue";}if(gameOver){ str = "[S]Start!";}g.drawString(str, x, y);}private void paintNextOne(Graphics g) {Cell[] cells = nextOne.getCells();for(int i=0; i<cells.length; i++){Cell c = cells[i];int x = (c.getCol()+10) * CELL_SIZE-1;int y = (c.getRow()+1) * CELL_SIZE-1;g.drawImage(c.getImage(), x, y, null);}}private void paintTetromino(Graphics g) {Cell[] cells = tetromino.getCells();for(int i=0; i<cells.length; i++){Cell c = cells[i];int x = c.getCol() * CELL_SIZE-1;int y = c.getRow() * CELL_SIZE-1;//g.setColor(new Color(c.getColor()));//g.fillRect(x, y, CELL_SIZE, CELL_SIZE);g.drawImage(c.getImage(), x, y, null);}}//在 Tetris 類 中添加 方法 paintWallprivate void paintWall(Graphics g){for(int row=0; row<wall.length; row++){//迭代每一行, i = 0 1 2 ... 19Cell[] line = wall[row];//line.length = 10for(int col=0; col<line.length; col++){Cell cell = line[col];int x = col*CELL_SIZE;int y = row*CELL_SIZE;if(cell==null){//g.setColor(new Color(0));//畫方形//g.drawRect(x, y, CELL_SIZE, CELL_SIZE);}else{g.drawImage(cell.getImage(), x-1, y-1, null);}}}}/*** 在 Tetris(俄羅斯方塊) 類中增加方法* 這個方法的功能是:軟下落的動作 控制流程* 完成功能:如果能夠下落就下落,否則就著陸到墻上,* 而新的方塊出現并開始落下。*/public void softDropAction(){if(tetrominoCanDrop()){tetromino.softDrop();}else{tetrominoLandToWall();destroyLines();//破壞滿的行checkGameOver();tetromino = nextOne;nextOne = Tetromino.randomTetromino();}}/** 銷毀已經滿的行,并且計分* 1)迭代每一行* 2)如果(檢查)某行滿是格子了 就銷毀這行**/public void destroyLines(){int lines = 0;for(int row = 0; row<wall.length; row++){if(fullCells(row)){deleteRow(row);lines++;}}// lines = ?this.lines += lines;//0 1 2 3 4this.score += SCORE_TABLE[lines];}private static final int[] SCORE_TABLE={0,1,10,30,200};// 0 1 2 3 4public boolean fullCells(int row){Cell[] line = wall[row];for(int i=0; i<line.length; i++){if(line[i]==null){//如果有空格式就不是滿行return false;}}return true;}public void deleteRow(int row){for(int i=row; i>=1; i--){//復制 [i-1] -> [i]System.arraycopy(wall[i-1], 0, wall[i], 0, COLS);}Arrays.fill(wall[0], null);}/** 檢查當前的4格方塊能否繼續下落 */public boolean tetrominoCanDrop(){Cell[] cells = tetromino.getCells();for(int i = 0; i<cells.length; i++){Cell cell = cells[i];int row = cell.getRow(); int col = cell.getCol();if(row == ROWS-1){return false;}//到底就不能下降了}for(int i = 0; i<cells.length; i++){Cell cell = cells[i];int row = cell.getRow(); int col = cell.getCol();if(wall[row+1][col] != null){return false;//下方墻上有方塊就不能下降了}}return true;}/** 4格方塊著陸到墻上 */public void tetrominoLandToWall(){Cell[] cells = tetromino.getCells();for(int i=0; i<cells.length; i++){Cell cell = cells[i];int row = cell.getRow();int col = cell.getCol();wall[row][col] = cell;}}public void moveRightAction(){tetromino.moveRight();if(outOfBound() || coincide()){tetromino.moveLeft();}}public void moveLeftAction(){tetromino.moveLeft();if(outOfBound() || coincide()){tetromino.moveRight();}}/** ... */private boolean outOfBound(){Cell[] cells = tetromino.getCells();for(int i=0; i<cells.length; i++){Cell cell = cells[i];int col = cell.getCol();if(col<0 || col>=COLS){return true;//出界了}}return false;}private boolean coincide(){Cell[] cells = tetromino.getCells();//for each 循環、迭代,簡化了"數組迭代書寫"for(Cell cell: cells){//Java 5 以后提供增強版for循環int row = cell.getRow();int col = cell.getCol();if(row<0 || row>=ROWS || col<0 || col>=COLS ||wall[row][col]!=null){return true; //墻上有格子對象,發生重合}}return false;}/** 向右旋轉動作 */public void rotateRightAction(){//旋轉之前//System.out.println(tetromino);tetromino.rotateRight();//System.out.println(tetromino);//旋轉之后if(outOfBound() || coincide()){tetromino.rotateLeft();}}/** Tetris 類中添加的方法 */public void rotateLeftAction(){tetromino.rotateLeft();if(outOfBound() || coincide()){tetromino.rotateRight();}}public void hardDropAction(){while(tetrominoCanDrop()){tetromino.softDrop();}tetrominoLandToWall();destroyLines();checkGameOver();tetromino = nextOne;nextOne = Tetromino.randomTetromino();}private boolean pause;private boolean gameOver;private Timer timer;/** Tetris 類中添加的方法, 用于啟動游戲 */public void startAction(){clearWall();tetromino = Tetromino.randomTetromino();nextOne = Tetromino.randomTetromino();lines = 0; score = 0; pause=false; gameOver=false;timer = new Timer();timer.schedule(new TimerTask(){public void run() {softDropAction();repaint();}}, 700, 700);}private void clearWall(){//將墻的每一行的每個格子清理為nullfor(int row=0; row<ROWS; row++){Arrays.fill(wall[row], null);}}/** 在Tetris 類中添加方法 */public void pauseAction(){timer.cancel(); //停止定時器pause = true;repaint();}public void continueAction(){timer = new Timer();timer.schedule(new TimerTask() {public void run() {softDropAction();repaint();}}, 700, 700);pause = false;repaint();}/** 在 Tetris 類中添加 方法 */public void checkGameOver(){if(wall[0][4]==null){return;}gameOver = true;timer.cancel();repaint();}public static void main(String[] args) {JFrame frame = new JFrame();Tetris tetris = new Tetris();frame.add(tetris);frame.setSize(525, 550);frame.setUndecorated(false);//true去掉窗口框!frame.setTitle("俄羅斯方塊");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Location 位置 RelativeTo相對于frame.setLocationRelativeTo(null);//使當前窗口居中frame.setVisible(true);tetris.action();} }?2. Cell.java
package com.fry.tetris;import java.awt.Image;/*** 格子* 每一個小格子,就有所在的行 列 和圖片*/ public class Cell {private int row;private int col;//private int color;private Image image;//格子的貼圖public Cell() {}public Cell(int row, int col, Image image) {super();this.row = row;this.col = col;this.image = image;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public Image getImage() {return image;}public void setImage(Image image) {this.image = image;}public void moveRight(){col++;//System.out.println("Cell moveRight()" + col);}public void moveLeft(){col--;}public void moveDown(){row++;}@Overridepublic String toString() {return "["+row+","+col+"]";} }3.功能實現 Tetromino.java
package com.fry.tetris;import java.util.Arrays; import java.util.Random;/*** 4格方塊 */ public class Tetromino {protected Cell[] cells = new Cell[4];/** 保存旋轉的相對于軸位置狀態 */protected State[] states;/** 隨機生成 4格方塊, 使用簡單工廠方法模式! * randomTetromino 隨機生成一個四格方塊 * 這個方面的返回值是多態的!* */public static Tetromino randomTetromino(){Random r = new Random();int type = r.nextInt(7);switch(type){case 0: return new T();case 1: return new I();case 2: return new J();case 3: return new L();case 4: return new O();case 5: return new S();case 6: return new Z();}return null;}public Cell[] getCells() {return cells;}/** 下落 */public void softDrop(){for(int i=0; i<cells.length; i++){cells[i].moveDown();}}public void moveRight(){//System.out.println("moveRight()");for(int i=0; i<cells.length; i++){this.cells[i].moveRight();}} public void moveLeft(){for(int i=0; i<cells.length; i++){cells[i].moveLeft();}}private int index = 100000;/** 在 Tetromino 上添加方法 */public void rotateRight() {index++;//index = 10001// index % states.length = 10001 % 4 = 1State s = states[index%states.length];//s1// [0] + s1 = [1]Cell o = cells[0];//獲取當前的軸//軸與相對位置的和作為旋轉以后的格子位置cells[1].setRow(o.getRow()+s.row1);cells[1].setCol(o.getCol()+s.col1);cells[2].setRow(o.getRow()+s.row2);cells[2].setCol(o.getCol()+s.col2);cells[3].setRow(o.getRow()+s.row3);cells[3].setCol(o.getCol()+s.col3);}/** 在 Tetromino 上添加方法 */public void rotateLeft() {index--;//index = 10001// index % states.length = 10001 % 4 = 1State s = states[index%states.length];//s1// [0] + s1 = [1]Cell o = cells[0];//獲取當前的軸cells[1].setRow(o.getRow()+s.row1);cells[1].setCol(o.getCol()+s.col1);cells[2].setRow(o.getRow()+s.row2);cells[2].setCol(o.getCol()+s.col2);cells[3].setRow(o.getRow()+s.row3);cells[3].setCol(o.getCol()+s.col3);}@Overridepublic String toString() {return Arrays.toString(cells); }/** Tetromino 類中添加的 內部類 用于記錄旋轉狀態 */protected class State{int row0,col0,row1,col1,row2,col2,row3,col3;public State(int row0, int col0, int row1, int col1,int row2, int col2,int row3, int col3) {this.row0 = row0;this.col0 = col0;this.row1 = row1;this.col1 = col1;this.row2 = row2;this.col2 = col2;this.row3 = row3;this.col3 = col3;} }}//Tetromino 類的結束 class T extends Tetromino{public T() {cells[0] = new Cell(0, 4, Tetris.T);cells[1] = new Cell(0, 3, Tetris.T);cells[2] = new Cell(0, 5, Tetris.T);cells[3] = new Cell(1, 4, Tetris.T);states = new State[]{new State(0,0, 0,-1, 0,1, 1, 0),new State(0,0, -1,0, 1,0, 0,-1),new State(0,0, 0,1, 0,-1, -1,0),new State(0,0, 1,0, -1,0, 0,1)};} } class I extends Tetromino{public I() {cells[0] = new Cell(0, 4, Tetris.I);cells[1] = new Cell(0, 3, Tetris.I);cells[2] = new Cell(0, 5, Tetris.I);cells[3] = new Cell(0, 6, Tetris.I);states = new State[]{new State(0,0, 0,1, 0,-1, 0,-2),new State(0,0, -1,0, 1,0,2,0)};} } class L extends Tetromino {public L() {cells[0] = new Cell(0, 4, Tetris.L);cells[1] = new Cell(0, 3, Tetris.L);cells[2] = new Cell(0, 5, Tetris.L);cells[3] = new Cell(1, 3, Tetris.L);states = new State[]{new State(0,0, 0,-1, 0,1, 1,-1 ),new State(0,0, -1,0, 1,0, -1,-1),new State(0,0, 0,1, 0,-1, -1,1),new State(0,0, 1,0, -1,0, 1,1)}; } }class J extends Tetromino {public J() {cells[0] = new Cell(0, 4, Tetris.J);cells[1] = new Cell(0, 3, Tetris.J);cells[2] = new Cell(0, 5, Tetris.J);cells[3] = new Cell(1, 5, Tetris.J);states = new State[]{new State(0,0, 0,-1, 0,1, 1,1),new State(0,0, -1,0, 1,0, 1,-1),new State(0,0, 0,1, 0,-1, -1,-1),new State(0,0, 1,0, -1,0, -1,1 )};} }class S extends Tetromino {public S() {cells[0] = new Cell(0, 4, Tetris.S);cells[1] = new Cell(0, 5, Tetris.S);cells[2] = new Cell(1, 3, Tetris.S);cells[3] = new Cell(1, 4, Tetris.S);states = new State[]{new State(0,0, 0,1, 1,-1, 1,0 ),new State(0,0, -1,0, 1,1, 0,1 )};} }class Z extends Tetromino {public Z() {cells[0] = new Cell(1, 4, Tetris.Z);cells[1] = new Cell(0, 3, Tetris.Z);cells[2] = new Cell(0, 4, Tetris.Z);cells[3] = new Cell(1, 5, Tetris.Z);states = new State[]{new State(0,0, -1,-1, -1,0, 0,1 ),new State(0,0, -1,1, 0,1, 1,0 )};} }class O extends Tetromino {public O() {cells[0] = new Cell(0, 4, Tetris.O);cells[1] = new Cell(0, 5, Tetris.O);cells[2] = new Cell(1, 4, Tetris.O);cells[3] = new Cell(1, 5, Tetris.O);states = new State[]{new State(0,0, 0,1, 1,0, 1,1 ),new State(0,0, 0,1, 1,0, 1,1 )};} }總結
以上是生活随笔為你收集整理的Java:用Java写俄罗斯方块太好玩了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经典的死循环
- 下一篇: 破冰、融合、同心 —— 沃创云开展202