1.需求分析
1 新建工程 导入图片,导入的图片在工程目录下
2 新建窗体,窗体大小400,600,新建画布,在画布类中实现三个接口
3 在画布中声明线程,以及在run方法中搭建线程样例代码
4 加载开始图片,声明Image变量,并在静态代码块中加载,在paint方法中画
5 鼠标移动到开始框中的变化
6 在点击的方法中切换背景,重画,开始线程.解决变小手问题.背景图片下滑完以后的处理
7 声明数组存放飞机,在静态代码块中加载飞机图片,在paint方法中使用三目运算切换画飞机,飞机跟随鼠标移动,飞机靠近边框问题
8 右键暂停,声明两方法,一个是控制执行wait方法的方法,一个是唤醒等待的方法的并别改suspend值.在点击的方法中获取鼠标状态来控制两个方法的执行
9 新建子弹类(int bx,by;Image bImg; int bSpeed;),在画布中新建集合存放子弹,在run方法中新建子弹对象并加到集合中,在paint方法中使用for循环从集合中取出对象并执行每一个对象的画的方法,在run方法中使用for执行移动方法
10 三个子弹,添加子弹方向,在新建子弹对象时传3个方法标识,在子弹类中添加三个子弹移动的方法,在创建子弹的时候创建三种子弹
11 创建奖励类,在画布类中创建数组存放加载进来的奖励图片,在静态代码块中加载图片,创建存放奖励的集合,在run方法中创建奖励并添加到集合中,在paint方法中画奖励,在run方法中调用奖励移动的方法.
12 画血量,在奖励的类中写碰撞,在碰时注意种类区别,各个奖励的实现.
13 敌机的出现和奖励一样
14 敌机和子弹撞击的实现
15 敌机和飞机撞击的实现
2.子弹类
public class Bullet {
int bx,by;//坐标
Image bImg;//图片
int bSpeed;//速度
int bDirection;//方向
boolean exist=true;//是否存在
public Bullet(int bx,int by,Image bImg,int bSpeed,int bDirection) {
super();
this.bx = bx;
this.by = by;
this.bImg = bImg;
this.bSpeed = bSpeed;
this.bDirection = bDirection;
}
//画子弹的方法
public void drawBullet(Graphics g) {
g.drawImage(bImg, bx, by, null);
}
//子弹移动的方法
public void moveBullet0() {
by-=bSpeed;
if (by<0) {
exist=false;
}
}
public void moveBullet1() {
bx-=bSpeed;
by-=bSpeed;
if (by<0) {
exist=false;
}
}
public void moveBullet2() {
bx+=bSpeed;
by-=bSpeed;
if (by<0) {
exist=false;
}
}
}
3.画布类
public class PlaneJPanel extends JPanel implements Runnable,MouseListener,MouseMotionListener{
Thread t = null;
static Image startImg;//游戏背景图
int x = 0,y = 0; //背景图坐标
// 游戏开始之前
boolean ck = true;
// 读取飞机图片
static BufferedImage[] p = new BufferedImage[2];
// 飞机坐标
int px = 100, py = 100;
int pc = 0;
// 暂停开关
boolean suspend = false;
// 子弹存储图片对象
static Image bImg;
List<Bullet> bullets = new ArrayList<Bullet>();
int count;
// 奖励存储图片对象
List<Award> awards = new ArrayList<Award>();
static BufferedImage[] awa = new BufferedImage[3];
// 飞机的血量
int blood = 1;
static {//使用静态代码块的作用:第一时间加载该资源
try {
startImg = ImageIO.read(new File("image/GameInterface/interface_1.png"));
p[0] = ImageIO.read(new File("image/1.png"));
p[1] = ImageIO.read(new File("image/2.png"));
bImg = ImageIO.read(new File("image/bullet/bullet_1.png"));
awa[0] = ImageIO.read(new File("image/award/award_1.png"));
awa[1] = ImageIO.read(new File("image/award/award_2.png"));
awa[2] = ImageIO.read(new File("Image/award/award_3.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PlaneJPanel() {
t = new Thread(this);
// 添加鼠标监听
addMouseListener(this);
addMouseMotionListener(this);
}
//绘制游戏背景
public void paint(Graphics g) {
// 图片 X坐标 Y坐标 绘制指定图像中已缩放到适合指定矩形内部的图像
g.drawImage(startImg, x, y, null);
// 画飞机
if (ck == false) {
pc = pc == 0 ? 1 : 0;
g.drawImage(p[pc], px, py, null);
}
for (int i = 0; i < bullets.size(); i++) {
Bullet bullet = bullets.get(i);
bullet.drawBullet(g);
}
// 画奖励
for (int i = 0; i < awards.size(); i++) {
Award award = awards.get(i);
award.drawAward(g);
}
//画血量
if(ck == false){
for (int i = 0; i < blood; i++) {
g.drawImage(awa[0], 37 * i, 10, null);
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
// 鼠标移动到这个范围内改变状态
if (ck && e.getX() >= 132 && e.getX() <= 259 && e.getY() >= 392 && e.getY() <= 432) {
setCursor(new Cursor(Cursor.HAND_CURSOR));// 将鼠标的状态变成小手
}else {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));// 将鼠标状态变成箭头
}
px = e.getX() - p[pc].getWidth() / 2;
py = e.getY() - p[pc].getHeight() / 2;
if (px <= 0) {
px = 0;
}
if (py <= 0) {
py = 0;
}
if (px >= 400 - p[pc].getWidth()) {
px = 400 - p[pc].getWidth();
}
if (py >= 600 - p[pc].getHeight()) {
py = 600 - p[pc].getHeight();
}
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
// 在开始游戏范围内点击
if (ck && e.getX() >= 132 && e.getX() <= 259 && e.getY() >= 392 && e.getY() <= 432) {
ck = false;
try {
startImg = ImageIO.read(new File("image/background/background_1.png"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 改变背景图片坐标
y = -5400;
t.start();
}
if (ck == false && e.getModifiers() == e.BUTTON3_MASK) {
suspend = suspend ? resume() : suspend();
}
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (this) {
while (true) {
count++;
if (suspend) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
y++;
if (y >= 0) {
y = -5400;
}
// 创建子弹对象
if (count % 20 == 0) {
Bullet bullet0 = new Bullet(px + p[pc].getWidth() / 2 - bImg.getWidth(null) / 2, py, bImg,
3, 0);
bullets.add(bullet0);
}
// 子弹移动的方法
for (int i = 0; i < bullets.size(); i++) {
Bullet bullet = bullets.get(i);
if (bullet.bDirection == 0) {
bullet.moveBullet0();
}
if (bullet.bDirection == 1) {
bullet.moveBullet1();
}
if (bullet.bDirection == 2) {
bullet.moveBullet2();
}
}
// 奖励的创建
if (count % 100 == 0) {
int h = (int) (Math.random() * 3);
int aSpeed = (int) (Math.random() * 5 + 3);
Award award = new Award((int) (Math.random() * 300), -50, awa[h], aSpeed, h, this);
awards.add(award);
}
// 奖励的移动
for (int i = 0; i < awards.size(); i++) {
Award award = awards.get(i);
award.moveAward();
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
}
}
// 定义两个方法
public boolean suspend() {
suspend = true;
return suspend;
}
public synchronized boolean resume() {
suspend = false;
notify();
return suspend;
}
}
4.奖励类
public class Award {
int ax,ay;
Image aImg;
int aSpeed;
int kind;
PlaneJPanel mainview;
public Award(int ax, int ay, Image aImg, int aSpeed, int kind,PlaneJPanel mainview) {
super();
this.ax = ax;
this.ay = ay;
this.aImg = aImg;
this.aSpeed = aSpeed;
this.kind = kind;
this.mainview = mainview;
}
public void drawAward(Graphics g) {
g.drawImage(aImg, ax, ay, null);
}
public void moveAward() {
ay+=aSpeed;
}
}
5.三颗子弹实现细节
(1)在子弹类添加移动方法
//子弹移动的方法
public void moveBullet0() {
by-=bSpeed;
if (by<0) {
exist=false;
}
}
public void moveBullet1() {
bx-=bSpeed;
by-=bSpeed;
if (by<0) {
exist=false;
}
}
public void moveBullet2() {
bx+=bSpeed;
by-=bSpeed;
if (by<0) {
exist=false;
}
}
(2)在run方法中修改子弹移动的代码
// 子弹移动的方法
for (int i = 0; i < bullets.size(); i++) {
Bullet bullet = bullets.get(i);
if (bullet.bDirection == 0) {
bullet.moveBullet0();
}
if (bullet.bDirection == 1) {
bullet.moveBullet1();
}
if (bullet.bDirection == 2) {
bullet.moveBullet2();
}
}
6.奖励的实现
(1) 创建奖励类 Award
public class Award {
int ax,ay;
Image aImg;
int aSpeed;
int kind;
PlaneJPanel mainview;
public Award(int ax, int ay, Image aImg, int aSpeed, int kind,PlaneJPanel mainview) {
super();
this.ax = ax;
this.ay = ay;
this.aImg = aImg;
this.aSpeed = aSpeed;
this.kind = kind;
this.mainview = mainview;
}
public void drawAward(Graphics g) {
g.drawImage(aImg, ax, ay, null);
}
public void moveAward() {
ay+=aSpeed;
}
}
(2)在画布类添加属性
// 奖励存储图片对象
List<Award> awards = new ArrayList<Award>();
static BufferedImage[] awa = new BufferedImage[3];
(3)在静态代码块中加载奖励图片
static {// 静态代码块中进行最先的加载
try {
startImg = ImageIO.read(new File("image/GameInterface/interface_1.png"));
p[0] = ImageIO.read(new File("image/1.png"));
p[1] = ImageIO.read(new File("image/2.png"));
bImg = ImageIO.read(new File("image/bullet/bullet_1.png"));
awa[0] = ImageIO.read(new File("image/award/award_1.png"));
awa[1] = ImageIO.read(new File("image/award/award_2.png"));
awa[2] = ImageIO.read(new File("Image/award/award_3.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
(4)在run方法中添加奖励
// 奖励的创建
if (count % 100 == 0) {
int h = (int) (Math.random() * 3);
int aSpeed = (int) (Math.random() * 5 + 3);
Award award = new Award((int) (Math.random() * 300), -50, awa[h], aSpeed, h, this);
awards.add(award);
}
// 奖励的移动
for (int i = 0; i < awards.size(); i++) {
Award award = awards.get(i);
award.moveAward();
}
(5)在paint 方法中画出奖励
// 画奖励
for (int i = 0; i < awards.size(); i++) {
Award award = awards.get(i);
award.drawAward(g);
}
7.画血量
(1)添加血量属性
// 飞机的血量
int blood = 1;
(2)在paint方法中画出
//画血量
if(ck == false){
for (int i = 0; i < blood; i++) {
g.drawImage(awa[0], 37 * i, 10, null);
}
}