13.4-全栈Java笔记:打飞机游戏实战项目|offScreenImage|GameObject|Plane
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13.4-全栈Java笔记:打飞机游戏实战项目|offScreenImage|GameObject|Plane相关的知识,希望对你有一定的参考价值。
双缓冲技术解决闪烁问题
上节,我们实现了动画效果,但是发现窗口会不停的闪烁,体验度非常差。在实际开发中,绘制图形是非常复杂的,绘图可能需要几秒甚至更长时间,也经常发生闪烁现象, 为了解决这个问题,我们通常使用“双缓冲技术”。
1)“双缓冲技术”的绘图过程如下:
a. 在内存中创建与画布一致的缓冲区
b. 在缓冲区画图
c. 将缓冲区位图拷贝到当前画布上
e. 释放内存缓冲区
双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。
我们只需将如下“双缓冲”实现代码,放入MyGrameFrame类中,即可:
【示例1】添加双缓冲技术
Image offScreenImage = null;
public void update(Graphics g) { if(offScreenImage == null) offScreenImage = this.createImage(500,500);//这是游戏窗口的宽度和高度
Graphics gOff = offScreenImage.getGraphics(); paint(gOff); g.drawImage(offScreenImage, 0, 0, null); } |
GameObject类设计
1) GameObject类的定义
我们发现,窗口中所有的对象(飞机、炮弹等等)都有很多共性:“图片对象、坐标位置、运行速度、宽度和高度”。为了方便程序开发,我们需要设计一个GameObject类,它可以作为所有游戏物体的父类,方便我们编程。
【示例2】GameObject类
package cn.sxt.game;
import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle;
public class GameObject { Image img; //该物体对应的图片对象 double x,y; //该物体的坐标 int speed; //该物体的运行速度 int width,height; //该物体所在矩形区域的宽度和高度
/** * 怎么样绘制本对象 * @param g */ public void drawMySelf(Graphics g){ g.drawImage(img, (int)x, (int)y, null); }
public GameObject(Image img, double x, double y) { this.img = img; this.x = x; this.y = y; if(img!=null){ this.width = img.getWidth(null); this.height = img.getHeight(null); } }
public GameObject(Image img, double x, double y, int speed, int width, int height) { this.img = img; this.x = x; this.y = y; this.speed = speed; this.width = width; this.height = height; }
public GameObject() { }
/** * 返回物体对应矩形区域,便于后续在碰撞检测中使用 * @return */ public Rectangle getRect(){ return new Rectangle((int)x,(int) y, width, height); } } |
2) 设计飞机类
有了GameObject这个父类,我们设计飞机类特别简单,目前飞机类没有特别复杂的要求。我们只需简单的继承,即可使用:
【示例3】Plane类
package cn.sxt.game;
import java.awt.Graphics; import java.awt.Image;
public class Plane extends GameObject { @Override public void drawMySelf(Graphics g) { super.drawMySelf(g); this.x +=3;//飞机水平飞,我们也可以调整x、y算法,按照我们指定的路径飞行 }
public Plane(Image img, double x, double y) { super(img,x,y); } } |
通过继承,我们发现实现新的类,爽了很多!
3) MyGameFrame类调用方式的调整
我们将Plane类封装后,也无需在MyGameFrame类中添加那么多飞机的属性,我们全部封装到了Plane类里面,因此,调用也变得更加简单。
【示例4】封装后的MyGameFrame类
public class MyGameFrame extends Frame { Image bgImg = GameUtil.getImage("images/bg.jpg"); Image planeImg = GameUtil.getImage("images/plane.png"); Plane plane = new Plane(planeImg,300,300);
//paint方法作用是:画出整个窗口及内部内容。被系统自动调用。 @Override public void paint(Graphics g) { g.drawImage(bgImg, 0, 0, null); plane.drawMySelf(g); //画出飞机本身 } //其余代码,没有任何变化,不在附上,自行参考上一个版本。 } |
通过面向对象封装后,如果我们要再创建多个飞机,也变得异常简单。
【示例5】创建多个飞机
public class MyGameFrame extends Frame { Image bgImg = GameUtil.getImage("images/bg.jpg"); Image planeImg = GameUtil.getImage("images/plane.png");
Plane plane = new Plane(planeImg,300,300); Plane plane2 = new Plane(planeImg,300,350); Plane plane3 = new Plane(planeImg,300,400);
//paint方法作用是:画出整个窗口及内部内容。被系统自动调用。 @Override public void paint(Graphics g) { g.drawImage(bgImg, 0, 0, null);
plane.drawMySelf(g); //画出飞机本身 plane2.drawMySelf(g); //画出飞机本身 plane3.drawMySelf(g); //画出飞机本身 } //其余代码,和上个版本一致,为节省篇幅突出重点,不在附上。 } |
「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。
笔记包含从浅入深的六大部分:
A-Java入门阶段
B-数据库从入门到精通
C-手刃移动前端和Web前端
D-J2EE从了解到实战
E-Java高级框架精解
F-Linux和Hadoop
本文出自 “全栈Java笔记” 博客,请务必保留此出处http://javanew.blog.51cto.com/12931675/1952663
以上是关于13.4-全栈Java笔记:打飞机游戏实战项目|offScreenImage|GameObject|Plane的主要内容,如果未能解决你的问题,请参考以下文章
13.3-全栈Java笔记:打飞机游戏实战项目|PaintThread|launchFrame
13.2-全栈Java笔记:打飞机游戏实战项目|Graphics|ImageIO|GameUtil
13.9-全栈Java笔记:打飞机游戏实战项目|Time|Plane|其他案例展示
13.7-全栈Java笔记:打飞机游戏实战项目|Rectangle|intersects|Plane