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坐标,取出来比较实现的效果不是很好


功能还在进一步实现过程中,希望能多收到点建议!






  • 15
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值