<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
2014年Gabriele Cirulli利用週末的時間寫2048這個遊戲的程式,僅僅只是好玩而已。他想用一種不同的視覺展現效果和更快速的動畫來創造屬於自己的遊戲版本。
遊戲是用java語言實現,採用了swing技術進行了介面化處理,設計思路用了物件導向思想。
主要需求
每次控制所有方塊向同一個方向運動,兩個相同數位的方塊撞在一起之後合併成為他們的和,每次操作之後會在空白的方格處隨機生成一個2或者4,最終得到一個“2048”的方塊就算勝利了。如果16個格子全部填滿並且相鄰的格子都不相同也就是無法移動的話,那麼遊戲就會結束。
1、遊戲面板生成顯示
2、方塊設計
3、鍵盤監聽,方向鍵控制數位行動
4、數位行動邏輯演演算法處理
5、數位累加到2048,遊戲勝利
遊戲開始
移動效果
public class Game2048View implements ActionListener{ Block[] blocks; //方塊 JPanel myJPanel; //主面板 JPanel jp1,jp2; //子面板 // int moveFlag; // 用於累計移動的次數 boolean numFlag; // 用於判斷是否還能加入新的數位 JLabel scroeValue; //顯示分數 public Game2048View(JFrame myJFrame){ blocks=new Block[16]; // moveFlag=0; numFlag=true; this.myJPanel=(JPanel)myJFrame.getContentPane();///獲取內容面板 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; //該方法是設定元件水平所佔用的格子數,如果為0,就說明該元件是該行的最後一個 gbc.gridheight=gridheight; //該方法是設定元件垂直所佔用的格子數 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)為網格佈局樣式。其中的引數「2」「1」分別為網格的「行數」和「列數」。 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("方向鍵移動數位累加至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) 建立具有指定行數和列數的網格佈局。 rows - 該 rows 具有表示任意行數的值 cols - 該 cols 具有表示任意列數的值 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; // 用於判斷是否還能加入新的數位 JLabel scroeValue; //顯示分數 int blocksarr[]=new int[4]; //儲存一行/列方塊中的數值 JFrame myJFrame; int scroe=0; Game2048View game2048View; //初始化鍵盤事件 public Game2048Logic(Game2048View game2048View, JFrame myJFrame, Block[] blocks,boolean numFlag,JLabel scroeValue) { // TODO 自動生成的建構函式存根 this.blocks=blocks; this.numFlag=numFlag; this.scroeValue=scroeValue; this.myJFrame=myJFrame; this.game2048View=game2048View; } //初始化按鈕事件 public Game2048Logic() { // TODO 自動生成的建構函式存根 } 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(); } /** * 垂直方向方塊移動處理常式 */ 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; //清空陣列blockarr for (int n = 0; n < blocksarr.length; n++) { blocksarr[n]=0; } } } /** * 水平方向方塊移動處理常式 */ 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; //清空陣列blockarr for (int n = 0; n < blocksarr.length; n++) { blocksarr[n]=0; } } } /** * 處理並返回一個陣列 */ 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; } /** * 反轉陣列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; } /** * 重新整理方塊,新增新出現的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; } } } /** * 獲得全部方塊內容,用於對比 */ 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 自動生成的方法存根 } }
通過此次的《2048遊戲》遊戲實現,讓我對swing的相關知識有了進一步的瞭解,對java這門語言也有了比以前更深刻的認識。
java的一些基本語法,比如資料型別、運運算元、程式流程控制和陣列等,理解更加透徹。java最核心的核心就是物件導向思想,對於這一個概念,終於悟到了一些。
以上就是Java實現經典遊戲2048的範例程式碼的詳細內容,更多關於Java 2048遊戲的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45