Java-俄羅斯方塊最新完善版
阿新 • • 發佈:2018-12-26
趨於完善版
步驟1:
package game; import java.awt.image.BufferedImage; public class Cell { private int row; private int col; private BufferedImage image; public Cell(){} public Cell(int row, int col ,BufferedImage 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 void left(){ col--; } public void down(){ row++; } public void right(){ col++; } @Override public String toString() { return "Cell [row=" + row + ", col=" + col + "]"; } public BufferedImage getImage() { return image; } public void setImage(BufferedImage image) { this.image = image; } }
步驟2:
package game; public class Tetromino { Cell[] cells = new Cell[4]; /**向左移動*/ public void moveLeft(){ for(int i=0;i<cells.length;i++){ cells[i].left(); } } /**向下移動*/ public void moveDown(){ for(int i=0;i<cells.length;i++){ cells[i].down(); } } /**向右移動*/ public void moveRight(){ for(int i=0;i<cells.length;i++){ cells[i].right(); } } /**新增一個方法,隨機產生一種子類物件*/ public static Tetromino randomOne(){ Tetromino one = null; int num = (int)(Math.random()*7); switch(num){ case 0:one = new T();break; case 1:one = new I();break; case 2:one = new O();break; case 3:one = new S();break; case 4:one = new Z();break; case 5:one = new J();break; default:one = new L(); } return one; } /**使用內部類定義7個子型別*/ static class T extends Tetromino{ public T(){ cells[0] = new Cell(0,4,TestTetromino.T); cells[1] = new Cell(0,3,TestTetromino.T); cells[2] = new Cell(0,5,TestTetromino.T); cells[3] = new Cell(1,4,TestTetromino.T); } } static class I extends Tetromino{ public I(){ cells[0] = new Cell(0,4,TestTetromino.I); cells[1] = new Cell(0,3,TestTetromino.I); cells[2] = new Cell(0,5,TestTetromino.I); cells[3] = new Cell(0,6,TestTetromino.I); } } static class O extends Tetromino{ public O(){ cells[0] = new Cell(0,4,TestTetromino.O); cells[1] = new Cell(0,3,TestTetromino.O); cells[2] = new Cell(1,3,TestTetromino.O); cells[3] = new Cell(1,4,TestTetromino.O); } } static class S extends Tetromino{ public S(){ cells[0] = new Cell(0,4,TestTetromino.S); cells[1] = new Cell(0,5,TestTetromino.S); cells[2] = new Cell(1,3,TestTetromino.S); cells[3] = new Cell(1,4,TestTetromino.S); } } static class Z extends Tetromino{ public Z(){ cells[0] = new Cell(0,4,TestTetromino.Z); cells[1] = new Cell(0,3,TestTetromino.Z); cells[2] = new Cell(1,4,TestTetromino.Z); cells[3] = new Cell(1,5,TestTetromino.Z); } } static class J extends Tetromino{ public J(){ cells[0] = new Cell(0,4,TestTetromino.J); cells[1] = new Cell(0,3,TestTetromino.J); cells[2] = new Cell(0,5,TestTetromino.J); cells[3] = new Cell(1,5,TestTetromino.J); } } static class L extends Tetromino{ public L(){ cells[0] = new Cell(0,4,TestTetromino.L); cells[1] = new Cell(0,3,TestTetromino.L); cells[2] = new Cell(0,5,TestTetromino.L); cells[3] = new Cell(1,3,TestTetromino.L); } } /** * 變形:旋轉 */ public void rotate() { int num = cells[1].getRow(); cells[1].setRow(cells[0].getRow()+cells[1].getCol()-cells[0].getCol()); cells[1].setCol(cells[0].getCol()+cells[0].getRow()-num); num = cells[2].getRow(); cells[2].setRow(cells[0].getRow()+cells[2].getCol()-cells[0].getCol()); cells[2].setCol(cells[0].getCol()+cells[0].getRow()-num); num = cells[3].getRow(); cells[3].setRow(cells[0].getRow()+cells[3].getCol()-cells[0].getCol()); cells[3].setCol(cells[0].getCol()+cells[0].getRow()-num); } /** * 碰撞 * @param cell 已堆積的方塊 * @return true / false */ public boolean hit(Cell cell) { for(int i=0;i<cells.length;i++){ if((cells[i].getCol()==cell.getCol()&& cells[i].getRow()==cell.getRow()-1)){ return true; } } return false; } /** * 底邊的碰撞 * @param cell * @return */ public boolean hitBound() { for(int i=0;i<cells.length;i++){ if(cells[i].getRow()>=19){ return true; } } return false; } public boolean hitLeft(Cell[] cs) { for(int i=0;i<cs.length;i++){ for(int j=0;j<cells.length;j++){ if(cells[j].getRow()==cs[i].getRow()&& cells[j].getCol()==cs[i].getCol()+1){ return true; } } } return false; } public boolean hitRight(Cell[] cs) { for(int i=0;i<cs.length;i++){ for(int j=0;j<cells.length;j++){ if(cells[j].getRow()==cs[i].getRow()&& cells[j].getCol()==cs[i].getCol()-1){ return true; } } } return false; } }
步驟3:
package game; import java.awt.Font; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; /**TestTetromino 是一個畫板*/ public class TestTetromino extends JPanel{ //常量 矩形的寬度,方格的寬度 public static final int CELL_SIZE = 26; //成員變數 Tetromino currentOne = Tetromino.randomOne(); Tetromino currentNext = Tetromino.randomOne(); private Cell[] cs = {}; private boolean[][] b = new boolean[20][10]; private int state; public static final int RUNNING = 0; public static final int GAMEOVER = 1; private int score=0; public static BufferedImage I; public static BufferedImage T; public static BufferedImage O; public static BufferedImage S; public static BufferedImage Z; public static BufferedImage J; public static BufferedImage L; public static BufferedImage tetris; public static BufferedImage gameover; static{ try { //read讀取硬碟上的圖片 //getResource(String path):path是圖片的相對當前包的位置 I = ImageIO.read(TestTetromino.class.getResource("I.png")); T = ImageIO.read(TestTetromino.class.getResource("T.png")); O = ImageIO.read(TestTetromino.class.getResource("O.png")); S = ImageIO.read(TestTetromino.class.getResource("S.png")); Z = ImageIO.read(TestTetromino.class.getResource("Z.png")); J = ImageIO.read(TestTetromino.class.getResource("J.png")); L = ImageIO.read(TestTetromino.class.getResource("L.png")); tetris = ImageIO.read(TestTetromino.class.getResource("tetris.png")); gameover = ImageIO.read(TestTetromino.class.getResource("gameover.png")); } catch (Exception e) { //列印棧中的資訊 e.printStackTrace(); } } /**重寫繪製功能,此功能畫板預設呼叫*/ public void paint(Graphics g){ g.drawImage(tetris,0, 0, null); //平移座標軸 g.translate(15, 15); paintScore(g); panelWall(g); paintCurrentOne(g); paintCurrentNext(g); paintCs(g); paintState(g); } private void paintState(Graphics g) { if(state==GAMEOVER){ g.drawImage(gameover, 0, 0, null); } } private void paintCurrentNext(Graphics g) { Cell[] cells = currentNext.cells; for(int i=0;i<cells.length;i++){ Cell cell = cells[i]; int col = cell.getCol(); int row = cell.getRow(); g.drawImage(cell.getImage(), col*CELL_SIZE+270, row*CELL_SIZE+25, null); } } private void paintScore(Graphics g) { Font font = new Font(Font.SANS_SERIF,Font.BOLD,20); g.setFont(font); g.drawString("SCORE:"+score, 340, 270); } private void paintCs(Graphics g) { Cell[] cells = cs; for(int i=0;i<cells.length;i++){ Cell cell = cells[i]; int col = cell.getCol(); int row = cell.getRow(); g.drawImage(cell.getImage(), col*CELL_SIZE, row*CELL_SIZE, null); } } /**繪製當前下落的四方塊*/ private void paintCurrentOne(Graphics g) { //獲取正在下落的方塊組合內的陣列物件 Cell[] cells = currentOne.cells; for(int i=0;i<cells.length;i++){ Cell cell = cells[i]; int col = cell.getCol(); int row = cell.getRow(); g.drawImage(cell.getImage(), col*CELL_SIZE, row*CELL_SIZE, null); } } /**繪製一個牆,20行,10列的表格*/ public void panelWall(Graphics g){ for(int i=0;i<20;i++){ for(int j=0;j<10;j++){ //橫座標j,縱座標i g.drawRect(j*CELL_SIZE, i*CELL_SIZE, CELL_SIZE, CELL_SIZE); } } } private Timer timer; public void action(){ /* * 定義監聽器物件,用於監聽鍵盤事件 * */ KeyListener l = new KeyAdapter(){ public void keyPressed(KeyEvent e){ int code = e.getKeyCode(); System.out.println("code:"+code); if(state==RUNNING){ switch(code){ case 37: if(!currentOne.hitLeft(cs)){ currentOne.moveLeft(); } break; case 39: if(!currentOne.hitRight(cs)){ currentOne.moveRight(); } break; case 40:currentOne.moveDown();break; case 38:currentOne.rotate(); } outOfBoundAction();//越界 } if(code==83){ cs = new Cell[]{}; b = new boolean[20][10]; score = 0; currentOne = Tetromino.randomOne(); currentNext = Tetromino.randomOne(); state=RUNNING; } //重新繪製 repaint(); } }; //面板新增鍵盤監聽事件 this.addKeyListener(l); //面板設定成螢幕焦點 this.requestFocus(); timer = new Timer(); timer.schedule(new TimerTask(){ public void run(){ if(state==RUNNING){ hitAction();//碰撞 hitBoundAction();//碰撞底邊 deleteAction();//消除 gameoverAction();//檢查遊戲是否結束 } repaint(); } },0,1); while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if(state==RUNNING){ currentOne.moveDown(); } //重寫繪製整個畫板上的內容 repaint(); } } protected void gameoverAction() { if(isGameOver()){ state = GAMEOVER; } } private boolean isGameOver() { for(int i=0;i<cs.length;i++){ if(cs[i].getRow()==0){ return true; } } return false; } protected void deleteAction() { for(int i=0;i<b.length;i++){ boolean bool = false; for(int j=0;j<b[0].length;j++){ if(!b[i][j]){ bool = true; break; } } if(!bool){ score+=15; for(int k=0;k<cs.length;k++){ if(cs[k].getRow()==i){ cs[k] = cs[cs.length-1]; cs = Arrays.copyOf(cs, cs.length-1); k--; } } for(int k=0;k<cs.length;k++){ if(cs[k].getRow()<i){ cs[k].setRow(cs[k].getRow()+1); } } } } b = new boolean[20][10]; for(int i=0;i<cs.length;i++){ b[cs[i].getRow()][cs[i].getCol()] = true; } } /** * 到底邊 */ private void hitBoundAction() { Cell[] cells = currentOne.cells; for(int i=0;i<cells.length;i++){ if(currentOne.hitBound()){ for(int j=0;j<cells.length;j++){ cs = Arrays.copyOf(cs, cs.length+1); cs[cs.length-1] = cells[j]; b[cs[cs.length-1].getRow()][cs[cs.length-1].getCol()] = true; } currentOne = currentNext; currentNext = Tetromino.randomOne(); break; } } } /** * 方塊間的碰撞 */ protected void hitAction() { for(int i=0;i<cs.length;i++){ if(currentOne.hit(cs[i])){ Cell[] cells = currentOne.cells; for(int j=0;j<cells.length;j++){ cs = Arrays.copyOf(cs, cs.length+1); cs[cs.length-1] = cells[j]; b[cs[cs.length-1].getRow()][cs[cs.length-1].getCol()] = true; } currentOne = currentNext; currentNext = Tetromino.randomOne(); break; } } } /** * 左右邊界 */ protected void outOfBoundAction() { Cell[] cells = currentOne.cells; for(int i=0;i<cells.length;i++){ if(cells[i].getCol()<0){ for(int j=0;j<cells.length;j++){ cells[j].setCol(cells[j].getCol()+1); } break; }else if(cells[i].getCol()>9){ for(int j=0;j<cells.length;j++){ cells[j].setCol(cells[j].getCol()-1); } break; } } } public static void main(String[] args) { //建立一個遊戲視窗 JFrame frame = new JFrame("俄羅斯方塊"); //設計視窗的大小 frame.setSize(540, 588); //建立一個畫板物件 TestTetromino panel = new TestTetromino(); //畫板嵌入視窗 frame.add(panel); //設定視窗居中 frame.setLocationRelativeTo(null); //設定視窗關閉 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //設定可見性 frame.setVisible(true); panel.action(); } }
用到的圖片可以自己在網上尋找*_*