本文共 7591 字,大约阅读时间需要 25 分钟。
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 ArrayList2)MyFrame类 ---- PlaneGameFrame类的父类,主要是一些有关界面的基本属性及方法的封装,便于游戏的扩充 代码:(); 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
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; } 这个方法主要用来返回一个矩形,根据坐标和长宽创建一个矩形对象 然后介绍一个检测矩形相交的方法:
转载地址:http://heews.baihongyu.com/