直升飞机java游戏_java飞机游戏
飞机游戏
需求分析
本意是做一个类似雷霆战机的小游戏, 但超出了知识范围, 简化成为了一个没有敌人, 生命, 得分, 菜单栏的小游戏, 游戏内容变成了飞机闪躲从固定位置发出的多个子弹, 计算存活时间的样子
游戏窗口通过Frame实现, 双缓冲技术解决闪烁问题
使用paint方法画出所有游戏内容, 且定义了一个线程不断重画窗口
增加键盘监听实现飞机的移动
使用ArrayList<>储存炮弹对象并画出, 并实现炮弹的碰撞反弹
利用返回物体矩形区域判断物体是否相交实现碰撞检测
飞机死亡的爆炸效果通过导入十二张图片然后轮播实现
使用Date打印存活时间
代码实现
Constant
package com.game;
/**
*
* @author 漫磋嗟
* 设置游戏窗口常量,便于统一修改
*/
public class Constant {
static final int CONSTANT_WIDTH = 800;
static final int CONSTANT_HEIGHT = 800;
}
MyFrame
package com.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.util.ArrayList;
import java.util.Date;
/**
*
* @author 漫磋嗟
* 游戏主窗口
*/
public class MyFrame extends Frame {
//传入图片作为成员变量
Image bgImg = GameUtil.getImage("images/bc.jpg");
Image planeImg = GameUtil.getImage("images/plane.png");
Plane plane = new Plane(planeImg, 360, 750, 5); //新建飞机对象
ArrayList shellList = new ArrayList(); //新建炮弹数组
Explode explode;//新建爆炸对象
Date startTime = new Date(); //游戏开始时间
Date endTime; //游戏结束时间
@Override
public void paint(Graphics g) {
g.drawImage(bgImg, 0, 0, null); //画背景
plane.drawSelf(g); //画飞机
//画出容器里的所有炮弹
for(int i=0;i
Shell b = shellList.get(i);
b.draw(g);
//飞机和炮弹的碰撞检测
boolean boom = b.getRect().intersects(plane.getRect());
if(boom) {
plane.live = false;
//只进行一次爆炸动画
if(explode == null) {
explode = new Explode(plane.x,plane.y);
}
explode.draw(g);
}
}
//打印游戏结果
if(!plane.live) {
if(endTime == null) {
endTime = new Date();
}
int period = (int)((endTime.getTime()-startTime.getTime())/1000);
printInfo(g, "你存活了"+period+"秒", 50, 230, 300, Color.red);
}
}
//打印信息
public void printInfo(Graphics g, String s, 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(s, x, y);
g.setColor(c);
}
//增加键盘监听
class KeyMonitor extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
plane.addDirection(e);
}
@Override
public void keyReleased(KeyEvent e) {
plane.minusDirection(e);
}
}
//定义一个不断重画窗口的内部类
class PaintThread extends Thread {
public void run() {
while(true) {
repaint();
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
public void launchFrame() {
setTitle("打飞机");
setSize(Constant.CONSTANT_WIDTH,Constant.CONSTANT_HEIGHT);
setVisible(true);
setLocationRelativeTo(null); //窗口居中
setResizable(false); //窗口不可拉伸
//增加关闭窗口监听
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//启动重画线程
new PaintThread().start();
//增加键盘的监听
addKeyListener(new KeyMonitor());
//初始化生成炮弹
for(int i=0; i<40; i++) {
Shell b = new Shell();
shellList.add(b);
}
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.launchFrame();
}
//双缓冲技术 解决闪烁问题
private Image offScreenImage = null;
public void update(Graphics g) {
if(offScreenImage == null)
offScreenImage = this.createImage(Constant.CONSTANT_WIDTH,Constant.CONSTANT_HEIGHT);
Graphics gOff = offScreenImage.getGraphics();
paint(gOff);
g.drawImage(offScreenImage, 0, 0, null);
}
}
GameUtil
package com.game;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
/**
*
* @author 漫磋嗟
* 用于导入图片的工具类
*/
public class GameUtil {
// 工具类最好将构造器私有化。
private 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;
}
}
GameObject
package com.game;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
/**
*
* @author 漫磋嗟
* 游戏中的物体类
*/
public class GameObject {
Image img;
double x,y;
int width,height;
int speed;
//画自己
public void drawSelf(Graphics g) {
g.drawImage(img, (int)x, (int)y, null);
}
public GameObject() {
}
public GameObject(Image img, double x, double y) {
super();
this.img = img;
this.x = x;
this.y = y;
}
public GameObject(Image img, double x, double y, int width, int height, int speed) {
super();
this.img = img;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
}
//返回物体对应矩形区域 用于碰撞检测
public Rectangle getRect(){
return new Rectangle((int)x,(int) y, width, height);
}
}
Plane
package com.game;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
/**
*
* @author 漫磋嗟
* 游戏中的飞机类
*/
public class Plane extends GameObject {
boolean left,right,down,up;
boolean live = true;
public Plane(Image img, double x, double y, int speed) {
super(img,x,y);
this.speed = speed;
//设置为宽度和高度为图片的高度宽度 便于碰撞检测
this.width = img.getWidth(null);
this.height = img.getHeight(null);
}
public void drawSelf(Graphics g) {
if(live) {
super.drawSelf(g);
if(left) {
x -= speed;
}
if(right) {
x += speed;
}
if(up) {
y -= speed;
}
if(down) {
y += speed;
}
}else {
}
}
//改变飞机的方向
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;
}
}
}
Shell
package com.game;
import java.awt.Color;
import java.awt.Graphics;
/**
*
* @author 漫磋嗟
* 游戏中的炮弹类
*/
public class Shell extends GameObject {
double degree;
public Shell() {
x = 400;
y = 300;
width = 10;
height = 10;
speed = 5;
//随机生成炮弹角度
degree = Math.random()*Math.PI*2;
}
public void draw(Graphics g) {
//将外部传入对象g的状态保存好
Color c = g.getColor();
g.setColor(Color.yellow);
g.fillOval((int)x, (int)y, width, height);
//炮弹沿着任意角度飞行
x += speed*Math.cos(degree);
y += speed*Math.sin(degree);
//碰到边界炮弹反弹回来
if(y<35 || y>Constant.CONSTANT_HEIGHT-height) {
degree = -degree;
}
if(x<0 || x>Constant.CONSTANT_WIDTH-width) {
degree = Math.PI-degree;
}
//返回给外部,变回以前的颜色
g.setColor(c);
}
}
Explode
/**
*
* @author 漫磋嗟
* 飞机的爆炸效果
*/
public class Explode {
double x,y;
static Image[] imgs = new Image[12];
static {
for(int i=0; i<12; i++) {
imgs[i] = GameUtil.getImage("images/explode/e"+(i+1)+".gif");
imgs[i].getWidth(null);
}
}
int count;
public void draw(Graphics g) {
if(count<12) {
g.drawImage(imgs[count], (int)x, (int)y, null);
count++;
}
}
public Explode(double x, double y) {
this.x = x;
this.y = y;
}
}
总结
使用ArrayList存储炮弹对象
建立一个导入图片的私有类和便于改变窗口长宽的常量类
游戏内物体坐标 (x, y) 一定要设置为double类型, 否则碰撞检测会出错
bug: 飞机没有边界 爆炸效果会出现卡顿或两次
希望能够有 PlaneGame2.0
直升飞机java游戏_java飞机游戏相关推荐
- [计算机毕设]基于java的打飞机游戏系统设计与实现(项目报告+源代码)
基于java的打飞机游戏系统项目说明报告 1.1 手机软件现状 在信息社会中,手机及其他无线设备越来越多的走进普通百姓的工作和生活,随着信息网络化的不断进展,手机及其他无线设备上网络势在必行.但是传统 ...
- 【源码+图片素材】Java开发经典游戏飞翔的小鸟_Java游戏项目Flappy Bird像素鸟游戏_Java小游戏_Java初级项目_Java课程设计项目
开发环境: jdk1.8 开发工具: IDEA JavaEE基础: 变量.数据类型.判断语句.循环结构.数组.集合.简单窗口创建.图形图片绘制.双缓存技术.事件-键盘事件.物体的碰撞检测.File [ ...
- Java面向对象学习练习———潜艇游戏(飞机游戏)
潜艇游戏需求: 所参与的角色: 战舰.深水炸弹.侦察潜艇.鱼雷潜艇.水雷潜艇.水雷 角色间的关系: 战舰发射深水炸弹 深水炸弹可以打潜艇(侦察潜艇.鱼雷潜艇.水雷潜艇),若打中: 潜艇消失.深水炸弹消 ...
- 怎么开发联机小游戏_Q飞机游戏:空战吃鸡大乱斗游戏!好玩的联机Q飞机对战小游戏...
20000+游戏爱好者已加入我们! 带你发现好游戏! <Q飞机>游戏小程序好玩吗? <Q飞机>小游戏怎么玩? 只有你想不到, 没有我找不到的好游戏! 「良心好游戏推荐」 搜罗了 ...
- java 飞机 源码_Java 飞机游戏源码(带音乐)
[实例简介] [实例截图] [核心代码] package liujunbo.feiji; import java.awt.Color; import java.awt.Frame; import ja ...
- java实现抽奖游戏_Java实现游戏抽奖算法
常用抽奖算法对比 基础的游戏抽奖算法通常要求实现在指定奖品的集合中,每个奖品根据对对应概率进行抽取.个人了解的主要有以下几中抽奖算法: 随机数一一对应 算法思想 这种算法思想最为简单.将n个奖品编号0 ...
- java 拼图游戏_Java 拼图游戏
Java 拼图游戏 2014-07-01·WeaponX 11359 次浏览 ## 效果图 ![pintu.png](https://image.xsoftlab.net/baike/articleI ...
- java打字游戏_Java打字游戏
贴吧上看到有人做Java打字游戏,但是问题多多,我把他的程序拿来大改一番,算是半个原创吧.键盘按出对应字母,则该字母消失并随机产生新字母. 如果加些贴图润色一下可以更美观,学习计划紧,暂时不美化了. ...
- 俄罗斯游戏java源代码_Java俄罗斯方块游戏源代码JAVA游戏源码下载
源码介绍 Java俄罗斯方块游戏源代码 (2 folders, 3 files, 1.55 KB, 166.30 KB in total.) Read me!.txt 174 b ...
最新文章
- phpstudy一个域名配置两个网站(一个是thinkphp5,一个是原生php)
- expressjs路由匹配规则
- 获取顶级域名与一级域名的python库-tld
- SAP Spartacus 服务器端渲染文件 server.js 和构建后的 main.js 对比
- Maven 核心原理
- 套娃的开始——Network in Network网络学习笔记
- Minix的系统调用
- Centos7 升级稳定版 openssl
- Struts(十二):异常处理:exception-mapping元素
- android组件开关按钮,简单聊聊“开关”这个小控件
- ARP解决方法/工具+真假ARP防范区别方法+ARP终极解决方案
- intellij 上导入外部包教程
- CS231n:作业1——KNN
- java 图片合并成pdf_Java多张图片合成PDF
- 目前最值得购买的两种上网神器?看完你会选择哪一款?
- ◎Hspace 和vspace 的设定
- hsql导入mysql_关于HSQLDB访问已有数据库文件的操作说明
- amd显卡驱动linux 卸载,怎么彻底卸载AMD显卡驱动|完全卸载AMD显卡驱动步骤
- python 描述性分析的包_pasty描述性统计包
- 多页vue应用的单页面打包方法(内含打包模式的应用)
热门文章
- Android仿抖音短视频布局
- 如何在Windows系统上解压缩tgz文件
- 苏州新导智慧养老之养老院解决方案监护系统,为智慧养老更进一步
- [土狗之路]coursera 北京大学C++ 魔兽世界:装备
- A-Level经济真题(10)
- 华为android8.0续航,华为畅享8电池容量多少_华为畅享8续航能力-太平洋IT百科
- 7-116 十六进制数转换成相应的十进制数 (15分)
- 【软件设计】深入理解日志系统的意义
- jbig2转其它格式(支持png,pbm)
- Win10 WSL Ubuntu如何重新启动(restart),sudo systemctl restart命令无效