java 大魚吃小魚遊戲總結

java 大魚吃小魚遊戲總結


整體思想:主界面、主角魚、被吃的魚、氣泡、聲音


程序主要有7個類組成:DrawStart、Fish、EatenFish、AirBubble、Music、GetImage、MyMouseListener


DrawStart:

主界面:簡單界面,用swing實現,只需要遊戲圖片和切換圖片;內含主方法,啓動遊戲;創建幾乎全部的屬性,最重要的是創建一

個內部類線程來實現被吃的魚

氣泡的產生

在這裏介紹一種獲得項目圖片資源的兩種方法:

一:得到窗體的工具包 Toolkit tool = Toolkit.getDefaultToolkit();(包 java.awt.Toolkit;)

  獲取圖      Image image = tool.getImage(DrawStart.class.getResource("圖片路徑"));(包 java.awt.Image;)

二:直接獲取         Image image = new ImageIcon("圖片路徑").getImage();

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;

public class DrawStart extends JFrame{
	int Gametype = 0;
	
	public Toolkit tool = Toolkit.getDefaultToolkit();//得到窗體的工具包

	Image logo = tool.getImage(DrawStart.class.getResource("logo.png"));//窗體標誌

	//創建緩衝圖片
	Image bg_img = null;
	
	//創建線程類對象
	MyThread thread = new MyThread();
	
	//創建一個集合存放多個氣泡
	ArrayList<AirBubble> air_list = new ArrayList<AirBubble>();
	
	//創建魚類對象
	private Fish fish = new Fish(this);
	
	
	//創建一個集合存放多個被吃的魚
	ArrayList<EatenFish> eatenfish_list = new ArrayList<EatenFish>();

	//創建背景類對象
	GetImage startBg = new GetImage(this);
	
	//創建一個音樂對象
	Music music = new Music();
		
	//顯示遊戲界面
	public void showFrame(){
		this.setTitle("大魚吃小魚");
		this.setSize(850,710);
		this.setResizable(false);
		setIconImage(logo);//窗體上的標誌
		
		//設置窗體可見
		this.setVisible(true);
		
		
		//添加鼠標監聽
		MyMouseListener mouse_listener = new MyMouseListener();
		this.addMouseListener(mouse_listener);
		this.addMouseMotionListener(mouse_listener);
		//添加鍵盤監聽
		addKeyListener(new KeyAdapter() {
		
			public void keyPressed(KeyEvent key) {
				if (key.getKeyCode() == 10 && Gametype == 0) {
					
					Gametype = 1;
					music.playBgMusic();
					repaint();
					
				}
				
			}

		});
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);//關閉窗體
		thread.start();
	}
	
	public void createFish(){
		//Fish fish = new Fish(370,300);
		Fish fish = new Fish(this);
	}
	//創建隨機數對象
	Random r = new Random();
	//創建被吃的魚
	public void createEatenfish() {
		if (r.nextInt(2) == 0) {
			EatenFish cr_eatenfish = new EatenFish(this, -50, r.nextInt(705),r.nextInt(2));
			eatenfish_list.add(cr_eatenfish);
		} 
		if (r.nextInt(2) == 1) {
			EatenFish cr_eatenfish = new EatenFish(this, getWidth() + 110, r.nextInt(705),r.nextInt(2));
			eatenfish_list.add(cr_eatenfish);
		}
	}
	
	//創建氣泡
	public void createAirBubble() {	
		music.playBubblesMusic();
		AirBubble ab_air = new AirBubble(this, r.nextInt(getWidth() - 40), 705);
		air_list.add(ab_air);
	}
	
	//重寫paint方法
	public void paint(Graphics p) {
		//判斷遊戲是否是開始的
		if (Gametype == 0) {
			startBg.startBackground(p);
		}
		//判斷遊戲是否是在加載中
		if (Gametype == 1) {
			startBg.loadBackground(p);
			
		for (int i = 0; i < eatenfish_list.size(); i++) {
			EatenFish eatenfish = eatenfish_list.get(i);
			// 畫被吃的魚
			eatenfish.drawEatenfish(p);
		}
			
		for (int i = 0; i < air_list.size(); i++) {
			AirBubble Dr_qipao = air_list.get(i);
			//畫氣泡
			Dr_qipao.drawAirBubble(p);
		}
			
				fish.drawFish(p);//畫主角
			
		
		}

	}

	// 創建定時器
    int time = 0;
	int eaten = 0;
	// 內部類,不停的重繪窗體圖像
	private class MyThread extends Thread {
		public void run() {
			 Fish.list.add( 1);
			 Fish.list.add( 2);
			while (true) {
				try {
					Thread.sleep(50);
					time++;
					eaten++;
					createFish();
					if (Gametype == 1 && time % 25 == 0) {
						createAirBubble();
						time = 0;
					}
					if (Gametype == 1 && eaten % 10 == 0) {
						createEatenfish();
						eaten = 0;
					}
					
					//重繪
					repaint();
				} catch (InterruptedException e) {
			
					e.printStackTrace();
				}

			}
		}

	}

	public static void main(String[] args){
		DrawStart ds = new DrawStart();
		ds.showFrame();
	}
}


AirBubble:得到氣泡的圖片並實現隨機在界面底層生成,並創建數組來實現它的產生和消失,通過線程控制

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

public class AirBubble {
	//得到窗體的工具包
	Toolkit tool = Toolkit.getDefaultToolkit();
	Image air = tool.getImage( AirBubble.class.getResource("qipao.png"));// 氣泡圖片
	Image air_1 = tool.getImage( AirBubble.class.getResource("qipao.png"));//氣泡圖片
	
	//設置氣泡的初始座標
    int air_x = 0;
    int air_y = 705;
  
    
    DrawStart StartBg = null;
    //通過構造方法傳遞窗體對象和氣泡的初始位置
    public AirBubble(DrawStart StartBg,int air_x,int air_y){
    	this.StartBg = StartBg;
    	this.air_x = air_x;
    	this.air_y = air_y;
    	
    }
	
	//畫氣泡
   public void drawAirBubble(Graphics g){
    	g.drawImage(air, air_x, air_y, StartBg);
    	
       	moveBackGround();
    }
    
   //氣泡的移動
    public void moveBackGround(){
    	air_y -=5;
    	if(air_y <=0){
    		StartBg.air_list.remove(this);
    		air_y = 705;
    	}
    }

  
}


EatenFish:得到被吃的魚的圖片,並實現隨機產生和隨機遊動的方法,也有隊列存起來,再被吃掉時可用remove方法刪除,通過線

程實現(主要是隨機數的運用)

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.Random;

public class EatenFish {
	//得到窗體的工具包
    public Toolkit tool = Toolkit.getDefaultToolkit();
    //得到被吃的小魚的圖片
    
    Random r = new Random();
    //獲取向左圖片
    Image smallFish_1 = tool.getImage(DrawStart.class.getResource("eatenfish_right/"+r.nextInt(3)+".gif"));
    //Image bigFish_1 = tool.getImage(DrawStart.class.getResource("eatenfish_right/"+2+".gif"));
    //向右遊動的初始座標
    Image smallFish_2 = tool.getImage(DrawStart.class.getResource("eatenfish_left/"+r.nextInt(3)+".gif"));
    //Image bigFish_2 = tool.getImage(DrawStart.class.getResource("eatenfish_right/"+2+".gif"));
    //向右遊動的初始座標
	int eaten_x = 0;
	int eaten_y = 0;
	
	
	//存儲判斷傳過來的數 0表示向右遊 反之向左
	int m = 0; 
	
	DrawStart StartBg =null;
	//通過構造方法傳遞窗體類和被吃魚的初始座標
	
	public EatenFish(DrawStart StartBg,int eaten_x,int eaten_y,int m){
		
		this.StartBg = StartBg;
		if(this.m == m ){
			this.eaten_x = eaten_x;
		}else{
			//向左遊的初始座標
			this.eaten_x = 1000;
			}
		this.eaten_y = eaten_y;
		
	}
	
	public EatenFish(DrawStart StartBg){
		this.StartBg = StartBg;
	}
	
	//定義定時器
	int time = 0;
	//定義存儲隨機數變量,如果隨機數等於0畫向右的魚 等於1畫向左的魚
	int oo = 0;
	
	//畫被吃的魚
	public void drawEatenfish(Graphics g){
		if(time%(StartBg.getWidth()+100)==0){
			oo = r.nextInt(5);
		}
			if(oo==0){
				g.drawImage(smallFish_1, eaten_x, eaten_y,70,60, StartBg);
				fishmove_right();
			} 
			if(oo==1){
				g.drawImage(smallFish_2, eaten_x, eaten_y, 70,60,StartBg);
				fishmove_left();
			}
			if(oo==2){
				g.drawImage(smallFish_1, eaten_x, eaten_y,70,60, StartBg);
				fishmove_lu();
			} 
			if(oo==3){
				g.drawImage(smallFish_2, eaten_x, eaten_y, 70,60,StartBg);
				fishmove_ru();
			}

		time++;
	}
	
	//畫被吃的魚的遊動 右邊
    public void fishmove_right(){
     	eaten_x +=3;
        if(eaten_x >= StartBg.getWidth()){
        	StartBg.eatenfish_list.remove(this);	
        	eaten_x = 0;        		
        	}
    	
    	}
	//畫被吃的魚的遊動 左邊
    public void fishmove_left(){
    	eaten_x -=3;
        if(eaten_x <= -50){
        	StartBg.eatenfish_list.remove(this);
        	eaten_x = 1000;        	
        	}
    	
    	}
    //畫左斜線
    public void fishmove_lu(){
    	eaten_x +=2;
    	eaten_y +=2;
    	if(eaten_x >1000&&eaten_y>750){
        	StartBg.eatenfish_list.remove(this);
        	eaten_x = 0;
        	eaten_y = 1000;
        	}
    	
    	}
    //畫右斜線
    public void fishmove_ru(){
    	eaten_x -=2;
    	eaten_y +=2;
    	if(eaten_x <= -50&&eaten_y>1000){
        	StartBg.eatenfish_list.remove(this);
        	eaten_x = 1000;
        	eaten_y = 0;
        	}
    	
    	}
    
    //返回被吃魚的矩形區域
    public Rectangle getRectangle(){
    	return new Rectangle(eaten_x, eaten_y, 60,50);
    }

	
}


Fish: 得到主角魚的圖片,並判斷魚遊動的方向,能實現變大,能實現吃掉小魚,玩家用鼠標控制的魚

主角魚和被吃的魚都會返回一個和自身位置差不多大小的矩形,只要判斷矩形相交就可以“吃魚”!

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;

public class Fish {
	int count = 0;//統計吃魚的個數
	static List<Integer> list = new ArrayList<Integer>() ;
	Rectangle  rect ;
	
	//得到窗體的工具包
	Toolkit tool = Toolkit.getDefaultToolkit();
		
	//得到主角圖片
	Image fish_right = tool.getImage(Fish.class.getResource("right.png"));
	Image fish_left = tool.getImage(Fish.class.getResource("left.png"));
	
	private DrawStart StartBg = null ;
	
	public Fish(DrawStart StartBg){
		this.StartBg=StartBg;
		
	}
	static int eat_x = 400;
	static int eat_y = 350;
		
	//創建被吃魚類對象
	EatenFish eatenfish = new EatenFish(StartBg);
		
	//畫主角魚
	public void drawFish(Graphics g) {
	    if(count<25){
	    	if(list.get(list.size()-2)<list.get(list.size()-1)){
				g.drawImage(fish_right,eat_x-40,eat_y-35,80,70,StartBg);		
	    	}else{
	    		g.drawImage(fish_left,eat_x-40,eat_y-35,80,70,StartBg);
				}
	    }else{
	    	if(list.get(list.size()-2)<list.get(list.size()-1)){
				g.drawImage(fish_right,eat_x-55,eat_y-48,110,96,StartBg);		
	    	}else{
	    		g.drawImage(fish_left,eat_x-55,eat_y-48,110,96,StartBg);
			}
	    }
		if(list.size()>4){
			list.remove(0);
			list.remove(1);
		}
		eatenFish_bye();
	}
	
	//返回主角魚的矩形區域
    public Rectangle getRectangle(){
    	if(count<25){
    		rect = new Rectangle(eat_x-35, eat_y-30, 70,60);
    	}else{
    		rect = new Rectangle(eat_x-50, eat_y-43, 100,87);
    	}
    		return rect;
	}

	//被吃魚消失
    public void eatenFish_bye(){
    	for(int i=0;i<StartBg.eatenfish_list.size();i++){
			EatenFish eatenfish = StartBg.eatenfish_list.get(i);
			//判斷兩個矩形區域是否相交
			if(getRectangle().intersects(eatenfish.getRectangle()) || eatenfish.getRectangle().intersects(getRectangle())){
				StartBg.eatenfish_list.remove(eatenfish);
				StartBg.music.playEatMusic();
				count++;
			}			
		}
    	
    }
}



Music:遊戲運行時的背景聲音、氣泡產生的聲音、吃魚時的聲音
java一種簡單的音樂播放方法:(包 java.applet.AudioClip)
AudioClip shot=Applet.newAudioClip(Music.class.getClassLoader().getResource("音樂路徑"));
缺點:只能播放wav格式的音樂

import java.applet.Applet;
import java.applet.AudioClip;

public class Music{
	private AudioClip shot,shot1,shot2,shot3;

		
	public void playBgMusic(){
		shot=Applet.newAudioClip(Music.class.getClassLoader().getResource("music/startMusic.wav"));
		shot.loop();
	}
	
	public void playBubblesMusic(){
		shot2=Applet.newAudioClip(Music.class.getClassLoader().getResource("music/bubbles.wav"));
		shot2.play();
	}
	
	public void playEatMusic(){
		shot1=Applet.newAudioClip(Music.class.getClassLoader().getResource("music/bite3.wav"));
		shot1.play();
	}
	public void playMusic(){
		shot3=Applet.newAudioClip(Music.class.getClassLoader().getResource("music/wave2.wav"));
		shot3.play();
	}
	
}
	

GetImage: 獲取遊戲背景圖片,在DrawStart中調用

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

public class GetImage {
	
	 //得到窗體的工具包
	 public Toolkit tool = Toolkit.getDefaultToolkit();
	 //得到開始界面圖片
	 Image start_1 = tool.getImage(GetImage.class.getResource("start_1.png"));
	 Image start_2 = tool.getImage(GetImage.class.getResource("start_2.png"));
	 Image main_bg_1 = tool.getImage(GetImage.class.getResource("mainbg.png"));
	    
	 DrawStart StartBg = null;
	//通過構造方法傳遞窗體對象
    public GetImage(DrawStart StartBg){
    	this.StartBg = StartBg;
    }
    
    //畫遊戲開始時的圖片
    public void startBackground(Graphics g){
    	g.drawImage(start_1, 0, 0,StartBg.getWidth(),StartBg.getHeight(), StartBg);
    }
    //畫加載時的背景
    public void loadBackground(Graphics g){
    	
    	g.drawImage(main_bg_1, 0, 0,StartBg.getWidth(),StartBg.getHeight(), StartBg);
    }

}

MyMouseListener:通過將主角魚的座標設爲靜態的,然後在鼠標移動方發上實現“畫直線”的方法就可以實現對主角魚的拖動

public class MyMouseListener implements java.awt.event.MouseListener,java.awt.event.MouseMotionListener{
	@SuppressWarnings("unused")
	private int x1,y1,x2,y2;
	
	 // 鼠標按鍵在組件上單擊(按下並釋放)時調用。 
	public void mouseClicked(java.awt.event.MouseEvent e){
		
		
	} 
	 // 鼠標進入到組件上時調用。     
 	public void mouseEntered(java.awt.event.MouseEvent e) {
		
		
	}
 	 // 鼠標離開組件時調用。     
 	public void mouseExited(java.awt.event.MouseEvent e) {
		
	}
        
	//按壓
	public void mousePressed(java.awt.event.MouseEvent e) {
		x1 = e.getX();
		y1 = e.getY();
		
	}
	// 鼠標按鈕在組件上釋放時調用。
	public void mouseReleased(java.awt.event.MouseEvent e) {
	
	}
	//鼠標按下並拖動時調用
	public void mouseDragged(java.awt.event.MouseEvent e){
			x2 = e.getX();
			y2 = e.getY();
			Fish.eat_x=x2;
			Fish.eat_y=y2;
			Fish.list.add(x2);
			x1 = x2;
			y1 = y2;
			
	}
		
		
	
	
	//鼠標光標在組件上按下並移動時調用
	public void mouseMoved(java.awt.event.MouseEvent e){


	}
	
}

遊戲相關圖片:





這個遊戲的實現最主要的是掌握多線程的思想

實現遊戲難點:氣泡、被吃的魚的隨機生成和魚的隨機遊動,這個關係到整個畫面是否有活躍

    遊戲的升級及魚的變動,改動魚之後相應的參數都要改變

    魚遊動方向的判斷,由於是用的靜態變量,所以用的是隊列存取X座標,取出來比較實現的效果不是很好


功能還在進一步實現過程中,希望能多收到點建議!






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章