您好,登錄后才能下訂單哦!
這篇文章主要介紹如何使用Java實現(xiàn)經(jīng)典游戲2048,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
1、游戲面板生成顯示
2、方塊設計
3、鍵盤監(jiān)聽,方向鍵控制數(shù)字移動
4、數(shù)字移動邏輯算法處理
5、數(shù)字累加到2048,游戲勝利
游戲開始
移動效果
public class Game2048View implements ActionListener{ Block[] blocks; //方塊 JPanel myJPanel; //主面板 JPanel jp1,jp2; //子面板 // int moveFlag; // 用于累計移動的次數(shù) boolean numFlag; // 用于判斷是否還能加入新的數(shù)字 JLabel scroeValue; //顯示分數(shù) public Game2048View(JFrame myJFrame){ blocks=new Block[16]; // moveFlag=0; numFlag=true; this.myJPanel=(JPanel)myJFrame.getContentPane();///獲取內(nèi)容面板 setJp1(); myJPanel.add(jp1,BorderLayout.NORTH); setJp2(); myJPanel.add(jp2, BorderLayout.CENTER); myJFrame.addKeyListener(new Game2048Logic(this,myJFrame,blocks,numFlag,scroeValue)); } public void addc(JPanel jp1,Component component, GridBagConstraints gbc,int gridwidth,int gridheight, int weightx,int weighty,int gridx,int gridy) { //此方法用來添加控件到容器中 gbc.gridwidth=gridwidth; //該方法是設置組件水平所占用的格子數(shù),如果為0,就說明該組件是該行的最后一個 gbc.gridheight=gridheight; //該方法是設置組件垂直所占用的格子數(shù) gbc.weightx=weightx; //該方法設置組件水平的拉伸幅度,如果為0就說明不拉伸,不為0就隨著窗口增大進行拉伸,0到1之間 gbc.weighty=weighty; //該方法設置組件垂直的拉伸幅度,如果為0就說明不拉伸,不為0就隨著窗口增大進行拉伸,0到1之間 gbc.gridx=gridx; gbc.gridy=gridy; gbc.fill=GridBagConstraints.BOTH; jp1.add(component,gbc); } public void setJp1() { GridBagLayout gbLayout=new GridBagLayout(); jp1=new JPanel(gbLayout); JPanel Jtitle=new JPanel(); JLabel title=new JLabel("2048"); title.setFont(new Font("font", Font.PLAIN, 45));//類型、風格、大小 title.setHorizontalAlignment(JLabel.LEFT);//jLabel的文本左右對齊屬性設置方法,對齊方式 Jtitle.add(title); jp1.add(Jtitle); JPanel Jscroe=new JPanel(new GridLayout(2, 1));//new GridLayout(2, 1)為網(wǎng)格布局樣式。其中的參數(shù)“2”“1”分別為網(wǎng)格的“行數(shù)”和“列數(shù)”。 JLabel scroe=new JLabel("Scroe"); scroe.setFont(new Font("font", Font.PLAIN, 16)); scroe.setHorizontalAlignment(JLabel.CENTER); scroeValue=new JLabel("0"); scroeValue.setFont(new Font("font", Font.PLAIN, 16)); scroeValue.setHorizontalAlignment(JLabel.CENTER); Jscroe.add(scroe); Jscroe.add(scroeValue); jp1.add(Jscroe); JPanel Jnoite=new JPanel(); JLabel noite=new JLabel("方向鍵移動數(shù)字累加至2048"); noite.setFont(new Font("font", Font.PLAIN, 14)); noite.setHorizontalAlignment(JLabel.LEFT); Jnoite.add(noite); jp1.add(Jnoite); JPanel JnewGame=new JPanel(); JButton newGame=new JButton("New Game"); newGame.setHorizontalAlignment(JButton.CENTER); newGame.addActionListener(this); JnewGame.add(newGame); jp1.add(JnewGame); GridBagConstraints gbc=new GridBagConstraints(); addc(jp1, Jtitle, gbc, 3, 2, 60, 60, 0, 0); addc(jp1, Jscroe, gbc, 0, 2, 40, 60, 3, 0); addc(jp1, Jnoite, gbc, 3, 1, 60, 40, 0, 2); addc(jp1, JnewGame, gbc, 0, 1, 40, 40, 3, 2); } public void setJp2() { addBlock(); initBlock(); initBlock(); } /** * 添加方塊 */ public void addBlock(){ jp2=new JPanel(); /* * setLayout是對當前組件設置為流式布局.組件在窗體中從左到右依次排列 如果排到行的末尾 換行排列 * GridLayout(int rows, int cols, int hgap, int vgap) 創(chuàng)建具有指定行數(shù)和列數(shù)的網(wǎng)格布局。 rows - 該 rows 具有表示任意行數(shù)的值 cols - 該 cols 具有表示任意列數(shù)的值 hgap - 水平間距 vgap - 垂直間距 */ jp2.setLayout(new GridLayout(4, 4, 5, 5)); for (int i = 0; i < blocks.length; i++) { blocks[i]=new Block(); blocks[i].setHorizontalAlignment(JLabel.CENTER);// 不透明的標簽 blocks[i].setOpaque(true);// 設置控件不透明 jp2.add(blocks[i]); } } /** * 初始化方塊 */ public void initBlock(){ while (numFlag) { int index=(int) (Math.random()*16); if (blocks[index].getText().trim().equals("")) { blocks[index].setValue("2"); break; } else { continue; } } } /** * 獲得第一個子面板的高度 */ public int getMyJPanelHeidth() { return jp1.getSize().height; } @Override public void actionPerformed(ActionEvent e) { // TODO 自動生成的方法存根 newGame(); } /** * 重新開始游戲 */ public void newGame() { for (int i = 0; i < blocks.length; i++) { blocks[i].setValue(""); } numFlag=true; scroeValue.setText("0"); initBlock(); initBlock(); } }
public class Game2048Logic implements KeyListener{ Block[] blocks; boolean numFlag; // 用于判斷是否還能加入新的數(shù)字 JLabel scroeValue; //顯示分數(shù) int blocksarr[]=new int[4]; //保存一行/列方塊中的數(shù)值 JFrame myJFrame; int scroe=0; Game2048View game2048View; //初始化鍵盤事件 public Game2048Logic(Game2048View game2048View, JFrame myJFrame, Block[] blocks,boolean numFlag,JLabel scroeValue) { // TODO 自動生成的構(gòu)造函數(shù)存根 this.blocks=blocks; this.numFlag=numFlag; this.scroeValue=scroeValue; this.myJFrame=myJFrame; this.game2048View=game2048View; } //初始化按鈕事件 public Game2048Logic() { // TODO 自動生成的構(gòu)造函數(shù)存根 } public boolean getnumFlag() { return numFlag; } @Override public void keyPressed(KeyEvent e) { // TODO 自動生成的方法存根 int[] blocksarr=getBlock(); switch (e.getKeyCode()) { case KeyEvent.VK_UP: colBlock("up"); hasEmptyBlock(); if (Arrays.equals(blocksarr, getBlock())) { } else { refershBlock(); } isGameFail("up"); break; case KeyEvent.VK_DOWN: colBlock("down"); hasEmptyBlock(); if (Arrays.equals(blocksarr, getBlock())) { } else { refershBlock(); } isGameFail("down"); break; case KeyEvent.VK_LEFT: rowBlock("left"); hasEmptyBlock(); if (Arrays.equals(blocksarr, getBlock())) { } else { refershBlock(); } isGameFail("left"); break; case KeyEvent.VK_RIGHT: rowBlock("right"); hasEmptyBlock(); if (Arrays.equals(blocksarr, getBlock())) { } else { refershBlock(); } isGameFail("right"); break; default: break; } scroeValue.setText(""+scroe); win(); } /** * 垂直方向方塊移動處理函數(shù) */ public void colBlock(String direction){ int tmp1=0; int tmp2=0; int index=0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (blocks[tmp1].getText().trim().equals("")) { tmp1+=4; if (tmp1>=16) { break; } else { continue; } } else { blocksarr[index]=Integer.parseInt(blocks[tmp1].getText().trim()); index+=1; tmp1+=4; if (tmp1>=16 || index>=4) { break; } else { continue; } } } switch (direction) { case "up": blocksarr=handleBlocksarr(blocksarr); break; case "down": blocksarr=reverseArr(handleBlocksarr(reverseArr(blocksarr))); break; default: break; } for (int n = 0; n < blocksarr.length; n++) { if (blocksarr[n]==0) { blocks[tmp2].setText(""); blocks[tmp2].setBackground(Color.gray); } else { blocks[tmp2].setValue(blocksarr[n]+""); } tmp2+=4; } index=0; tmp1=i+1; tmp2=i+1; //清空數(shù)組blockarr for (int n = 0; n < blocksarr.length; n++) { blocksarr[n]=0; } } } /** * 水平方向方塊移動處理函數(shù) */ public void rowBlock(String direction) { int tmp1=0; int tmp2=0; int index=0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (blocks[tmp1].getText().trim().equals("")) { tmp1+=1; if (tmp1>=16) { break; } else { continue; } } else { blocksarr[index]=Integer.parseInt(blocks[tmp1].getText().trim()); index+=1; tmp1+=1; if (tmp1>=16 || index>=4) { break; } else { continue; } } } switch (direction) { case "left": blocksarr=handleBlocksarr(blocksarr); break; case "right": blocksarr=reverseArr(handleBlocksarr(reverseArr(blocksarr))); break; default: break; } for (int n = 0; n < blocksarr.length; n++) { if (blocksarr[n]==0) { blocks[tmp2].setText(""); blocks[tmp2].setBackground(Color.gray); } else { blocks[tmp2].setValue(blocksarr[n]+""); } tmp2+=1; } index=0; //清空數(shù)組blockarr for (int n = 0; n < blocksarr.length; n++) { blocksarr[n]=0; } } } /** * 處理并返回一個數(shù)組 */ public int[] handleBlocksarr(int[] blocksarr) { int index=0; int[] result=new int[4]; for (int i = 0; i < blocksarr.length; i++) { //排序 if (blocksarr[i]!=0) { result[index]=blocksarr[i]; index++; } } if (index==0 || index==1) { for (int i = index; i < result.length; i++) { result[i]=0; } } else { for (int i = 0; i < blocksarr.length; i++) { blocksarr[i]=0; } switch (index) { case 2: if (result[0]==result[1]) { blocksarr[0]=result[0]+result[1]; scroe+=result[0]*2; } else { blocksarr=result; } break; case 3: if (result[0]==result[1]) { blocksarr[0]=result[0]+result[1]; scroe+=result[0]*2; blocksarr[1]=result[2]; } else { if (result[1]==result[2]) { blocksarr[0]=result[0]; blocksarr[1]=result[1]+result[2]; scroe+=result[1]*2; } else { blocksarr=result; } } break; case 4: if (result[0]==result[1]) { blocksarr[0]=result[0]+result[1]; scroe+=result[0]*2; if (result[2]==result[3]) { blocksarr[1]=result[2]+result[3]; scroe+=result[2]*2; } else { blocksarr[1]=result[2]; blocksarr[2]=result[3]; } } else { if (result[1]==result[2]) { blocksarr[0]=result[0]; blocksarr[1]=result[1]+result[2]; scroe+=result[1]*2; blocksarr[2]=result[3]; } else { blocksarr[0]=result[0]; blocksarr[1]=result[1]; if (result[2]==result[3]) { blocksarr[2]=result[2]+result[3]; scroe+=result[2]*2; } else { blocksarr=result; } } } break; default: break; } result=blocksarr; } return result; } /** * 反轉(zhuǎn)數(shù)組eg:45000 --> 00054 */ public int[] reverseArr(int[] arr) { int[] tmp=new int[arr.length]; int index=arr.length-1; for (int i = 0; i < arr.length; i++) { tmp[index]=arr[i]; index--; } return tmp; } /** * 刷新方塊,添加新出現(xiàn)的2或4 */ public void refershBlock(){ if (numFlag==false) { } while (numFlag) { int index=(int) (Math.random()*16); if (blocks[index].getText().trim().equals("")) { if (Math.random()<0.8) { blocks[index].setValue("2"); } else { blocks[index].setValue("4"); } break; } else { continue; } } } /** * 判斷是否有空的方塊 */ public void hasEmptyBlock() { for (int i = 0; i < blocks.length; i++) { if (blocks[i].getText().trim().equals("")) { this.numFlag=true; break; } else { this.numFlag=false; } } } /** * 判斷游戲是否失敗 */ public void isGameFail(String direction) { boolean result=true; //true代表失敗 false代表沒有失敗 int tmp=0; if (numFlag == false) { // 表示沒有空的方塊 switch (direction) { case "up": case "down": for (int i = 0; i < 4; i++) { tmp=i*4; for (int j = 0; j < 3; j++) { if (blocks[tmp].getText().trim().equals(blocks[tmp+1].getText().trim())) { result = false; //游戲未失敗 break; } else { tmp++; } } if (result==false) { break; } } break; case "left": case "right": for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { if (blocks[tmp].getText().trim().equals(blocks[tmp+4].getText().trim())) { result = false; //游戲未失敗 break; } else { tmp+=4; if (tmp>=16) { break; } else { continue; } } } tmp=i+1; if (result==false) { break; } } break; default: break; } } else { result=false; } if (result==true) { JOptionPane.showMessageDialog( null , "Game Over",null , JOptionPane.ERROR_MESSAGE) ; game2048View.newGame(); } else { } } /** * 判斷游戲是否成功,即成功累加至2048 */ public void win() { for (int i = 0; i < blocks.length; i++) { if (blocks[i].getText().trim().equals("2048")) { JOptionPane.showMessageDialog( null , "YOU ARE WIN",null , JOptionPane.ERROR_MESSAGE) ; game2048View.newGame(); break; } } } /** * 獲得全部方塊內(nèi)容,用于對比 */ public int[] getBlock() { int[] blocksarr=new int[16]; for (int i = 0; i < blocks.length; i++) { if (blocks[i].getText().trim().equals("")) { blocksarr[i]=0; } else { blocksarr[i]=Integer.parseInt(blocks[i].getText().trim()); } } return blocksarr; } @Override public void keyReleased(KeyEvent e) { // TODO 自動生成的方法存根 } @Override public void keyTyped(KeyEvent e) { // TODO 自動生成的方法存根 } }
以上是“如何使用Java實現(xiàn)經(jīng)典游戲2048”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。