Java-实现飞机躲子弹游戏

cn.bjst.plane

Bullet.java

Bullet类设置子弹的坐标,速度,角度,宽度和高度

package cn.bjst.plane;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import cn.bjst.util.Constant;

public class Bullet extends GameObject{

    int speed=5;
    double degree;

    
    public Bullet() {
    	degree= Math.random()*Math.PI*2;
    	x=Constant.GAME_WIDTH/2;
    	y=Constant.GAME_HEIGHT/2;
        width=10;
        height=10;
    
    }
    

    public void draw(Graphics g) {
    	Color c=g.getColor();
        g.setColor(Color.yellow);
        g.fillOval((int)x,(int) y, width, height);
        g.setColor(c);
        
        x +=speed*Math.cos(degree);
        y +=speed*Math.sin(degree);
        
        if(y>Constant.GAME_HEIGHT-height||y<30) {//反弹的计算
        	degree = -degree;
        }
        
        if(x<0||x>Constant.GAME_WIDTH-width) {   //反弹的计算
        	degree =Math.PI-degree;
        }
    }
	
	
}

 

Explode.java

Explode爆炸效果类:快速读取图片轮播形成动态的爆炸效果。

package cn.bjst.plane;

import java.awt.Graphics;
import java.awt.Image;
import cn.bjst.util.GameUtil;
/*
 * 
 * 爆炸类
 */
public class Explode {
	double x,y;
	static Image[] imgs=new Image[16];
	int count;

	static {
		for(int i=0;i<16;i++) {
			imgs[i] =GameUtil.getImage("images/explode/e"+(i+1)+".gif");
		    imgs[i].getWidth(null);
		}
		
	}
	public void draw(Graphics g) {
		if(count<=15) {
		g.drawImage(imgs[count], (int)x, (int)y, null);
		count++;
		}
	}
	public Explode(double x,double y){
		this.x=x;
		this.y=y;
		
	}
}

GameObject.java

package cn.bjst.plane;

import java.awt.Image;
import java.awt.Rectangle;

public class GameObject {
	Image img;
	double x,y;
	int speed =10;
	
	
	int width,height;
	
	
	public Rectangle getRect() {
		
		return new Rectangle((int)x,(int)y,width,height);
	}


	public GameObject(Image img, double x, double y, int speed, int width, int height) {
		super();
		this.img = img;
		this.x = x;
		this.y = y;
		this.speed = speed;
		this.width = width;
		this.height = height;
	}
	
	public GameObject() {
		
	}
}

Plane.java

Plane类:设置飞机的图片,坐标,移动方向,移动速度,是否存活。

package cn.bjst.plane;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import cn.bjst.util.GameUtil;
import cn.bjst.util.GameUtil1;

public class Plane extends GameObject{
	
	private boolean left,up,right,down;
	boolean live =true;
	
	public void draw(Graphics g) {
		if(live) {
		g.drawImage(img,(int)x, (int)y,null);
		move();
		}
	}
	
	
	public void move() {
	if(left) {
		x -=speed;
	}
	if(right) {
		x +=speed;
	}
	if(up) {
		y -=speed;
	}
	if(down) {
		y +=speed;
	}
		
	}
	
	public void addDirection(KeyEvent e) { 
		switch (e.getKeyCode()) {
	case KeyEvent.VK_LEFT:	
		left=true;
		break;
	case KeyEvent.VK_RIGHT:	
		right=true;
		break;
	case KeyEvent.VK_UP:
		up=true;
		break;
	case KeyEvent.VK_DOWN:
		down=true;
		break;
	default:
		break;
	}
		}
	
	public void minusDirection(KeyEvent e) { 
		switch (e.getKeyCode()) {
	case KeyEvent.VK_LEFT:	
		left=false;
		break;
	case KeyEvent.VK_RIGHT:	
		right=false;
		break;
	case KeyEvent.VK_UP:
		up=false;
		break;
	case KeyEvent.VK_DOWN:
		down=false;
		break;
	default:
		break;
	}
		}
	
	
	public Plane(String imgpath,double x,double y)  {
		this.img= GameUtil.getImage(imgpath);
		this.width = img.getWidth(null);   
	    this.height = img.getHeight(null); 
		this.x=x;
		this.y=y;
		
	}
	
	public Plane() {
	
	}


	public boolean isLive() {
		return live;
	}


	public void setLive(boolean live) {
		this.live = live;
	}
	
	


	
	
}

PlaneGameFrame.java

于该类运行程序

package cn.bjst.plane;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.lang.invoke.SwitchPoint;
import java.util.ArrayList;
import java.util.Date;
import cn.bjst.util.Constant;
import cn.bjst.util.GameUtil;
import cn.bjst.util.MyFrame;

public class PlaneGameFrame extends MyFrame{

   Image bg=GameUtil.getImage("images/bg.jpg");   
   Plane p =new Plane("images/plane.png",50,50);
  
   ArrayList bulletList = new ArrayList();//泛型暂时未学,学后强烈建议加上
     
   Explode bao ;
   Date startTime;
   Date endTime;
   
   public void paint(Graphics g) {
	   g.drawImage(bg, 0, 0, null);
	   p.draw(g);
	   
	   for(int i=0;i<bulletList.size();i++) {
		   Bullet b =(Bullet)bulletList.get(i);
		   b.draw(g);
		   
		   //检测跟飞机的碰撞
		   boolean peng =b.getRect().intersects(p.getRect());
		   
		   
		   if(peng) {
			   p.setLive(false);
			   
			   if(bao==null) {
			   endTime =new Date();
			   bao=new Explode(p.x,p.y);
			   }
			   bao.draw(g);
			   break;
			   
		   }
	   }
	   
	   if(!p.isLive()) {
		   printInfo(g,"Game Over",50,100,200,Color.WHITE);
		   int period =(int )(endTime.getTime()-startTime.getTime())/1000;
		   printInfo(g, "时间:"+period+"秒", 20, 120,260, Color.yellow);
	   switch (period/10) {
	    case 0:
	    	   printInfo(g, "等级-兵", 30, 110,230, Color.WHITE);
		break;
	    case 1:
	    	   printInfo(g, "等级-排", 30, 110,230, Color.GREEN);
		break;
	    case 2:
	    	   printInfo(g, "等级-连", 30, 110,230, Color.BLUE);
		break;
	    case 3:
	    	   printInfo(g, "等级-营", 30, 110,230, Color.PINK);
		break;

	    default:
		break;
	}
	   }
	  
   }
   
   
   /**
             在窗口上打印信息
    */
   
   
   public void printInfo(Graphics g,String str,int size,int x,int y,Color color) {
	   Color c =g.getColor();
	   g.setColor(color);
	   Font   f =new Font("宋体",Font.BOLD,size);
	   g.setFont(f);
	   g.drawString(str,x,y);   
	   g.setColor(c);
	   
   }
   
   
   private Image offScreenImage =null;//利用双缓冲技术消除闪烁
   
   public void update(Graphics g) {
	   if(offScreenImage == null)
		   offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);
	   
	   Graphics gOff =offScreenImage.getGraphics();
	   
	   paint(gOff);
	   g.drawImage(offScreenImage, 0, 0, null);
   }
   
     
   
   public static void main(String[] args) {
	   new PlaneGameFrame().launchFrame();
   }
   
   
   
   public void launchFrame() {
	   super.launchFrame();
	   //增加键盘的监听
	   addKeyListener(new KeyMonitor());
	   
	   //生成一堆子弹
	   for(int i=0;i<3;i++) {
		   Bullet b=new Bullet();
		   bulletList.add(b);
		   
	   }
	   startTime = new Date();
   }
   
    
   //定义内部类,可以方便的使用外部类的普通属性
   class KeyMonitor extends KeyAdapter{

	@Override
	public void keyPressed(KeyEvent e) {
      System.out.println("按下"+e.getKeyCode());
      p.addDirection(e);
      
	}

	@Override
	public void keyReleased(KeyEvent e) {
		 System.out.println("释放"+e.getKeyCode());
		 p.minusDirection(e);
	}
	   
   }
   
}

cn.bjst.util

定义工具类在cn.bjst.util包下面

1.Constant 用来存放常量的类 :窗体的宽度、高度、坐标x,y。

2.GameUtil是一个通用的读取图片的类,它的构造器私有化,即不能被实例化,但是提供了一个静态方法。
3.本文中原GameUtil1代码有问题已更改使用GameUtil,有兴趣的小伙伴可以尝试一下原GameUtil1感受一下问题所在,下面有解析。

Constant.java

package cn.bjst.util;

public class Constant {
       public static final int GAME_WIDTH = 500;
       public static final int GAME_HEIGHT = 900;
}

GameUtil.java

package cn.bjst.util;
 
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
 
public class GameUtil {
    // 工具类最好将构造器私有化。
    private GameUtil() {
    } 
 
    
    /**
     * 返回指定路径文件的图片对象
     * @param path
     * @return
     */
    public static Image getImage(String path) {
        BufferedImage bi = null;
        try {
            URL u = GameUtil.class.getClassLoader().getResource(path);
            bi = ImageIO.read(u);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bi;
    }
}

GameUtil1.java

package cn.bjst.util;

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

public class GameUtil1{
	
	private GameUtil1(){}
	
	public static Image getImage(String path) {
	return Toolkit.getDefaultToolkit().getImage(GameUtil1.class.getClassLoader().getResource(path));}
 }

MyFrame.java

Myframe extends Frame 是一个通用的窗体类

package cn.bjst.util;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class MyFrame extends Frame{
	/**
	 * 加载窗口
	 */
	public void launchFrame() {
		setSize(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);
		setLocation(100,100);
		setVisible(true);
		
		new  PaintThread().start();
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}

		});
	
	
	   }
	


	class PaintThread extends Thread{
		
		public void run() {
				while(true) {
					repaint();
					try {
					    Thread.sleep(40); //1s=1000ms				    
					}catch(InterruptedException e ) {
						e.printStackTrace();
					}
				}
		     }	
		}
}

代码源出处尚学堂300集,上文代码是经过更改后的,因源代码中GameUtil1.java中存在一些问题,所以这里面我把源代码更改为用GameUtil.java中使用,因为对这块不太了解咨询了大佬。

在这里插入图片描述
该文为自己练习使用,仅供参考若需要飞机、爆炸图片可评论留下QQ邮箱!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值