1. 程式人生 > >java小遊戲大魚吃小魚入門(音樂新增+魚頭轉向+背景移動+背景泡泡效果)

java小遊戲大魚吃小魚入門(音樂新增+魚頭轉向+背景移動+背景泡泡效果)

上一篇講了如何寫基礎簡易的大魚吃小魚,接下來需要一些新增使遊戲介面效果更好。

1.新增音樂: 需要新增背景音樂和吃魚的效果音效等等音樂,將播放這些音樂的方法寫在一個類中,適時呼叫會很方便,即使只想新增背景音樂也可以寫在類中,方便以後直接在類種新增其他音樂的播放。 此處舉例只加背景音樂的程式碼:

建立音樂類:

public class Music {

	java.net.URL file1 = getClass().getResource("貝多芬 - 第五號鋼琴協奏曲.wav");
    AudioClip sound1 = java.applet.Applet.newAudioClip(file1); 
	 
	 public void playBgMusic(){
		 sound1.play();
	 }
	 
}

在介面類中/或主函式種建立音樂物件並呼叫播放方法:

Music music = new Music();
music.playBgMusic();

(記得把音樂檔案放入程式碼的包中,直接賦值貼上進程式碼包即可)

2.魚頭轉向: 讓滑鼠所控制的主角魚的方向隨滑鼠移動而變,滑鼠向右移動,魚朝向右邊,滑鼠向左移動,魚朝向左邊。 首先怎樣在畫魚時產生轉向效果:不需要找ava中方法旋轉魚的圖片,只需要準備兩張不停方向的主角魚圖片來畫魚就可以了。 怎樣根據滑鼠移動判斷要用什麼圖片畫主角魚呢:需要判斷這次滑鼠移動所到的位置相比上一次是向左了還是向右了,這就需要兩個引數,一個記錄前一次的位置,一個記錄現在的位置,來進行比較。(只需要記錄x座標即可,比較的是水平方向) 此段程式碼寫在滑鼠監聽器中 將上一篇的滑鼠監聽類的程式碼稍稍修改,程式碼如下:

public class mouselisener extends MouseAdapter{

	static float x1,x2;//不斷記錄滑鼠所在的橫座標
	Graphics g;
	Frame frame;
	Fish myfish;
	ArrayList<Fish> list;
	String getstr;
	static int flag=1;//用來切換x1,x2的記錄順序

	public mouselisener(Graphics g, Frame mf, ArrayList<Fish> list) {
		this.g = g;
		this.frame = mf;
		this.list = list;
		this.myfish = list.get(0);
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mouseDragged(MouseEvent e) {
		//myfish.x = e.getX();
		//myfish.y = e.getY();
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
		if(flag==1){
			x1=e.getX();
			myfish.x=e.getX();
			myfish.y=e.getY();
		    flag=2;
		}
		else if(flag==2){
			x2=e.getX();
			myfish.x=e.getX();
			myfish.y=e.getY();
			flag=1;
			x1=x2;
		}
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseWheelMoved(MouseWheelEvent e) {
	}

	public void actionPerformed(ActionEvent e) {}

}

並在畫魚時根據以上x座標的判斷選用不同方向的圖片畫魚,將上一篇中Fish類中的draw方法修改,程式碼如下:

public  void draw(Graphics g,ArrayList<Fish> list) {
		if (this.size > 0) {
			// 不是我的魚
			if (this != list.get(0)) {
				//超出畫面就刪掉這個魚
				if(this.x+this.size>=frame.getWidth())list.remove(this);
				else if(this.y+this.size>=frame.getHeight())list.remove(this);
				else if (this.size <= 60)
				g.drawImage(fishshape1, x, y, size-10, size-10, null);
				else if (this.size > 60 && this.size <= 120)
				g.drawImage(fishshape2, x, y, size+20, size+20, null);
				else if (this.size > 120)
				g.drawImage(fishshape4, x, y, size, size, null);
				System.out.println(this.size);
			}
			//是我的魚
			else if (this == list.get(0)){
				int location=frame.getWidth()/2;
				System.out.println("MY FISH: "+mouselisener.x1+"   "+mouselisener.x2);
				if(mouselisener.x2<=location&&mouselisener.x1>=location){
					g.drawImage(myfishshape_to_right, x, y, size, size, null);
				}
				else if(mouselisener.x2>=location&&mouselisener.x1<=location){
					g.drawImage(myfishshape, x, y, size, size, null);
				}
				else if(mouselisener.x2<=location&&mouselisener.x1<=location){
					g.drawImage(myfishshape_to_right, x, y, size, size, null);
				}
				else if(mouselisener.x2>=location&&mouselisener.x1>=location){
					g.drawImage(myfishshape, x, y, size, size, null);
				}
				//g.drawImage(myfishshape, x, y, size, size, null);
			}
		} 
		else if (this.size <= 0&&this!=list.get(0))
		{
			list.remove(this);
		}
	}

別忘了在準備主角魚圖片時準備兩個反方向的圖片,可以通過線上翻轉圖片https://www.asqql.com/giffanzuan/這個網站來進行圖片翻轉。

3.背景圖片移動: 讓圖片上下方向或左右方向移動,看起來像是魚在真實的海底遊動一樣,只需要從上到下或從左到右畫背景圖片即可 將上一篇中的Threadfish類中run中畫次畫布的程式碼稍稍修改,程式碼如下:

int index=0;
g2.drawImage(fishbackground,0,0,frame.getWidth(), frame.getHeight(),0+index,0,200+index,400,null);
			index+=1;
			if(index+400>=800)index=0;

用index來記錄畫到哪裡了,一旦畫到圖片盡頭就又從頭開始,由於畫次畫布寫在run中,由執行緒控制每隔很短時間就執行一次,所以看起來背景圖片就是連續移動的了。用到方法g.drawImage方法,此方法由很多不同個數引數的用法,如前面畫魚時的使用,詳情可查詢API文件

4.新增泡泡: 泡泡和魚一樣,都可以用佇列來表現,泡泡比魚更簡單,“泡泡不吃泡泡”,只需要實現產生泡泡佇列,移動泡泡,畫出泡泡即可,模仿Fish和Fishlist類來寫Paopao和Paopaolist

public class PaoPao {

	int x,y,speedx,speedy,size;
	Framefish frame;
	
	public PaoPao(Framefish frame,int x,int y,int speedx,int speedy,int size){
		this.frame=frame;
		this.x=x;
		this.y=y;
		this.speedx=speedx;
		this.speedy=speedy;
		this.size=size;
	}
	
	public void move(ArrayList<PaoPao> paopaolist){
			y = y - speedy;
			x = x + speedx;
	}
	
	public void drawpp(Graphics g){
	  
		Toolkit tool = Toolkit.getDefaultToolkit();
		Image paopao = tool.getImage(Fish.class.getResource("fish泡泡.png"));
		if(y>=0&&y<=frame.getHeight())
		g.drawImage(paopao,x,y,size,size,null);
	}
	
}

public class PaoPaoList extends Thread{

	Random random;
	Framefish frame;
	int x,y,speedx,speedy,size;
	ArrayList<PaoPao> paopaolist;
	
	public PaoPaoList(Framefish frame,ArrayList<PaoPao> paopaolist){
		
		this.frame=frame;
		this.paopaolist=paopaolist;
		random = new Random();
	}
	
	public void run(){
		while(true){
			x=random.nextInt(frame.getWidth())+20;
			y=frame.getHeight();
			speedx=0;
			speedy=random.nextInt(30)+10;
			size=random.nextInt(70)+30;
			PaoPao paopao = new PaoPao(frame,x,y,speedx,speedy,size);
			paopaolist.add(paopao);
			
			try {
				Thread.sleep(2000);//休眠3000產生一個氣泡
			} catch (InterruptedException e) {
			}
			
		}
	}
}

並把泡泡佇列加在介面中和Threadfish的run中,實現在畫魚時,同時也實現畫泡泡,在run中新增下面程式碼即可:

for(int i=0;i<paopaolist.size();i++){
				PaoPao pp=paopaolist.get(i);
				pp.drawpp(g2);
				
				pp.move(paopaolist);
			}
			

泡泡產生的速度,和畫的速度都可以設定通過Thread.sleep(休眠時間)來控制 想要新增水母效果等等和魚,泡泡也是類似的

這樣看起來遊戲就看起來更完善了一些,如果還想要新增遊戲關卡可以看看下一篇。

如有錯誤或不完善的地方,歡迎指出