溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Java實現(xiàn)經(jīng)典游戲2048

發(fā)布時間:2022-02-15 11:15:14 來源:億速云 閱讀:157 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹如何使用Java實現(xiàn)經(jīng)典游戲2048,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

    主要設計

    1、游戲面板生成顯示

    2、方塊設計

    3、鍵盤監(jiān)聽,方向鍵控制數(shù)字移動

    4、數(shù)字移動邏輯算法處理

    5、數(shù)字累加到2048,游戲勝利

    功能截圖

    游戲開始

    如何使用Java實現(xiàn)經(jīng)典游戲2048

    移動效果

    如何使用Java實現(xiàn)經(jīng)典游戲2048

    代碼實現(xiàn)

    界面布局類

    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();
    	}
    }

    業(yè)務邏輯類

    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è)資訊頻道!

    向AI問一下細節(jié)

    免責聲明:本站發(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)容。

    AI