博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java小游戏之打飞机(二)
阅读量:4305 次
发布时间:2019-05-27

本文共 7591 字,大约阅读时间需要 25 分钟。

Java小游戏之打飞机(二)
这篇文章本应昨天写的,可是真打算写的时候,CSDN博客维护,导致拖到了今天:
在上篇文章中已经详细介绍了该游戏的基本架构和需求分析,今天就详细写一写具体每个类的实现:
1)PlaneGameFrame类    ----游戏的主界面以及一些具体的飞机动作方法、碰撞检测等
代码:
package 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.util.ArrayList;import java.util.Date;import util.GameUtil;import util.MyFrame;/** * 飞机游戏主页面 * 继承至util包下的MyFrame类 * @author long * */public class PlaneGameFrame extends MyFrame {	Image bg=GameUtil.getImage("images/bg.jpg");	Plane p=new Plane("images/plane.png",50,50);		int bulletNum = 10;		ArrayList list = new ArrayList
(); Explode e = null; //Explode e = new Explode(30, 30); Date startTime; Date endTime; @Override public void paint(Graphics g) { g.drawImage(bg, 0, 0, null); if(p.isLive){ p.draw(g); drawBullet(g); endTime=new Date(); printTime(g); }else{ e.draw(g); printInfo(lever(),180,200,50,Color.YELLOW,g); printInfo("总用时:"+getTime()+"s",180,240,20,Color.YELLOW,g); } } public void printTime(Graphics g){ double t = getTime(); if(t>0){ printInfo("Time:"+t+"s",390,50,15,Color.YELLOW,g); } } public double getTime(){ double time; int t=(int)(endTime.getTime()-startTime.getTime())/100; System.out.println("time:"+t); time = t/10.0; if(t<0.2) return 0; return time; } public String lever(){ String msg=""; int lever = (int)getTime()/10; switch (lever) { case 0: msg = "菜鸟"; break; case 1: msg = "小鸟"; break; case 2: msg = "大鸟"; break; case 3: msg = "鸟王子"; break; default: msg = "鸟神"; break; } return msg; } public void drawBullet(Graphics g){ for(int i=0;i
2)MyFrame类    ----
PlaneGameFrame类的父类,主要是一些有关界面的基本属性及方法的封装,便于游戏的扩充
代码:
package util;import javax.swing.JFrame;import javax.swing.JPanel;/** * 游戏面板的父类 * @author long * */public class MyFrame extends JPanel{		/**	 * 加载Frame的方法	 */	public void launchFrame(){		JFrame frame = new JFrame("MyGame");		frame.add(this);		frame.setSize(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);		frame.setAlwaysOnTop(true); // 设置其总在最上		frame.setLocationRelativeTo(null); // 设置窗体初始位置		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		frame.setVisible(true);		setFocusable(true);				new PaintThread().start();	}		/**	 * 定义一个重画窗口的线程类,是一个内部类	 * @author dell	 *	 */	class PaintThread extends Thread {				public void run(){			while(true){				repaint();				try {					Thread.sleep(40); //1s = 1000ms				} catch (InterruptedException e) {					e.printStackTrace();				}   			}		}			}		public static void main(String[] args) {		new MyFrame().launchFrame();	}}
3)Constant类    ----常量类,主要封装了项目中用到的常量
代码:
package util;public class Constant {	public static final int GAME_WIDTH = 500;	public static final int GAME_HEIGHT = 500;}
4)GameUtil类    ----游戏的工具类,用于封装游戏中常用的工具方法,由于项目比较小,这里只是封装了一个加载图片的方法,后续可以封装更多的方法
代码:
package util;import java.awt.Image;import java.awt.image.BufferedImage;import java.io.IOException;import java.net.URL;import javax.imageio.ImageIO;/** * 工具类(加载图片) * @author long * */public class GameUtil {	private GameUtil(){ }  //工具类通常将构造方法私有		public static Image getImage(String path){		URL u = GameUtil.class.getClassLoader().getResource(path);		BufferedImage img = null;		try {			img = ImageIO.read(u);		} catch (IOException e) {			e.printStackTrace();		}		return img;	}}
5)GameObject类    ----游戏物体类,封装了游戏物体基本的属性和方法,如图片,坐标,图片宽度高度等属性,还有一个比较重要的方法public Rectangle getRect()这个方法用于后来的碰撞检测
代码:
package plane;import java.awt.Image;import java.awt.Rectangle;/** * 游戏物体类 * @author long * */public class GameObject {		Image img;  //图片		double x,y; //坐标	int speed;  //速度	int width;  //宽度	int height; //高度	public GameObject(){			}		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 Rectangle getRect(){		Rectangle r = new Rectangle((int)x, (int)y, width, height);		return r;	}}
6)Plane类    ----继承至
GameObject类,封装了飞机移动的方法(键盘事件)
代码:
package plane;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyEvent;import util.Constant;import util.GameUtil;/** * 飞机类 *  * @author long *  */public class Plane extends GameObject {	boolean left, right, up, down; // 移动方向的状态	boolean isLive = true;	public void draw(Graphics g) {		g.drawImage(img, (int) x, (int) y, null);		move();	}	/**	 * 按下键盘时移动状态	 * 	 * @param e	 */	public void addMove(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;		}	}	/**	 * 松开键盘时的移动状态改变情况	 * 	 * @param e	 */	public void reliseMove(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 void move() {		if (left) {			x -= speed;			if (x < 0) {				x = 0;			}		}		if (right) {			x += speed;			if (x > Constant.GAME_WIDTH-width) {				x = Constant.GAME_WIDTH-width;			}		}		if (up) {			y -= speed;			if (y < 0) {				y = 0;			}		}		if (down) {			y += speed;			if (y > Constant.GAME_HEIGHT-height-30) {				y = Constant.GAME_HEIGHT-height-30;			}		}	}	public Plane() {	}	public Plane(Image img, double x, double y) {				this.speed = 10;		this.img = img;		this.x = x;		this.y = y;				this.width = img.getWidth(null)-10;		this.height = img.getHeight(null)-10;	}	public Plane(String imgPath, double x, double y) {		this(GameUtil.getImage(imgPath), x, y);	}}
7)Bullet类    ----子弹类,继承至GameObject类,封装了子弹的基本属性与方法,有个重要的关于子弹碰到墙壁反弹的实现
代码:
package plane;import java.awt.Color;import java.awt.Graphics;import java.awt.Image;import util.Constant;/** * 子弹类 * 随机生成移动角度 * 碰到墙壁会反弹回来 * @author long * */public class Bullet extends GameObject {		double degree; //角度		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-40||y<0){			degree = -degree;		}				if(x<0||x>Constant.GAME_WIDTH-width-width){			degree = Math.PI-degree;		}	}		public Bullet(){		this.x = Constant.GAME_WIDTH/2;		this.y = Constant.GAME_HEIGHT/2;		this.width = 10;		this.height = 10;				this.speed = 5;  //子弹移动速度				degree = Math.random()*Math.PI*2; //随机生成	}		}
8)Explode类    ----爆炸类,主要用于子弹击中飞机时的爆炸效果的实现,即一系列爆炸的图片的加载与画在面板上
代码:
package plane;import java.awt.Graphics;import java.awt.Image;import util.GameUtil;public class Explode {	double x,y;	static Image[] imgs=new Image[16];	static {		for(int i=0;i
----------------------------------------------------------------------------------
自此,项目中所有的类的源码及大致解释已经结束,下面将详细说说其中的重要方法以及我遇到的困难:
1.碰撞检测-----子弹与飞机碰撞
游戏中的碰撞检测一般都是检测两个物体所在的矩形是否相交?如果相交则碰撞否则没有
首先介绍一个创建矩形的方法:
   public Rectangle getRect(){
        Rectangle r = new Rectangle((int)x, (int)y, width, height);
        return r;
    }
这个方法主要用来返回一个矩形,根据坐标和长宽创建一个矩形对象
然后介绍一个检测矩形相交的方法:
boolean java.awt..intersects( r)
    如果两矩形相交,则返回true,否则返回false
2.如何让子弹碰到墙壁反弹回来:
       if(y>Constant.GAME_HEIGHT-height-40||y<0){
            degree = -degree;
        }        
        if(x<0||x>Constant.GAME_WIDTH-width-width){
            degree = Math.PI-degree;
        }
 
  degree表示子弹运行的角度,x、y表示子弹的坐标,Constant.GAME_HEIGHT表示游戏面板高度、Constant.GAME_WIDTH表示游戏面板宽度,height表示子弹的高度、width子弹的宽度
3.关于键盘事件不响应的原因:
  Panel中的键盘事件会默认获得焦点,而JPanel中获得焦点默认是false,需手动设为true,否则不响应键盘事件
  在newJFrame时手动加上setFocusable(true);这句就ok
自此,整个游戏结束,欢迎共同学习与指正!!!

转载地址:http://heews.baihongyu.com/

你可能感兴趣的文章
maven打包本地依赖包
查看>>
spring boot jpa 实现拦截器
查看>>
jenkins + maven+ gitlab 自动化部署
查看>>
Pull Request流程
查看>>
Lambda 表达式
查看>>
函数式数据处理(一)--流
查看>>
java 流使用
查看>>
java 用流收集数据
查看>>
java并行流
查看>>
CompletableFuture 组合式异步编程
查看>>
mysql查询某一个字段是否包含中文字符
查看>>
Java中equals和==的区别
查看>>
JVM内存管理及GC机制
查看>>
Java:按值传递还是按引用传递详细解说
查看>>
Java中Synchronized的用法
查看>>
阻塞队列
查看>>
linux的基础知识
查看>>
接口技术原理
查看>>
五大串口的基本原理
查看>>
PCB设计技巧与注意事项
查看>>