本文實例為大家分享了java實現俄羅斯方塊的具體代碼,供大家參考,具體內容如下
俄羅斯方塊設計思想
俄羅斯方塊都從小玩到大吧,什麼規則大家都知道了吧,以前感覺那玩意賊好玩,但是就是老贏不了,現在學會了自己寫一個天天練!
鍵盤操作:
左鍵:左移; 右鍵:右移;
上鍵:變換造型下鍵:加速下掉(沒毛病吧,沒有繼續整)
任意一行的方塊滿格,這一行就消除,消除一行方塊得10分,目前小主我還沒有設置關卡,各位喜歡的寶寶們可以自己設置關卡哦;
那麼那些方塊的造型到底從哪裡來的呢,那就是我們自己設計的,常見的幾種造型就是:I型,T型,L型,田字格型等等吧,自己個加唄!
那麼到底咋整的咧?其實啊就是一個4*4的數組,當然了你開心設計n*n也可以,你牛皮你說了算!
那麼下面舉了一個例子,用來告訴你們為啥你們看見的造型可以變換的原因就是這樣提前設計好,0為空,1為填充格,這樣你就可以在你的遊戲裡面凹造型了!
算了:直接放圖先看代碼運行結果吧:
喜歡嗎?喜歡就直接做吧,可能代碼寫的不夠好,請各位大神多多包涵,我回頭也會多總結,會不斷更新代碼的;
GamePanel類:遊戲界麵類,整個方塊掉落和顯示,遊戲的邏輯斯洛都在這個類裡面實現;
package tetris;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Random;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.Timer;public class GamePanel extends JPanel implements KeyListener{ private int mapRow = 21; private int mapCol = 12; private int mapGame[][] = new int[mapRow][mapCol];//開闢一個二維數組空間,用來存放我們的地圖信息private Timer timer; private int score = 0;//記錄成績Random random = new Random(); private int curShapeType = -1; private int curShapeState = -1;//設置當前的形狀類型和當前的形狀狀態private int nextShapeType = -1; private int nextShapeState = -1;//設置下一次出現的方塊組的類型和狀態private int posx = 0; private int posy = 0; private final int shapes[][][] = new int[][][]{ //T字形按逆時針的順序存儲{ {0,1,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0}, {0,1,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0}, {1,1,1,0, 0,1,0,0, 0,0,0,0, 0,0,0,0}, {0,1,0,0, 0,1,1,0, 0,1,0,0, 0,0,0,0} }, //I字形按逆時針的順序存儲{ {0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0}, {0,1,0,0, 0,1,0,0, 0,1,0,0, 0,1,0,0}, {0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0}, {0,1,0,0, 0,1,0,0, 0,1,0,0, 0,1,0,0} }, //倒Z形按逆時針的順序存儲{ {0,1,1,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}, {1,0,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0}, {0,1,1,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}, {1,0,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0} }, //Z形按逆時針的順序存儲{ {1,1,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0}, {0,1,0,0, 1,1,0,0, 1,0,0,0, 0,0,0,0}, {1,1,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0}, {0,1,0,0, 1,1,0,0, 1,0,0,0, 0,0,0,0} }, //J字形按逆時針的順序存儲{ {0,1,0,0, 0,1,0,0, 1,1,0,0, 0,0,0,0}, {1,1,1,0, 0,0,1,0, 0,0,0,0, 0,0,0,0}, {1,1,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0}, {1,0,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0} }, //L字形按逆時針的順序存儲{ {1,0,0,0, 1,0,0,0, 1,1,0,0, 0,0,0,0}, {0,0,1,0, 1,1,1,0, 0,0,0,0, 0,0,0,0}, {1,1,0,0, 0,1,0,0, 0,1,0,0, 0,0,0,0}, {1,1,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0} }, //田字形按逆時針的順序存儲{ {1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}, {1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}, {1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0}, {1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0} } }; private int rowRect = 4; private int colRect = 4;//這裡我們把存儲的圖像看成是一個4*4的二維數組,雖然在上面我們採用一維數組來存儲,但實際還是要看成二維數組來實現private int RectWidth = 10; public GamePanel()//構造函數----創建好地圖{ CreateRect(); initMap();//初始化這個地圖SetWall();//設置牆// CreateRect(); timer = new Timer(500,new TimerListener()); timer.start(); } class TimerListener implements ActionListener{ public void actionPerformed(ActionEvent e) { MoveDown(); } } public void SetWall()//第0列和第11列都是牆,第20行也是牆{ for(int i = 0; i < mapRow; i++)//先畫列{ mapGame[i][0] = 2; mapGame[i][11] = 2; } for(int j = 1; j < mapCol-1; j++)//畫最後一行{ mapGame[20][j] = 2; } } public void initMap()//初始化這個地圖,牆的ID是2,空格的ID是0,方塊的ID是1 { for(int i = 0; i < mapRow; i++) { for(int j = 0; j < mapCol; j++) { mapGame[i][j] = 0; } } } public void CreateRect()//創建方塊---如果當前的方塊類型和狀態都存在就設置下一次的,如果不存在就設置當前的並且設置下一次的狀態和類型{ if(curShapeType == -1 && curShapeState == -1)//當前的方塊狀態都為1,表示遊戲才開始{ curShapeType = random.nextInt(shapes.length); curShapeState = random.nextInt(shapes[0].length); } else { curShapeType = nextShapeType; curShapeState = nextShapeState; } nextShapeType = random.nextInt(shapes.length); nextShapeState = random.nextInt(shapes[0].length); posx = 0; posy = 1;//牆的左上角創建方塊if(GameOver(posx,posy,curShapeType,curShapeState)) { JOptionPane.showConfirmDialog(null, "遊戲結束!", "提示", JOptionPane.OK_OPTION); System.exit(0); } } public boolean GameOver(int x, int y, int ShapeType, int ShapeState)//判斷遊戲是否結束{ if(IsOrNoMove(x,y,ShapeType,ShapeState)) { return false; } return true; } public boolean IsOrNoMove(int x, int y, int ShapeType, int ShapeState)//判斷當前的這個圖形是否可以移動,這裡重點強調x,y的坐標是指4*4的二維數組(描述圖形的那個數組)的左上角目標{ for(int i = 0; i < rowRect ; i++) { for(int j = 0; j < colRect; j++) { if(shapes[ShapeType][ShapeState][i*colRect+j] == 1 && mapGame[x+i][y+j] == 1 || shapes[ShapeType][ShapeState][i*colRect+j] == 1 && mapGame[x+i][y+j] == 2) { return false; } } } return true; } public void Turn()//旋轉{ int temp = curShapeState; curShapeState = (curShapeState+1) % shapes[0].length; if(IsOrNoMove(posx,posy,curShapeType,curShapeState)) { } else { curShapeState = temp; } repaint(); } public void MoveDown()//向下移動{ if(IsOrNoMove(posx+1,posy,curShapeType,curShapeState)) { posx++; } else { AddToMap();//將此行固定在地圖中CheckLine(); CreateRect();//重新創建一個新的方塊} repaint(); } public void MoveLeft()//向左移動{ if(IsOrNoMove(posx,posy-1,curShapeType,curShapeState)) { posy--; } repaint(); } public void MoveRight()//向右移動{ if(IsOrNoMove(posx,posy+1,curShapeType,curShapeState)) { posy++; } repaint(); } public void AddToMap()//固定掉下來的這一圖像到地圖中{ for(int i = 0; i < rowRect; i++) { for(int j = 0; j < colRect; j++) { if(shapes[curShapeType][curShapeState][i*colRect+j] == 1) { mapGame[posx+i][posy+j] = shapes[curShapeType][curShapeState][i*colRect+j]; } } } } public void CheckLine()//檢查一下這些行中是否有滿行的{ int count = 0; for(int i = mapRow-2; i >= 0; i--) { count = 0; for(int j = 1; j < mapCol-1; j++) { if(mapGame[i][j] == 1) { count++; } else break; } if(count >= mapCol-2) { for(int k = i; k > 0; k--) { for(int p = 1; p < mapCol-1; p++) { mapGame[k][p] = mapGame[k-1][p]; } } score += 10; i++; } } } public void paint(Graphics g)//重新繪製窗口{ super.paint(g); for(int i = 0; i < rowRect; i++)//繪製正在下落的方塊{ for(int j = 0; j < colRect; j++) { if(shapes[curShapeType][curShapeState][i*colRect+j] == 1) { g.fillRect((posy+j+1)*RectWidth, (posx+i+1)*RectWidth, RectWidth, RectWidth); } } } for(int i = 0; i < mapRow; i++)//繪製地圖上面已經固定好的方塊信息{ for(int j = 0; j < mapCol; j++) { if(mapGame[i][j] == 2)//畫牆{ g.drawRect((j+1)*RectWidth, (i+1)*RectWidth, RectWidth, RectWidth); } if(mapGame[i][j] == 1)//畫小方格{ g.fillRect((j+1)*RectWidth, (i+1)*RectWidth, RectWidth, RectWidth); } } } g.drawString("score = "+ score, 225, 15); g.drawString("下一個方塊:", 225, 50); for(int i = 0; i < rowRect; i++) { for(int j = 0; j < colRect; j++) { if(shapes[nextShapeType][nextShapeState][i*colRect+j] == 1) { g.fillRect(225+(j*RectWidth), 100+(i*RectWidth), RectWidth, RectWidth); } } } } public void NewGame()//遊戲重新開始{ score = 0; initMap(); SetWall(); CreateRect(); repaint(); } public void StopGame()//遊戲暫停{ timer.stop(); } public void ContinueGame() { timer.start(); } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_UP://上----旋轉Turn(); break; case KeyEvent.VK_DOWN://下----向下移動MoveDown(); break; case KeyEvent.VK_LEFT://左----向左移動MoveLeft(); break; case KeyEvent.VK_RIGHT://右----向右移動MoveRight(); break; } } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub }} GameFrame類:整個遊戲的進入口,好吧,說白了就是有main()函數的類,這個類裡面實現遊戲界面的一些設計,你可以理解為一個小小小小的UI;
package tetris;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JFrame;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;public class GameFrame extends JFrame implements ActionListener{ private int widthFrame = 500; private int heightFrame = 600; private JMenu menuone = new JMenu("遊戲");//創建一個菜單private JMenuItem newGame = menuone.add("重新開始");//創建一個內置菜單選項private JMenuItem exitGame = menuone.add("遊戲退出"); private JMenuItem stopGame = menuone.add("遊戲暫停"); private JMenuItem goOnGame = menuone.add("遊戲繼續"); private JMenu menutwo = new JMenu("幫助");//創建第二個菜單private JMenuItem aboutGame = menutwo.add("關於遊戲"); GamePanel gamepanel = new GamePanel(); public GameFrame()//構造函數{ addKeyListener(gamepanel); newGame.addActionListener(this); exitGame.addActionListener(this); stopGame.addActionListener(this); goOnGame.addActionListener(this); aboutGame.addActionListener(this); this.add(gamepanel); JMenuBar menu = new JMenuBar(); menu.add(menuone); menu.add(menutwo); this.setJMenuBar(menu); this.setTitle("俄羅斯方塊"); this.setBounds(50, 10, widthFrame, heightFrame); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { if(e.getSource() == newGame)//遊戲重新開始{ gamepanel.NewGame(); } if(e.getSource() == exitGame)//遊戲退出{ System.exit(0); } if(e.getSource() == stopGame)//遊戲暫停{ gamepanel.StopGame(); } if(e.getSource() == goOnGame)//遊戲繼續{ gamepanel.ContinueGame(); } if(e.getSource() == aboutGame)//關於遊戲信息{ JOptionPane.showMessageDialog(null, "左右鍵移動,向上建旋轉", "提示", JOptionPane.OK_OPTION); } } public static void main(String[] args) { new GameFrame(); }}以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。