飞机小游戏具体代码

飞机小游戏

实现类

  • Constant:用于存放不可变的参数
  • Explode:爆炸类
  • GameObject:所有实体的父类
  • GameUtil:加载图片的工具类
  • MyGameFrame:主体
  • Plane:飞机类
  • Shell:飞机类

图片

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现

不可更改的游戏数据:

package game;

/**
 * 存放不可更改的游戏数据
 * 
 * @author 浅墨
 *
 */
public class Constant {
	public static final int GAME_WIDTH = 500; // 游戏界面宽度
	public static final int GAME_HEIGHT = 500; // 游戏界面高度
	public static final int explode_x = 115; // 游戏结束后时间显示的位置x
	public static final int explode_y = 200; // 游戏结束后时间显示的位置y
}

读取图片:

package game;
/**
 * 读取图片
 */
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

public class GameUtil {
	//工具类私有化
	public GameUtil() {
		
	}
	
	//读取图片
	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;
	}
}

游戏中所有的实体的父类:

package game;

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

/**
 * 游戏中所有物体的父类
 * @author 浅墨
 *
 */
public class GameObject {
	private Image img;	//图片
	private int speed;	//移动速度
	private double x;	//x坐标
	private double y;	//y坐标
	private int width;	//宽度
	private int height;	//高度
	
	//多次画出图片位置
	public void drawSelf(Graphics g) {
		g.drawImage(img, (int)x,(int)y, null);
	}
	
	/**
	 * 返回物体所在的矩形,便于后续的碰撞检测
	 * @return
	 */
	public Rectangle getRect() {
		return new Rectangle((int)x,(int)y,width,height);
	}
	
	
	public GameObject(Image img, int speed, double x, double y, int width, int height) {
		super();
		this.img = img;
		this.speed = speed;
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}

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

	public GameObject() {
		super();
	}

	public Image getImg() {
		return img;
	}

	public void setImg(Image img) {
		this.img = img;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public double getX() {
		return x;
	}

	public void setX(double x) {
		this.x = x;
	}

	public double getY() {
		return y;
	}

	public void setY(double y) {
		this.y = y;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}
	
}

炮弹:

package game;

import java.awt.Color;
import java.awt.Graphics;

/**
 * 炮弹类
 * 
 * @author 浅墨
 *
 */
public class Shell extends GameObject {

	double degree; // 移动的弧度

	public Shell() {
		setX(200);
		setY(200);
		setWidth(10);
		setHeight(10);
		setSpeed(2);
		degree = Math.random() * Math.PI * 2; // 生成[0,2π)之间的随机数
	}

	public void draw(Graphics g) {
		Color c = g.getColor();
		g.setColor(Color.YELLOW);

		// 填充一个点(炮弹)
		g.fillOval((int) getX(), (int) getY(), getWidth(), getHeight());

		// 改变炮弹的飞行角度
		setX(getX() + getSpeed() * Math.cos(degree));
		setY(getY() + getSpeed() * Math.sin(degree));

		// 炮弹碰到边界反弹(当碰到边界时,沿着碰撞的方向翻转,实现改变方向)
		if (getX() < 0 || getX() > Constant.GAME_WIDTH - getWidth()) {
			degree = Math.PI - degree;
		}

		if (getY() < 30 || getY() > Constant.GAME_HEIGHT - getHeight()) {
			degree = -degree;
		}

		g.setColor(c);
	}
}

飞机:

package game;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;

/**
 * 飞机类
 * 
 * @author 浅墨
 *
 */
public class Plane extends GameObject {

	boolean left;
	boolean up;
	boolean right;
	boolean down;
	boolean live=true;

	/**
	 * 重写画笔,持续刷新位置
	 */
	@Override
	public void drawSelf(Graphics g) {
		
		if(live) {
			g.drawImage(getImg(), (int) getX(), (int) getY(), null);
			
			if(left&&getX()>0) {
				setX(getX()-getSpeed());
			}
			
			if(right&&getX()<480) {
				setX(getX()+getSpeed());
			}
			
			if(up&&getY()>30) {
				setY(getY()-getSpeed());
			}
			
			if(down&&getY()<470) {
				setY(getY()+getSpeed());
			}		
		}
	}

	public Plane(Image img, double x, double y) {
		this.setImg(img);
		this.setX(x);
		this.setY(y);
		setSpeed(3);	//给移动速度赋初值
//		this.setHeight(img.getHeight(null));
//		this.setWidth(img.getWidth(null));
		this.setHeight(10);
		this.setWidth(10);
	}

	//键盘按下某个键,则增加某个方向移动
	public void addDirection(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_LEFT:
			left = true;
			break;
		case KeyEvent.VK_UP:
			up = true;
			break;
		case KeyEvent.VK_RIGHT:
			right = 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_UP:
			up = false;
			break;
		case KeyEvent.VK_RIGHT:
			right = false;
			break;
		case KeyEvent.VK_DOWN:
			down = false;
			break;
		default:
			break;
		}
	}

}

爆炸:

package game;

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

/**
 * 爆炸类
 * 
 * @author 浅墨
 *
 */
public class Explode {
	private double x; // x地址
	private double y; // y地址

	static Image[] imgs = new Image[16];
	static {
		for (int i = 0; i < 16; i++) {
			imgs[i] = GameUtil.getImage("explode/e" + (i + 1) + ".gif");
			imgs[i].getWidth(null);
		}
	}

	int count;// 计数

	public void draw(Graphics g) {
		if (count <= 15) {
			g.drawImage(imgs[count], (int) x, (int) y, null);
			count++;
		}
	}

	public Explode(double x, double y) {
		super();
		this.x = x;
		this.y = y;
	}

}

主窗口:

package game;

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MyGameFrame extends Frame {

	/**
	 * 加载图片
	 */
	Image fj = GameUtil.getImage("image/fj.jpg");
	Image bj = GameUtil.getImage("image/bj.jpg");

	/**
	 * 制作飞机,爆炸效果,炮弹
	 */
	Plane plane = new Plane(fj, 250, 250);
	Explode boom;
	List<Shell> shellList = new ArrayList<>();	// 利用List存放多个炮弹
	
	/**
	 * 计算游玩的时间
	 */
	Date start=new Date();	//游戏开始时间
	Date end;
	int time;	

	/**
	 * 画出飞机,爆炸效果,炸弹
	 */
	public void paint(Graphics g) { // 自动被调用,g相当于画笔
		Color c=g.getColor();
		g.drawImage(bj, 0, 0, null);
		plane.drawSelf(g); // 持续刷新飞机位置

		// 画出所有炮弹
		for (int i = 0; i < shellList.size(); i++) {
			Shell b = shellList.get(i);
			b.draw(g);

			// 将飞机和炮弹矩形化,并调用intersects方法判断矩形是否相交,来实现碰撞检测
			if (shellList.get(i).getRect().intersects(plane.getRect())) {
				plane.live = false;

				if (boom == null) {
					boom = new Explode(plane.getX(), plane.getY());
					end=new Date();
					time=(int)(end.getTime()-start.getTime())/1000;
				}
				boom.draw(g);
			}
			
			/**
			 * 显示游玩时间
			 */
			if(!plane.live) {
				g.setColor(Color.red);
				Font f=new Font("宋体",Font.BOLD,50);
				g.setFont(f);
				g.drawString("生存时间:"+time+"秒", Constant.explode_x, Constant.explode_y);
				
			}
			
			g.setColor(c);
		}
	}

	/**
	 * 定义键盘监听的内部类,实现飞机移动
	 * @author 浅墨
	 */
	class KeyListenter extends KeyAdapter {
		@Override
		public void keyPressed(KeyEvent e) {
			plane.addDirection(e);
		}

		@Override
		public void keyReleased(KeyEvent e) {
			plane.minusDirection(e);
		}
	}

	/**
	 * 双缓冲解决闪烁问题
	 */
	private Image offScreenImage = null;
	public void update(Graphics g) {
		if (offScreenImage == null) {
			offScreenImage = this.createImage(Constant.GAME_HEIGHT, Constant.GAME_WIDTH);
		}
		Graphics gOff = offScreenImage.getGraphics();
		paint(gOff);
		g.drawImage(offScreenImage, 0, 0, null);
	}

	/**
	 * 初始化窗口
	 */
	public void launch() {
		this.setTitle("飞机小游戏");
		this.setVisible(true);
		this.setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
		this.setLocation(300, 300);
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
				super.windowClosing(e);
			}
		});

		new Thread(() -> {
			while (true) {
				// 内部类调用外部类JFrame的方法,实际是componet的方法
				repaint(); // 持续重画窗口,重新编辑这个组件

				try {
					TimeUnit.MILLISECONDS.sleep(25);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();

		// 添加键盘监听
		addKeyListener(new KeyListenter());

		// 增加50个炮弹
		for (int i = 0; i < 50; i++) {
			Shell b = new Shell();
			shellList.add(b);
		}
	}
	

	public static void main(String[] args) {
		MyGameFrame f = new MyGameFrame();
		f.launch();
	}
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值