1. 程式人生 > >JAVA貪吃蛇小遊戲分論(一)

JAVA貪吃蛇小遊戲分論(一)

引言:Java貪吃蛇小遊戲是一款非常經典的小遊戲,在總論中分析了我的貪吃蛇小遊戲的執行過程,以及貪吃蛇的演算法分析等等,對於貪吃蛇的移動原理,隨機點的出現等有了一定的瞭解,那麼,分論三篇將從我寫的程式碼出發,分析貪食蛇小遊戲的具體組成原理和程式碼實現,分論一主要說明貪吃蛇小遊戲的介面設計,貪吃蛇的設計,和隨機點出現等,分論二來分析貪吃蛇移動方式的分析,分論三主要介紹貪吃蛇小遊戲輔助類,即圓角按鈕和音樂類的實現。

(一)貪吃蛇小遊戲介面分析

介面是貪吃蛇小遊戲執行的地方,是遊戲中最基礎的元素,在Java中利用swing來介面設計,有三個介面,啟動介面,執行介面,和重啟介面,利用窗體JFrame來設計介面,為了讓窗體比較好看,需要加入圖片,圖片的路徑需要放在程式可引用的地方。如下面的程式碼就是在啟動介面中加入圖片。

 //加入背景圖片
	public  void  AddPicture() {	                                           	
		ImageIcon img = new ImageIcon("F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\timg.jpg");//注意引用圖片的路徑。
        JLabel Label= new JLabel(img);
        Label.setBounds(0,0,img.getIconWidth(),img.getIconHeight());            //設定大小
        frame.getLayeredPane().add(Label,new Integer(Integer.MIN_VALUE));      //設定圖片底層和按鈕在容器中的順序   
        JPanel  jp  =(JPanel)frame.getContentPane();   
        jp.setOpaque(false);                                                   //設定透明與否
	}

然後在窗體中加入各種元件,如按鈕,文字框和標籤等,需要給按鈕加入監聽器事件,不同的按鈕有不同的作用,如進入遊戲按鈕點選以後進入執行介面,並關閉啟動介面。

	/*設定按鈕的監聽器事件
	 * 進入按鈕的監聽器事件的主要功能是當點選按鈕以後,程式關掉啟動介面,並轉入執行介面。
	 * 主要實現原理是定義一個新介面的類,作為執行介面,然後定義一個關掉啟動介面的方法,然後在監聽器事件中,
	 * 呼叫關掉介面的方法,例項化執行介面 
	 */
	@Override
	 
	public void actionPerformed(ActionEvent e) {                                  
		new  pushButtonMusic ();		 
		// TODO 自動生成的方法存根
		closeThis();		                                                       //關掉新介面的方法
	    try {	    
			new Frame2 ();                                                         //例項化執行介面
		} catch (InterruptedException e1) {
			// TODO 自動生成的 catch 塊
			e1.printStackTrace();
		}  //建立新的窗體,以達到切換窗體的效果
	}	
	 private void closeThis() {
		// TODO 自動生成的方法存根
		 frame.dispose();//關閉啟動介面的方法。
	}

開始遊戲或者暫停遊戲的用來控制貪吃蛇的具體狀態。

 //設定按鈕的監聽器事件
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自動生成的方法存根
		//按開始鍵
		if(e.getSource() == startButton) {
			new  pushButtonMusic ();
            startFlag = true;
            startButton.setEnabled(false);
            stopButton.setEnabled(true); 

將標籤,按鈕等放入窗體中,來實現程式和使用者的人機互動功能,具體的關於SWing知識在Java基礎片中說了很多,此外,在執行程式的時候,需要重新定義窗體的大小和位置, 因為不同電腦螢幕大小不同。窗體顯示的位置也一樣。

(二)貪吃蛇和隨機點分析

貪吃蛇小遊戲中最難設計的便是貪吃蛇和隨機點,那麼,如何設計貪吃蛇和隨機點呢?我們已經知道貪吃蛇是以陣列的形式來定義的,貪吃蛇包括兩個部分,設計部分和實現移動,也就是說,如何讓貪吃蛇出現在窗體中,怎麼樣實現移動。隨機點在窗體中按照隨機點座標來實現。
(1)貪吃蛇的設計
它是由什麼組成的?如何實現移動?我們可以把貪吃蛇的蛇身定義為一個數組,理解成一個集合,它有固定的起始元素,代表遊戲一開始時的蛇身。當貪吃蛇吃到點時,集合就新增一個元素,蛇的長度就加一,然後隨機點重新出現。
那麼,集合中的元素是什麼呢?要理解這個問題,首先得關注蛇身移動所處的環境。在JFrame窗體中,是由X、Y軸座標對位置進行區分。貪吃蛇的蛇身可以看做是一個一個聯絡緊密的點,在座標軸上顯示出來。每當朝某個方向移動時,蛇的座標就按照某個規律變化。例如,我們操控貪吃蛇向上移動時,蛇的全體座標的Y軸就減一;如果蛇的第一個座標與蛇身的某個座標重合,就代表貪吃蛇碰到自己;如果蛇的第一個座標碰到了邊界,蛇就撞牆。這就是貪吃蛇的本質。
我們來建立建立蛇身上每一個點的物件,蛇身就是由一個一個這樣的物件所組成的,那麼定義一個類,用來返回貪吃蛇的每個點的座標:

/*
 * 定義一個類,用來描述貪吃蛇遊戲中的蛇,蛇身上的每一個點,通過建立snakeNode的物件,指定不同的X軸和Y軸的值,就能組成一個蛇身。
 * 同時可以獲得蛇身上的x和y點座標,和顏色
 */
import java.awt.Color;
public class SnakeNode {    //定義蛇身集合中的各個元素點,x,y。以及顏色三個蛇的關鍵組成
    private int x;
    private int y;
    private Color color; 
	public int setX=20;
	public int setY=20;
	 
    public SnakeNode() {
        super();
    }
    public SnakeNode(int x, int y, Color color) {
        super();
        this.x = x;
        this.y = y;
        this.color = color;
    }
    //定義和返回x座標
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    //定義和返回y軸的座標
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    //定義和返回顏色
    public Color getColor() {
        return color;
    }
    public void setColor(Color color) {
        this.color = color;
    }
}

其次,貪吃蛇的定義,定義一個集合,來儲存蛇身上的各個點。 一個變數,用來表示隨機出現的點(貪吃蛇的目標),貪吃蛇單擊開始按鈕以後初始移動的方向,定義一個變數Length用來表示蛇的長度。

   private ArrayList<SnakeNode> snake = new ArrayList<>();//定義蛇身的陣列集合
      private int Direction;//定義蛇頭的方向
      private int Length ;//定義蛇身的長度
      private SnakeNode newNode = new SnakeNode(1,1,Color.BLACK);//定義隨機點

將貪吃蛇加入窗體中,需要定義貪吃蛇在窗體位置,這樣的話,執行程式在執行介面就會看到貪吃蛇。

         snake.add(new SnakeNode(width/2,length/2 ,Color.red));
         snake.add(new SnakeNode(width/2,length/2+1 ,Color.blue));
         snake.add(new SnakeNode(width/2,length/2+2 ,Color.green));    	 
          Direction = 1;//定義初始方向為向上
          Length = 3;//蛇身長度為3
          CreateNode1();//產生隨機點

貪吃蛇的移動需要在一個範圍內,執行介面中有按鈕等其他元件,故而將貪吃蛇的移動範圍和元件區域分開也就是貪吃蛇撞到的牆體。變數width和length。我們將蛇身的移動範圍限制在X軸上0—15,Y軸上0~25,至於變數unit,稍後再進行分析

 private final int length = 15;//定義活動範圍
 private final int width = 25;//定義活動範圍
 private final int unit = 45;//定義單位長度

上面分析了貪吃蛇從設計到實現的整個過程,總體來說,將貪吃蛇看成一個數組集合,需要定義一個類,來獲得貪吃蛇每一節身體的座標,也就是陣列的每一個數,因為貪吃蛇分為蛇頭,蛇身和蛇尾,每一個部分的設計不一樣。然後定義一些變數,用來儲存貪吃蛇的座標,初始方向和長度,然後將其加入到窗體中,這樣執行程式的時候就可以看到貪吃蛇了,此外,將執行介面劃分為兩個區域,元件區用來放各種元件,貪吃蛇執行區就是貪吃蛇執行的區域,撞到邊界即撞到牆體就會死亡。
(2)隨機點設計
createNode()是創造隨機點的方法,隨機點是定義在窗體中隨機的x和y座標決定。創造隨機點有哪些要求?首先,隨機點的範圍肯定不能超出限制,否則遊戲將無法繼續;其次,隨機點不能出現在蛇身上,也就是隨機點的座標不能和蛇身體上的任意座標相同,否則就會出現BUG。

public void CreateNode1() {                     //創造隨機點的方法                                         
    Boolean flag = true;
        while(flag) {
        newY1 = new Random().nextInt(15)+1;     //定義隨機點的縱座標
         newX1= new Random().nextInt(25)+1;   //定義隨機點的橫座標
         for(int x = 0; x < Length; x++) {   // 不能出現在蛇身上,通過迴圈判斷是否與蛇身的點重合來產生隨機點
         if(snake.get(x).getX() == newX1 && snake.get(x).getY() == newY1) {
           flag = true;
        	  break;
          }
           flag = false; 
    }
    for(int i = 0; i < Length; i++) { //隨機點不能超出面板 ,確定面板的上下左右邊界,然後判斷隨機點是否超出邊界。
          if(snake.get(i).getX()> 5&& snake.get(i).getX()<newX1  &&snake.get(i).getY() > 5
                 && snake.get(i).getY()<newY1) {    
                  flag = true;
                 break;
                 }
              flag= false;
          }
    }
                
       Color color = new Color(new Random().nextInt(255),new Random().nextInt(255),new Random().nextInt(255));
        newNode.setColor(color);
        newNode.setX(newX1);                                
        newNode.setY(newY1);                  
    }

通過上面的分析,我們已經能夠架構出貪吃蛇的基本框架,設計好介面,定義好貪吃蛇的形狀和隨機點,那麼, 如何顯示在介面上呢?swing圖形介面設計有Graphics類,可用來畫出自己想要的圖形, 定義影象類,畫出貪吃蛇移動的執行介面,如貪吃蛇的形狀,背景圖片,蛇頭蛇尾等 。描述蛇函式的主體形狀,隨機點的形狀和蛇的形狀 。

//定義影象類,畫出貪吃蛇移動的執行介面,如貪吃蛇的形狀,背景圖片,蛇頭蛇尾等      
   //描述蛇函式的主體形狀,隨機點的形狀和蛇的形狀 
   
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//加背景
        Image  im=Toolkit.getDefaultToolkit().getImage("F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\background1.jpg");//將圖片存入相應的路徑
        g.drawImage(im, 0, 0, this.getWidth(), this.getHeight(), this);
        //畫出蛇頭,貪吃蛇在上下左右移動的時候蛇頭的方向也不一樣,故監聽貪吃蛇上下左右的移動,改變蛇頭的圖形。
      		if(direction ==1||Direction==1){   //貪吃蛇向上時		      			
      			Toolkit toolup = this.getToolkit();
      	        Image headup =  toolup.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\up.png");
      	        g.drawImage(headup,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);     	        
      		}else if(direction ==-1){//貪吃蛇向下時	
     			      	
      			 Toolkit tooldown = this.getToolkit();
      	        Image headdown =  tooldown.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\down.png");
      	        g.drawImage(headdown,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);
      	        
      		}else if(direction ==2){//貪吃蛇向左時	
            	Toolkit toolleft = this.getToolkit();
      	        Image headleft =  toolleft.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\left.png");
      	        g.drawImage(headleft,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);      		
      		}else if(direction ==-2){ //貪吃蛇向右時	    			 
      			Toolkit toolright = this.getToolkit();
      	        Image headright =  toolright.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\right.png");
      	        g.drawImage(headright,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);
      	     	}      	      		
      	//畫出食物的形狀	      	 
        Toolkit tool1 = this.getToolkit();
        Image food=  tool1.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\food.png");
        g.drawImage(food,newNode.getX()*unit, newNode.getY()*unit, unit, unit,this);       
        
        Toolkit tool2 = this.getToolkit();
        Image food1=  tool2.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\food.png");
        g.drawImage(food1,newNode.getX()*unit, newNode.getY()*unit, unit, unit,this); 
                        
      //繪製指定矩形的邊框。矩形的左邊和右邊位於 x 和 x + width。頂邊和底邊位於 y 和 y + height。使用圖形上下文的當前顏色繪製該矩形。
        g.drawRect(40, 30, 1350, 810 );             
        for(int x = 1; x < Length-1; x++) {                   //利用迴圈,來繪製蛇身的形狀
            g.setColor(snake.get(x).getColor());
            g.fillOval(snake.get(x).getX()*unit, snake.get(x).getY()*unit, unit, unit);   //給蛇的每一個節點畫橢圓                  
        }                     
          for(int x = Length-1; x < Length; x++) {     // 來繪製蛇身的形狀  	       
        Toolkit toolright = this.getToolkit();
          Image headright =  toolright.getImage( "F:\\MYJAVA\\Myprogram\\Snakeexample\\src\\image\\body.png");
  	       g.drawImage(headright,snake.get(x).getX()*unit, snake.get(x).getY()*unit, unit,unit,this);//利用迴圈,來繪製蛇的形狀           
        }
   }