JAVA零基础学习之路(三十)

飞机大战

简介和项目

通过游戏项目学习整个Java基础知识体系。比如:多线程用来实现动画效果、容器实现对于多发炮弹的存取和处理、常用类等等的应用。

大纲知识点要求
游戏项目基本功能开发AWT基本知识了解
ImagelO 加载图片掌握
多线程和内部类了解
双缓冲技术了解
飞机类设计键盘控制了解
八个方向自由控制了解
类的设计(复习面向对象)理解
炮弹类设计炮弹任意角度飞行了解
容器或数组存储炮弹了解
矩形碰撞检测了解
爆炸类设计利用数组实现系列图片轮播了解
主窗囗中实现爆炸对象展示了解
时间控制了解
字符串显示了解

游戏项目基本功能开发

AWT技术画出游戏主窗口

  • 基本功能实现

AWT和Swing是Java中常见的GUI(图形用户界面)技术。仅限于画出最基本的窗口和图形加载,所以,大家无需在此花大量时间学习这两门技术。

本项目中,我们使用的是 AWT技术,它是Java中最老的GUI技术,非常简单。

建立Java项目,并建立类MyGameFrame。

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MyGameFrame extends Frame {//初始化窗口public void launchFrame(){this.setTitle("飞机大战");this.setvisible(true);//窗口默认不可见。需要让他可见this.setSize(width: 500, height: 500);this.setLocation(x:300, y:300);//增加关闭窗口的动作this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(status:0);}});}public static void main(String[] args) {MyGameFrame frame = new MyGameFrame();frame.LaunchFrame();}
}

图形和文本绘制

paint方法

1.如果要在窗口中画图或者显示什么内容,重写paint(Graphics g)方法。

2. paint()画出窗口及其内部内容。它会被系统自动调用。我们不需要去调用这个方法。

【例】paint方法介绍

@Override
public void paint(Graphics g) {//paint方法作用是:画出整个窗口及内部内容。被系统自动调用。
}

ImagelO实现图片加载技术

public class MyGameFrame extends Frame {Image bg = GameUtil.getImage(path:"images/bg.jpg");Image plane = GameUtil.getImage(path:"images/plane.png");//初始化窗口public void launchFrame(){...}@Overridepublic void paint(Graphics g) {g.drawImage(bg, x:0, y:0, width:500, height:500, observer: null);g.drawImage(plane, x: 200, y:200, width: 30, height:30, observer: null);}public static void main(String[] args] {MyGameFrame frame = new MyGameFrame();frame.launchFrame();}
}

双缓冲技术解决闪烁问题

在实际开发中,绘制图形是非常复杂的,绘图可能需要几秒甚至更长时间,也经常发生闪烁现象,为了解决这个问题,我们通常使用“双缓冲技术”。

“双缓冲技术”的绘图过程如下:

1、在内存中创建与画布一致的缓冲区

2、在缓冲区画图

3、将缓冲区位图拷贝到当前画布上

4、释放内存缓冲区

双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。

我们只需将如下“双缓冲”实现代码,放入MyGrameFrame 类中,即可:

【例】添加双缓冲技术

private Image offScreenImage = null;
public void update(Graphics g) {if(offScreenlmage == null)offScreenlmage=this.createlmage(500,500);//这是游戏窗口的宽度和高度Graphics gOff = offScreenlmage.getGraphics();paint(gOff);g.drawlmage(offScreenlmage, 0, 0, null);
}

GameObject类设计

import java.awt.*;
//游戏物体的根类
public class GameObject {Image img;//对应的图片int x,y;//坐标int speed;//物体移动速度int width,height;//物体的宽度和高度//画自己public void drawMySelf(Graphics g){g.drawImage(img,x,y,width,height, observer: null);}//返回该物体对应的矩形public Rectangle getRec(){return new Rectangle(x,y,width,height);}public GameObject(){}public GameObject(Image img, int x, int 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 Game0bject(Image img, int x, int y, int speed) {this(img,x,y);this.speed = speed; }public Game0bject(Image img, int x, int y) {this(img);this.x = x;this.y =y;}public GameObject(Image img) {this.img =img;if(this.img!=null){this.width = img.getWidth(observer:null);this.height = img.getHeight(observer:null);}}
}

设计飞机类

有了GameObject类,设计飞机类特别简单。

飞机是我们游戏中的主物体,需要由玩家直接控制,手段有:键盘、鼠标、触摸屏等等。无论是什么硬件,本质上都是玩家通过硬件改变游戏物体的坐标,从而实现多种多样的效果。

键盘控制原理

键盘和程序交互时,每次按下键、松开键都会触发相应的键盘事件,事件的信息都封装到了KeyEvent 对象中。

为了识别按下的键是哪个键,系统对键盘所有按键做了编号,每个按键都对应相应的数字。比如:回车键对应数字10,空格键对应数字32等。这些编号,我们都可以通过KeyEvent对象来查询,KeyEvent.VKENTER实际就是存储了数字10。

增加操控功能

我们为飞机类增加了4个方向,用来控制飞机的移动。同时,为了后续需求,也增加了live变量,它表示飞机是“活的”还是“死的”,“活的”我们就画出飞机,“死的”就不画飞机了。

【例】Plane类:增加操控功能

package com.bjsxt.plane;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
public class Plane extends GameObject {boolean left, up, right, down;boolean live = true;//按下上下左右键,则改变方向值。 //比如:按下上键,则e.getKeyCode()的值就是VK_UP,那么置:up=true;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;}}@Overridepublic void drawMySelf(Graphics g) {super.drawMySelf(g);//根据方向,计算飞机新的坐标if(left){x -= speed;}if(right){×+=speed;}if(up){y -= speed;}if(down){y += speed;}}
}

炮弹类设计

通过炮弹类的设计,我们可以更深入面向对象编程以及数组的知识。同时,可能还需要读者稍微回忆一下初中数学曾学过的三角函数,这样更能理解炮弹飞行路径的计算原理。当然,如果忘记这些知识了也没关系,毕竟在实际开发中很少涉及数学原理性的内容。

炮弹类我们用实心的黄色椭圆实现,不再加载新的图片。当然,大家可以自行找一些炮弹图片亦可。

我们的逻辑是在窗口固定位置(200,200)处生成炮弹,炮弹方向是随机的,并且遇到边界会反弹。

【例】Shell类

package com.bjsxt.plane;
import java.awt.Color;
import java.awt.Graphics;
public class Shell extends GameObject {double degree;public Shell(){degree = Math.random()*Math.P*2;×=200;y=200;width = 10;height = 10;speed = 3;//炮弹沿着任意角度飞行× += speed*Math.cos(degree);y += speed*Math.sin(degree);//如下代码,用来实现碰到边界,炮弹反弹回来(原理和打台球游戏一样)if(y>Constant.GAME HEIGHT-height|ly<30){degree = -degree;}if(x<O||x>Constant.GAME_ WIDTH-width){degree = Math.P/-degree;}//返回给外部,变回以前的颜色g.setColor(c);}
}

炮弹任意角度飞行路径

炮弹沿着任意角度飞行,核心代码就两行:

× += speed*Math.cos(degree);

y += speed*Math.sin(degree);

这里实际用到了初中学的三角函数,通过cos/sin将任意角度分解到×轴、Y轴,从而可以精确的直到x、y坐标的变化情况。

碰撞检测技术

游戏中,碰撞是遇到最频繁的技术。当然,很多游戏引擎内部已经做了碰撞检测处理,我们只需调用即可。

矩形检测原理

游戏中,多个元素是否碰到一起,实际上,通常是用“矩形检测”原理实现的。我们在前面提到,游戏中所有的物体都可以抽象成“矩形”,我们只需判断两个矩形是否相交即可。对于一些复杂的多边形、不规则物体,实际上是将他分解成多个矩形,继续进行矩形检测。

Java的APl中,为我们提供了Rectangle类来表示矩形相关信息,并且提供了intersects()方法,直接判断矩形是否相交。

我们的游戏逻辑是:“飞机碰到炮弹,则死亡”。也就是说,我们需要检测:“飞机和所有的炮弹是否碰撞”。如果有50个炮弹对象,则进行50次比对检测即可。我们修改MyGameFrame类的paint()方法

【例】MyGameFrame类:增加碰撞检测

public void paint(Graphics g){g.drawlmage(bglmg, 0, 0null);plane.drawMySelf(g);//画出飞机本身//画出容器中所有的炮弹for(int i=0;i<shellList.size();i+ +){Shell b ==shellList.get(i);b.draw(g);//飞机和所有炮弹对象进行矩形检测boolean peng = b.getRect().intersects(plane.getRect()if(peng){plane.live = false;//飞机死掉,画面不显示}}
}

分享一个全面学习JAVA的视频教程

以上就是小编为大家整理的关于JAVA的知识。

后续持续更新,还望诸君多多学习,早日上岸!

需要学习具体教程的可以关注私信我哦!

本文链接:https://my.lmcjl.com/post/12300.html

展开阅读全文

4 评论

留下您的评论.