Java實現(xiàn)經典游戲俄羅斯方塊(升級版)的示例代碼
前言
俄羅斯方塊是一款風靡全球,從一開始到現(xiàn)在都一直經久不衰的電腦、手機、掌上游戲機產品,是一款游戲規(guī)則簡單,但又不缺乏樂趣的簡單經典小游戲,上手容易,適用范圍廣泛,人所共知。俄羅斯方塊游戲簡單的基本規(guī)則是有小方塊組成的7種不同的規(guī)則圖形陸續(xù)從屏幕上落下,玩家操作移動使其下落拼出一條完整的橫條,隨即會消失,玩家得分,游戲等級提高,當沒有被消除的圖形堆積到屏幕頂端時,游戲結束。
俄羅斯方塊游戲最初是由俄羅斯人阿列克謝·帕基特諾夫在1984年開發(fā)的休閑小游戲,曾幾何時它創(chuàng)造了無可匹敵的商業(yè)價值,影響了一代休閑小游戲的開發(fā)與產業(yè)鏈。隨著信息時代科技時代的不斷發(fā)展和變化,計算機已經普及到每一個人的生活中,在繁忙的工作生活中,這一類休閑小游戲給人們帶來了些許的放松。
《俄羅斯方塊升級版》游戲用java語言實現(xiàn),采用了swing技術進行了界面化處理,設計思路用了面向對象思想。
主要需求
整個游戲系統(tǒng)會隨機產生7種由四個小方塊組成的不同形狀的方塊,經過旋轉后得到28種狀態(tài),如果增加游戲難度,會增加六種不同形狀的方塊形狀,同樣經過旋轉后增加24種狀態(tài)。方塊按一定的速度自由下落,玩家通過鍵盤上的上下左右按鍵控制方塊的左右移動和旋轉,將方塊落下后放在合適的位置。當方塊落下后,如果方塊落下后有一整行被方塊填滿,那么該一整行消去。當一行被消去時,玩家得分增加10分,當得分達到100分后,玩家等級增加一級,速度加快一級,難度加大。如果當方塊落下后整個游戲畫布界面被占滿,則方塊不再下落,游戲宣告失敗。游戲具體的功能需求有如下幾個:
游戲界面需求:游戲的良好的界面會讓玩家眼前一亮,更加能充分的感受到游戲帶來的娛樂性,放松性。本游戲的默認背景色是深綠色,游戲主界面畫面自定義為自己的所喜歡的圖片,并可以更改,主界面方塊默認用橘黃色,預顯方塊顏色默認為淡紫色。背景色、前景色對比鮮明,以達到讓玩家眼前一亮的感覺,并能在游戲達到高等級狀態(tài),方塊下落速度漸高的情況下使玩家能夠清楚的分辨出下落方塊的形狀,增加游戲的刺激性。
游戲形狀需求:用數組作為存儲方塊52種狀態(tài)的數據結構,即初級等級長條形、Z字形、反Z形、田字形、7字形、反7形、T字型一共7種形狀的向4個方向的旋轉變形,和中級等級的三種方塊12種不同的狀態(tài),高級等級的三種方塊12種不同的狀態(tài)。各個方塊可以實現(xiàn)按逆時針的旋轉方式旋轉,并且方塊能否旋轉需要用條件加以判斷,如果旋轉后可能發(fā)生越界,則不能旋轉,需要調整位置來保證他可以旋轉。
主要設計
以下該游戲中類的設計:
MyFrame類:繼承自JFrame類,作為游戲的主類,負責對游戲的主體全局進行控制,連接與指揮各個類的樞紐。
PreView類:繼承自JPanel類,作為操作面板類,負責安放主游戲窗口,積分板,級別控制按鈕等窗口用以控制游戲進程。
GameCanvas類:繼承自JPanel類,ChangeBlockColor線程類動態(tài)改變畫布類的方格顏色,畫布類通過檢查方格顏色來體現(xiàn)ChangeBlockColor方塊的移動情況與消去狀況。
Box類:方格類,組成方塊的基本元素,主要表達方式為顏色。
Block類:作為操控方塊的類,控制方塊的移動,下落以及變形。
游戲主界面顯示模塊:
游戲主界面采用Swing組件開發(fā),并且向其注冊監(jiān)聽器,以實現(xiàn)各種控制功能,綜合游戲窗體的設計,其上至少需要注冊三個監(jiān)聽器,分別是動作監(jiān)聽器(ActionListener)、鍵盤監(jiān)聽器(KeyListener)、選項監(jiān)聽器(ItemListener)。
根據初步設計,可以確定客戶端上所要用到的Swing組件對象有JFrame對象、JPanel對象,JLabel對象、JButton對象、JMenuBar對象、JMenu對象、JMenuItem對象、JTextField對象、JTextArea對象、JDialog對象等,至少十個Swing組件對象。
背景畫布模塊設計:該游戲的主背景畫布是一個20行、12列的二維數組,方塊顯示是由相應顏色變化來標識,主窗體用顏色填充后可形成呈現(xiàn)出來背景樣式和方塊。本游戲用繼承自JPanel的GameCanvas類控制背景畫布的顯示,用rows代表畫布的行數,cols代表畫布的列數,行數和列數決定著畫布擁有方格的數目。
預覽方塊模塊設計:方塊和數據信息是游戲中最基本的功能模塊。Box這個類方格類,是組成塊的基本元素,用自己的顏色來表示塊的外觀 ,MyTask繼承TimerTask類用來定時下落,用計數方式來實現(xiàn)速度的改變,MyListener類繼承KeyAdapter類用來實現(xiàn)按鍵監(jiān)聽,控制方塊的上下左右。定義一個4x4方陣,共16個小格。用“0”和“1”來表示每個方格是繪制新顏色還是保留底色。
方塊移動、旋轉模塊設計:方塊的翻轉與移動比較容易實現(xiàn),方塊移動只需要改變方塊的橫坐標或縱坐標,然后重新繪制方塊即可。方塊翻轉也只需要改變背景數組的值,重新繪制方即可。
本游戲方塊下落時,進行動態(tài)繪制,實現(xiàn)Cloneable接口, 以指示 Object.clone() 方法可以合法地對該類實例進行按字段復制。方塊的操作類BlockOperation繼承Thread類,重寫run()方法,以實現(xiàn)方塊的動態(tài)正確下落。當然,在線程中要判定方塊是處于moving狀態(tài)還是pausing狀態(tài)
功能截圖
游戲開始主界面:
游戲菜單:
設計方塊顏色:
代碼實現(xiàn)
MyFrame
public class MyFrame extends JFrame{ JPanel jp_pan=new JPanel(); JPanel jp_pre=new JPanel(); JPanel jp_ctrl=new JPanel(); JPanel jp_scor=new JPanel(); Zidingyi zi; JRadioButtonMenuItem jr1=new JRadioButtonMenuItem("初級",true); JRadioButtonMenuItem jr2=new JRadioButtonMenuItem("中級"); JRadioButtonMenuItem jr3=new JRadioButtonMenuItem("高級"); JLabel jt9=new JLabel("得分:0" ); static JLabel jt10=new JLabel("等級:1" ); JMenu m1=new JMenu("游戲"); JMenu m2=new JMenu("幫助"); JCheckBox jc1; JSlider jsl; // Dialog dia;//創(chuàng)建對話框 static ImageIcon background = new ImageIcon(Constant.backGround1); // 把背景圖片加到label static JLabel label = new JLabel(background); // Dialog dia=new Dialog(this, "自定義", false); int scor=0;//初始化分數為0 static int rank=0;//初始化等級為0 int highC=0; boolean upspeed=false; boolean isTime=true; boolean runstop; static boolean isRank=false; static boolean changeBack=false; public static boolean playing=false; static boolean isMusic=true; static boolean high=false; PreView pv=new PreView(); JMenuItem ji1=new JMenuItem("開局"); GameCanvas gc=new GameCanvas(20, 12);//畫出20行12列 private Block block=new Block();//當前塊 private int newspeed=1000;//默認當前等級為1 MusicPlayer mp=new MusicPlayer(); Timer time=new Timer(); MyTask mytask; int temp=1; // 游戲主構造函數 public MyFrame(String str){ super(str); this.setSize(450, 570); Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();//獲取屏幕尺寸 setLocation((scrSize.width - getSize().width) / 2, (scrSize.height - getSize().height) / 2);//設置屏幕居中 this.setLayout(null); //label的大小為jframe的大小 label.setBounds(0, 0, this.getWidth(), this.getHeight()); //把label加到jframe的最底層,比jframe上的那個panel還下面 this.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE)); //label比jframe上的那個panel還下面,那需要把那個panel設為透明的,不然就蓋住背景了 JPanel imagePanel = (JPanel) this.getContentPane(); imagePanel.setOpaque(false); addMenu(); //游戲開始按鈕 ji1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // 如果游戲已經開始,再按一次即顯示游戲結束 if (playing == true) { ji1.setText("開局"); if(isMusic==true) {mp.playStart();} gc.setGameOver(true); gc.repaint(); MyFrame.rank=11-Constant.step; MyFrame.jt10.setText("等級:"+MyFrame.rank); runstop=true; block.isAlive=false; block=new Block(); mytask.cancel(); playing = false; } else { reset(); if(isMusic==true) {mp.playStart();} MyFrame.rank=11-Constant.step; MyFrame.jt10.setText("等級:"+MyFrame.rank); ji1.setText("結束游戲"); playing = true; mytask=new MyTask(); time.schedule(mytask, 0, 100);//100毫秒執(zhí)行一次 Thread thread = new Thread(new play());// 調用開始游戲的方法 thread.start(); } }; }); this.add(gc);//添加游戲畫布 addRight();//添加右邊 this.setFocusable(true);//設置可獲得焦點 this.requestFocus();//設置焦點 this.addKeyListener(new MyListener()); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void setBackGround(){ label.setIcon(background); } /** * 定時下落,用計數方式來實現(xiàn)速度的改變 * */ private class MyTask extends TimerTask { @Override public void run() { temp++; if (temp % Constant.step == 0) { block.newL = block.x; block.newH = block.y + 1; // block.yy(); if (block.pausing == true) return; if (high == true) { block.earse(); highC++; if (highC == 4) { gc.addRow(); highC = 0; } } if (block.isMoveAble(block.newH, block.newL)) { block.earse(); block.y++; block.display(); gc.repaint(); } else { block.isAlive = false; gc.repaint(); // cancel(); } // 取消定時器任務 temp = 1; } } } private class play implements Runnable { public void run() { /* if(killThread==true) return;*/ int col = (int) (Math.random() * (gc.getCols() - 3));//隨即位置生成列 int style = Constant.STYLES[(int) (Math.random() * Block.get_addl())][(int) (Math .random() * 4)]; while (playing) { if (block != null) { //判斷當前方塊是否死亡 if (block.isAlive) { try { Thread.currentThread().sleep(100); } catch (InterruptedException ie) { ie.printStackTrace(); } continue; } } isFullLine(); // if(upspeed)//判斷是否加速,是的話則進行調用 // upLevel(); if(isGameOver()){ if(isMusic==true) {mp.playGameOver();} gc.setGameOver(true); gc.repaint(); ji1.setText("開局"); mytask.cancel(); playing=false; return; } block = new Block(style, -1, col, gc); block.jixu();//防止在暫停時候重新開始游戲,暫停字還不消失 gc.repaint();// 將創(chuàng)建出來的方塊顯示出來 block.isAlive = true; col = (int) (Math.random() * (gc.getCols() - 3));//隨即位置生成列 style = Constant.STYLES[(int) (Math.random() * Block.get_addl())][(int) (Math .random() * 4)]; pv.setStyle(style); } } /** * 增加速度 */ private void upLevel() { if(Constant.step-1<1){ return;} Constant.step=Constant.step-1; //速度增加一級 rank++; jt10.setText("等級:"+rank); upspeed=false;//將標志位至為false } /** * 判斷是否滿行,滿行則調用消行方法。 */ private void isFullLine() { // TODO Auto-generated method stub for (int i = 0; i < 20; i++) { int row = 0; boolean flag = true; for (int j = 0; j < 12; j++) { if (!gc.getBox(i, j).isColorBox()) { flag = false; break; } } if (flag == true) { row = i; gc.delete(row);//刪除行 if(isMusic==true) {mp.playEraseSound();} addScor();//增加分數 if(scor%10==0)//設置為10分增加一個等級 upspeed=true;//將速度增加標志位至為true if(upspeed==true) upLevel(); } } } /** * 得分的計算方法 */ private void addScor() { scor=scor+10; jt9.setText("得分:"+scor); } } /** * 判斷最頂層是否有被占用,游戲是否結束 */ private boolean isGameOver() { for (int i = 0; i < 12; i++) { Box box = gc.getBox(0, i); if (box.isColorBox()) return true; }return false; } private void reset() { scor=0; rank=0; jt10.setText("等級:"+rank); jt9.setText("得分:"+scor); upspeed=false; playing=true; runstop=false; // block.pausing=false; // isTime=true; // block=new Block(); // block.isAlive=false; gc.setGameOver(false); gc.repaint(); gc.reset(); } /* private class MenuKeyListener extends KeyAdapter{ public void keyPressed(KeyEvent e) { int i = e.getKeyCode(); switch (i) { case KeyEvent.VK_C: System.out.println("111");; break; case KeyEvent.VK_DOWN: block.moveDown(); break; case KeyEvent.VK_LEFT: block.moveLeft(); break; } } }*/ /** * *按鍵監(jiān)聽,上下左右。 */ private class MyListener extends KeyAdapter{ @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub int i = e.getKeyCode(); switch (i) { case KeyEvent.VK_UP: block.moveUp(); break; case KeyEvent.VK_DOWN: block.moveDown(); break; case KeyEvent.VK_LEFT: block.moveLeft(); break; case KeyEvent.VK_RIGHT: block.moveRight(); break; case KeyEvent.VK_SPACE: block.quickDown(); break; case KeyEvent.VK_P: block.pause(); break; case KeyEvent.VK_C: block.jixu(); break; } } } /** * 菜單添加方法 */ private void addMenu() { // TODO Auto-generated method stub JMenuBar jb1=new JMenuBar(); // m1.addKeyListener(new MenuKeyListener()); //監(jiān)聽Dialog對話框,如果有等級改變則改變選擇 m1.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { // TODO Auto-generated method stub int i=Block.get_addl(); if(i==7) jr1.setSelected(true); else if(i==10) jr2.setSelected(true); else jr3.setSelected(true); } }); // JMenuItem ji1=new JMenuItem("開局(O)"); jr1.addActionListener(new MenuActionListener()); jr2.addActionListener(new MenuActionListener()); jr3.addActionListener(new MenuActionListener()); ButtonGroup bg=new ButtonGroup(); bg.add(jr1); bg.add(jr2); bg.add(jr3); JMenuItem ji2=new JMenuItem("自定義"); ji2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub zi=new Zidingyi(MyFrame.this,"自定義",false,block,gc); zi.setVisible(true); if(playing==true) block.pause(); } }); JMenuItem ji3=new JMenuItem("退出"); ji3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub System.exit(1);//退出程序 } }); JMenuItem ji4=new JMenuItem("關于"); ji4.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub JDialog dl=new Version(MyFrame.this,"版本信息",false); } }); //調用顏色對話框設置方塊顏色 JMenuItem ji_color=new JMenuItem("方塊顏色"); ji_color.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub Color newFrontColor = JColorChooser.showDialog( MyFrame.this,"設置方塊顏色", gc.getBlockColor()); if (newFrontColor != null) gc.setBlockColor(newFrontColor); } } ); MyFrame.this.setJMenuBar(jb1); jb1.add(m1); jb1.add(m2); m1.add(ji1); m1.add(jr1); m1.add(jr2); m1.add(jr3); m1.add(ji2); m1.add(ji_color); m1.add(ji3); m2.add(ji4); } /** * 右界面的添加 */ private void addRight() { // TODO Auto-generated method stub // JTextField jt1=new JTextField("下一塊"); JLabel jt1=new JLabel("下一塊"); jt1.setFont(new Font("華文行楷", Font.BOLD, 18)); jt1.setOpaque(false); // jt1.setEditable(false); jp_pre.setLayout(null); jt1.setBounds(5, 0, 80, 20); jp_pre.add(jt1); pv.setBounds(10, 20, 102, 102); jp_pre.add(pv);//添加預覽窗口 jp_pre.setBounds(308, 5, 120, 125);//設置坐標 jp_pre.setOpaque(false);//設置背景為透明 MyFrame.this.add(jp_pre); // JTextField jt2=new JTextField("功能鍵盤" ); JLabel jt2=new JLabel("功能鍵盤"); jt2.setFont(new Font("華文行楷", Font.BOLD, 23)); // jt2.setEditable(false); jt2.setOpaque(false); // JTextField jt3=new JTextField("快速向下:↓" ); JLabel jt3=new JLabel("快速向下:↓"); jt3.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt3.setEditable(false); jt3.setOpaque(false); // JTextField jt4=new JTextField("旋轉:↑" ); JLabel jt4=new JLabel("旋轉:↑"); jt4.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt4.setEditable(false); jt4.setOpaque(false); // JTextField jt5=new JTextField("向左:←" ); JLabel jt5=new JLabel("向左:←"); jt5.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt5.setEditable(false); jt5.setOpaque(false); // JTextField jt6=new JTextField("向右:→" ); JLabel jt6=new JLabel("向右:→"); jt6.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt6.setEditable(false); jt6.setOpaque(false); JLabel jt11=new JLabel("一鍵下落:空格"); jt11.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt6.setEditable(false); jt6.setOpaque(false); // JTextField jt7=new JTextField("暫停:P" ); JLabel jt7=new JLabel("暫停:P"); jt7.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt7.setEditable(false); jt7.setOpaque(false); // JTextField jt8=new JTextField("繼續(xù):C" ); JLabel jt8=new JLabel("繼續(xù):C"); jt8.setFont(new Font("華文行楷", Font.BOLD, 15)); // jt8.setEditable(false); jt8.setOpaque(false); jp_ctrl.setLayout(new GridLayout(8, 1, 0, 0)); // jp_ctrl.setBorder(BorderFactory.createBevelBorder(EtchedBorder.LOWERED)); jp_ctrl.add(jt2); jp_ctrl.add(jt3); jp_ctrl.add(jt4); jp_ctrl.add(jt5); jp_ctrl.add(jt6); jp_ctrl.add(jt11); jp_ctrl.add(jt7); jp_ctrl.add(jt8); jp_ctrl.setOpaque(false); jp_ctrl.setBounds(310, 145, 120, 200); MyFrame.this.add(jp_ctrl); // jt9.setEditable(false); jt9.setOpaque(false); jt9.setForeground(Color.BLACK); // jt10.setEditable(false); jt10.setOpaque(false); jt10.setForeground(Color.BLACK); jp_scor.setLayout(new GridLayout(2, 1, 0, 20)); jp_scor.add(jt9); jt9.setFont(new Font("華文行楷", Font.BOLD, 26)); jt10.setFont(new Font("華文行楷", Font.BOLD, 26)); jp_scor.add(jt10); jt9.setBackground(Color.LIGHT_GRAY); jt10.setBackground(Color.LIGHT_GRAY); jp_scor.setOpaque(false); jp_scor.setBounds(320, 360, 100, 140); MyFrame.this.add(jp_scor); } /** * 菜單等級的監(jiān)聽 * */ private class MenuActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { //獲取JMenuItem對象 JMenuItem j=((JMenuItem)e.getSource()); if(j==jr1){ // newLevel=Constant.LEVEL_1; Block.set_addl(7); } if(j==jr2){ Block.set_addl(10); } if(j==jr3){ // high=true; Block.set_addl(13); } } } public static void main(String[] args) { new MyFrame("俄羅斯方塊"); } }
GameCanvas
public class GameCanvas extends JPanel { private Color backColor = Color.GRAY, frontColor = Color.orange; private int rows, cols, score = 0, scoreForLevelUpdate = 0; private Box[][] boxes; private int boxWidth=25, boxHeight=25; private boolean gameOver=false; public boolean pau=false; /** * 畫布類的構造函數 * @param rows int, 畫布的行數 * @param cols int, 畫布的列數 * 行數和列數決定著畫布擁有方格的數目 */ public GameCanvas(int rows, int cols) { this.rows = rows; this.cols = cols; this.setOpaque(false); boxes = new Box[rows][cols]; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boxes[i][j] = new Box(false); } } setBounds(0, 0, 300, 500);//設置相對位置坐標 setBorder(new EtchedBorder( EtchedBorder.RAISED, Color.white, new Color(148, 145, 140))); } /** * 畫布類的構造函數 * @param rows 與public GameCanvas(int rows, int cols)同 * @param cols 與public GameCanvas(int rows, int cols)同 * @param backColor Color, 背景色 * @param frontColor Color, 前景色 */ public GameCanvas(int rows, int cols, Color backColor, Color frontColor) { this(rows, cols); this.backColor = backColor; this.frontColor = frontColor; } /** * 設置游戲背景色彩 * @param backColor Color, 背景色彩 */ public void setBackgroundColor(Color backColor) { this.backColor = backColor; } /** * 取得游戲背景色彩 * @return Color, 背景色彩 */ public Color getBackgroundColor() { return backColor; } /** * 設置游戲方塊色彩 * @param frontColor Color, 方塊色彩 */ public void setBlockColor(Color frontColor) { this.frontColor = frontColor; } /** * 取得游戲方塊色彩 * @return Color, 方塊色彩 */ public Color getBlockColor() { return frontColor; } /** * 取得畫布中方格的行數 * @return int, 方格的行數 */ public int getRows() { return rows; } /** * 取得畫布中方格的列數 * @return int, 方格的列數 */ public int getCols() { return cols; } /** * 取得游戲成績 * @return int, 分數 */ public int getScore() { return score; } /** * 取得自上一次升級后的積分 * @return int, 上一次升級后的積分 */ public int getScoreForLevelUpdate() { return scoreForLevelUpdate; } /** * 得到某一行某一列的方格引用。 * @param row int, 要引用的方格所在的行 * @param col int, 要引用的方格所在的列 * @return ErsBox, 在row行col列的方格的引用 */ public Box getBox(int row, int col) { if (row < 0 || row > boxes.length - 1 || col < 0 || col > boxes[0].length - 1) return null; return boxes[row][col]; } /** * 消行 */ public void delete(int row) { //創(chuàng)建新Box存儲新狀態(tài),不能直接賦值,賦值只是指向同一個對象 for (int i = row; i > 0; i--) { for (int j = 0; j < 12; j++) boxes[i][j] = new Box(boxes[i - 1][j].isColorBox()); } repaint(); } /** * 自動上漲 */ public void addRow() { for (int i = 0; i <19 ; i++) { for (int j = 0; j < 12; j++) { boxes[i][j] = new Box(boxes[i + 1][j].isColorBox()); } } for (int i = 0; i < 12; i++) { int a = (int) (Math.random() * 2); if (a == 1) boxes[19][i] = new Box(true); else boxes[19][i] = new Box(false); } repaint(); } /** * 畫組件。 * @param g 圖形設備環(huán)境 */ public void paint(Graphics g) { super.paint(g); if (gameOver) { paintGame(g); g.setColor(Color.RED); g.setFont(new Font("黑體", Font.BOLD, 80)); // g.drawString("GAME\nOVER",10, 220); g.drawString("GAME", 50, 220); g.drawString("OVER", 50, 310); } else if(pau==true){ paintGame(g); g.setColor(Color.BLUE); g.setFont(new Font("華文行楷", Font.BOLD, 40)); // g.drawString("GAME\nOVER",10, 220); g.drawString("暫停", 100, 200); g.drawString("按C繼續(xù)!", 60, 310); }else paintGame(g); } public void paintGame(Graphics g) { g.setColor(Color.BLUE); g.draw3DRect(0, 0, 298, 498, true); g.setColor(frontColor); // int a; // int key=0x8000; // int y1=0; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { if (boxes[i][j].isColorBox() == true) { g.setColor(frontColor);// 獲取方格顏色 g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight, true);// j,i是相反過來的} } }} } /** * 設置游戲結束 */ public boolean setGameOver(boolean go){ gameOver=go; return gameOver; } /** * 重置畫布 */ public void reset() { for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) boxes[i][j].setColor(false); } repaint(); } }
總結
通過此次的《俄羅斯方塊升級版》游戲實現(xiàn),讓我對swing的相關知識有了進一步的了解,對java這門語言也有了比以前更深刻的認識。
java的一些基本語法,比如數據類型、運算符、程序流程控制和數組等,理解更加透徹。java最核心的核心就是面向對象思想,對于這一個概念,終于悟到了一些。
以上就是Java實現(xiàn)經典游戲俄羅斯方塊(升級版)的示例代碼的詳細內容,更多關于Java俄羅斯方塊的資料請關注腳本之家其它相關文章!
相關文章
Java中的線程同步與ThreadLocal無鎖化線程封閉實現(xiàn)
這篇文章主要介紹了Java中的線程同步與ThreadLocal無鎖化線程封閉實現(xiàn),Synchronized關鍵字與ThreadLocal變量的使用是Java中線程控制的基礎,需要的朋友可以參考下2016-03-03Java中==符號與equals()的使用詳解(測試兩個變量是否相等)
下面小編就為大家?guī)硪黄狫ava中==符號與equals()的使用詳解(測試兩個變量是否相等)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解
這篇文章主要給大家介紹了關于spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 聲明的相關資料,需要的朋友可以參考下2020-08-08使用JMX監(jiān)控Zookeeper狀態(tài)Java API
今天小編就為大家分享一篇關于使用JMX監(jiān)控Zookeeper狀態(tài)Java API,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03