自学Java已经有一段时间了吧,一直都没有一个关于界面的完整的项目,计算器这些又太简单,所以就一直构思写一个基于JavaSwing的游戏。虽然在日常开发中使用到JavaSwing开发界面的很少。但是这个游戏也就当做一次对我前面所学习的知识的巩固吧,好了废话不多说,下面我们先来看看游戏运行的效果。图片素材都是网络上面找的。后面我会把所有资源都发上来(音频、图片、图标等)
游戏主界面
游戏运行界面
这只是一张GIF图片,实际运行的时候还有声音,玩的时候更有感觉
游戏暂停界面
游戏结束界面
游戏结束界面写的很简单
第一次写游戏,还是有很多不足的地方,大神轻喷。
下面开始给大家正式讲解我的思路:
1、首先使用面向对象的方法去思考,因为是飞行游戏,所以里面涉及到很多东西移动。敌机绘制和移动,敌机子弹移动,礼物移动,英雄机的移动,英雄机子弹的移动。爆炸效果图的出现,所以我们可以抽象一个父类出来。 这个父类就叫飞行器类吧。
下面是抽象类Flyer的变量和方法结构图:
下面是具体实现的代码:
package com.PlaneWars;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
/**
*
* 封装所有飞行器的属性和方法
* @author poc999
*
*/
public abstract class Flyer {
/*
* 飞行器的坐标
*/
public int x;
public int y;
/*
* 飞行器的大小
*/
public int WIDTH;
public int HEIGHT;
/*
* 飞行器的图片
*/
BufferedImage image;
//初始化飞行器对象
public Flyer(int x,int y,int WIDTH,int HEIGHT,BufferedImage image){
this.x=x;
this.y=y;
this.WIDTH=WIDTH;
this.HEIGHT=HEIGHT;
this.image=image;
}
//每个飞行器都需要自己移动,但是需要子类自己去实现移动的方法
public abstract void move(long time);
//判断两个飞行器是否碰撞
public static boolean boom(Flyer f1,Flyer f2){
//step1: 求出两个矩形的中心点
int f1x = f1.x + f1.WIDTH/2;
int f1y = f1.y + f1.HEIGHT/2;
int f2x = f2.x + f2.WIDTH/2;
int f2y = f2.y + f2.HEIGHT/2;
//step2: 横向和纵向碰撞检测
boolean H = Math.abs(f1x - f2x) < (f1.WIDTH + f2.WIDTH)/2;
boolean V = Math.abs(f1y -f2y) < (f1.HEIGHT + f2.HEIGHT)/2;
//step3: 必须两个方向同时碰撞
return H&V;
}
//绘制出每个飞行物
public void draw(Graphics g)
{
g.drawImage(image, x, y, WIDTH, HEIGHT, null);
}
}
2、下面我们来构思需要那些物体在JPlane上面跑起来。
(1)敌机1.2.3
(2)爆炸效果
(3)敌机子弹
(4)礼物
(5)英雄子弹
(6)英雄机
(7)上面所有的这些类都继承Flyer抽象类。因为都是飞行器
下面是所有类的结构图:
下面我们就先来挨着实现每一个飞行器类:
①Enemy1类(A类敌机类):
package com.PlaneWars;
import java.util.Random;
public class Enemy1 extends Flyer{
Random r=new Random();
//构造方法
public Enemy1(int x, int y) {
super(x, y, 40, 40, ImageRead.enemyA);
// TODO Auto-generated constructor stub
}
/*
* A类敌机的移动方法,X,Y每次随机加上一个小于5的值
*/
@Override
public void move(long time) {
// TODO Auto-generated method stub
x+=r.nextInt(5);
y+=r.nextInt(5);
}
/*
*
* 敌机子弹是随着敌机位置出现的,所以这里写一个返回敌机火力的方法
*/
public Enemybullet enemyfire(){
Enemybullet e=new Enemybullet(this.x+WIDTH/4,this.y+HEIGHT);
return e;
}
}
②Enemy2类(B类敌机类)和A类敌机的实现大同小异:
package com.PlaneWars;
import java.util.Random;
public class Enemy2 extends Flyer{
Random r=new Random();
public Enemy2(int x, int y) {
super(x, y, 35, 35, ImageRead.enemyB);
// TODO Auto-generated constructor stub
}
//只能向左移动
@Override
public void move(long time) {
// TODO Auto-generated method stub
x-=r.nextInt(5);
y+=r.nextInt(5);
}
public Enemybullet enemyfire(){
Enemybullet e=new Enemybullet(this.x+WIDTH/4,this.y+HEIGHT);
return e;
}
}
③Enemy3类(C类敌机类,上同)
package com.langxikeji.PlaneWars;
import java.util.Random;
public class Enemy3 extends Flyer{
Random r=new Random();
public Enemy3(int x, int y) {
super(x, y,30,30,ImageRead.enemyC);
// TODO Auto-generated constructor stub
}
/*
*和A类B类敌机移动不同,只能够在Y轴上面移动
*/
@Override
public void move(long time) {
// TODO Auto-generated method stub
y+=r.nextInt(5);
}
public Enemybullet enemyfire(){
Enemybullet e=new Enemybullet(this.x+WIDTH/4,this.y+HEIGHT);
return e;
}
}
④enemyBullet类(敌机子弹类):
package com.PlaneWars;
public class Enemybullet extends Flyer{
public Enemybullet(int x, int y) {
super(x, y, 20, 26, ImageRead.enemybullet);
// TODO Auto-generated constructor stub
}
@Override
public void move(long time) {
// TODO Auto-generated method stub
if(time%20==0){
y+=10;
}
}
}
⑤Gift类(礼物类):
package com.PlaneWars;
public class Gift extends Flyer{
public Gift(int x, int y) {
super(x, y, 30, 30, ImageRead.gift);
// TODO Auto-generated constructor stub
}
@Override
public void move(long time) {
// TODO Auto-generated method stub
if(time%20==0){
y+=10;
}
}
}
⑥Hero类(英雄机类):
package com。PlaneWars;
/*
* 英雄机的类,因为英雄机需要键盘来控制移动,所以。移动的方法需要从新定义
*/
public class Hero extends Flyer{
public Hero(int x, int y) {
super(x, y, 40, 40, ImageRead.hero);
// TODO Auto-generated constructor stub
}
public void MoveUp() { // 以防飞机上移出界,每次移五个单位
if (y >= 10)
y -= 10;
}
public void MoveDown() {
if (y <= 606) // 游戏界面减去飞机高79和最小移动步长
y += 10;
}
public void MoveLeft() {
if (x >= 10)
x -= 10;
}
public void MoveRight() {
if (x <= 431)
x += 10;
}
//飞机子弹发射的位置由飞机位置确定
public Herobullet Herofire(){
Herobullet bullet=new Herobullet(this.x+WIDTH/4,this.y);
return bullet;
}
@Override
public void move(long time) {
// TODO Auto-generated method stub
}
}
⑦HeroBullet类(英雄机子弹类):
package com.PlaneWars;
/*
* 英雄机子弹的类
*/
public class Herobullet extends Flyer {
public Herobullet(int x, int y) {
super(x, y, 40,40, ImageRead.herobullet);
// TODO Auto-generated constructor stub
}
@Override
public void move(long time) {
// TODO Auto-generated method stub
if(time%20==0){
y-=10;
}
}
}
⑧Blast类(爆炸效果类):
package com.PlaneWars;
/*
* 英雄机子弹和敌机相撞的爆炸类
*/
public class Blast extends Flyer{
public Blast(int x, int y) {
super(x-20, y-20,50,50,ImageRead.blast );
// TODO Auto-generated constructor stub
}
//并没有移动,爆炸图刚刚出现就消失了
@Override
public void move(long time) {
// TODO Auto-generated method stub
}
}
上面是所以飞行器的类,这只是我写的这么多类,如果你还要增加敌机或者
一些其他的飞行物体。你可以按照我的方法在增加类。下面是资源加载类!
⑨资源加载类(ImageRead类)
package com.PlaneWars;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import javax.imageio.ImageIO;
/*
* 所有资源加载类
*/
public class ImageRead {
public static BufferedImage enemyA;// 敌机一
public static BufferedImage enemyB;// 敌机二
public static BufferedImage enemyC;// 敌机三
public static BufferedImage hero;// 英雄机
public static BufferedImage herobullet;// 英雄机子弹
public static BufferedImage enemybullet;// 敌机子弹
public static BufferedImage gift;// 礼物
public static BufferedImage blast;// 爆炸
public static BufferedImage map1;//地图
public static BufferedImage b1;
public static BufferedImage b2;
public static BufferedImage b3;
public static BufferedImage b4;
public static BufferedImage icon;
/*
* 资源加载使用静态初始化块
* 因为只需要启动的时候使用一次
*/
static {
try {
enemyA = ImageIO.read(new FileInputStream("./素材/Boss/BOSS1.png"));
enemyB = ImageIO.read(new FileInputStream("./素材/Boss/BOSS2.png"));
enemyC = ImageIO.read(new FileInputStream("./素材/Boss/BOSS3.png"));
hero = ImageIO.read(new FileInputStream("./素材/Hero1/hero.png"));
herobullet = ImageIO.read(new FileInputStream("./素材/Bullet/双弹1.png"));
enemybullet = ImageIO.read(new FileInputStream("./素材/Bullet/蓝弹1.png"));
gift = ImageIO.read(new FileInputStream("./素材/Gift/gift.png"));
blast = ImageIO.read(new FileInputStream("./素材/Blast/blast_2_2.png"));
map1=ImageIO.read(new FileInputStream("./素材/Maps/map5.jpg"));
icon=ImageIO.read(new FileInputStream("./素材/Icon/图标.jpg"));
b1=ImageIO.read(new FileInputStream("./素材/Maps/map4.jpg"));
b2=ImageIO.read(new FileInputStream("./素材/Maps/b2.jpg"));
b3=ImageIO.read(new FileInputStream("./素材/Maps/b3.png"));
b4=ImageIO.read(new FileInputStream("./素材/Maps/b4.png"));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
⑩PlaneFrame类(顶层窗体类)。是画板的载体,自己可以根据背景的大小来设置
package com.PlaneWars;
import java.awt.BorderLayout;
import javax.swing.JFrame;
/**
* @author poc999
*
*/
public class PlaneFrame extends JFrame {
private static final long serialVersionUID = 1L;
// 创建JPlane的对象
PlaneWars pw = new PlaneWars();
// 创建PlaneFrame的构造器,初始化对象
public PlaneFrame() {
// 将JPanel的焦点状态设置为true。
pw.setFocusable(true);
// 让JFrame先获得焦点,然后JPanel在获得焦点
pw.requestFocus();
this.add(pw, BorderLayout.CENTER);
}
public static void main(String[] args) {
// 创建主窗口的对象
PlaneFrame pf = new PlaneFrame();
// 设置主窗体的名字
pf.setTitle("PlaneWars by2.0");
// 设置主窗体的大小
pf.setSize(500, 700);
// 设置主窗体居中显示
pf.setLocationRelativeTo(null);
// 设置游戏界面图标
pf.setIconImage(ImageRead.icon);
// 设置主窗体的关闭和退出
pf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示主窗体
pf.setVisible(true);
// 主窗体不可拉伸
pf.setResizable(false);
}
}
⑾PlaneWars(最后一个类,也是最重要的一个类)
package com.PlaneWars;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PlaneWars extends JPanel implements KeyListener {
/**
1、简单描述就是:迭代器遍历元素的时候,
通过集合是不能修改元素的。
2、游戏暂停需要重新请求焦点。
3、每一判断碰撞之后需要跳出循环,继续回到上一次碰撞的地方判断
*/
private static final long serialVersionUID = 1L;
// 指定按键的初始状态
private boolean up, down, left, right, VK_Z, VK_X, VK_ENTER = false;
// 开始状态
private int state = START;
// 设置游戏的各种状态的值
private static int START = 0;
private static int RUNNING = 1;
private static int PAUSE = 2;
private static int GAME_OVER = 3;
// 时间初始化
private int time = 0;
// 背景的连续移动初始值
private int backgroundmove = 0;
// 记录英雄机的分数
private int score = 0;
// 设置游戏的关数的初始值
private int stage = 0;
// 导弹的初始数量
private int bomb = 10;
// 英雄机的初始血量
private int life = 20;
// 用于产生随机数,敌机的初始X坐标
Random r = new Random();
// 背景音乐,爆炸 导弹 子弹音效
private AudioClip bgmusic;
private AudioClip blastmusic;
private AudioClip bombmusic;
private AudioClip bulletmusic;
// 分数 炸弹 生命 关卡标签
private JLabel scorelabel;
private JLabel bomblabel;
private JLabel lifelabel;
private JLabel pointlabel;
// 使用集合保存所有对象
private Hero hero;
private Gift gift;
private List blast = new ArrayList<>();
private List enemy1 = new ArrayList<>();
private List enemy2 = new ArrayList<>();
private List enemy3 = new ArrayList<>();
private List enemybullet = new ArrayList<>();
private List herobullet = new ArrayList<>();
public PlaneWars() {
URL u1 = PlaneWars.class.getResource("/bgmusic.wav");
URL u2 = PlaneWars.class.getResource("/blastmusic.wav");
URL u3 = PlaneWars.class.getResource("/Bomb.wav");
URL u4 = PlaneWars.class.getResource("/bulletmusic.wav");
bgmusic = Applet.newAudioClip(u1);
blastmusic = Applet.newAudioClip(u2);
bombmusic = Applet.newAudioClip(u3);
bulletmusic = Applet.newAudioClip(u4);
// 初始化面板
board();
// 使用线程
Thread game = new Thread() {
public void run() {
// 背景音乐的循环播放
bgmusic.loop();
while (true) {
/*
* 英雄机的移动,moving()方法需要写在外面。 因为刚开始需要控制键盘enter键。
* 使用到线程,使state变为RUNNING
*/
moving();
if (state == RUNNING && stage == 1) {
// 控制关卡的分数
if (score > 5000) {
stage = 2;
pointlabel.setText("第二关");
}
// 敌机的移动
enemymoving(time);
// 英雄机子弹的移动
herobulletmoving(time);
// 敌机子弹的移动
enemybulletmoving(time);
// 生成敌机
enemy(time);
// 生成敌机子弹
enemyfire(time);
// 英雄机子弹和敌机碰撞
collision(time);
// 敌机子弹和英雄机碰撞
crash(time);
// 礼物和英雄机的碰撞
giftcrash(time);
// 时间的递增
time += 40;
try {
Thread.sleep(40);
} catch (Exception e) {
e.printStackTrace();
}
}
// 第二关(把所有方法执行两次)
if (state == RUNNING && stage == 2) {
// 敌机的移动
enemymoving(time);
enemymoving(time);
// 英雄机子弹的移动
herobulletmoving(time);
herobulletmoving(time);
// 敌机子弹的移动
enemybulletmoving(time);
enemybulletmoving(time);
// 生成敌机
enemy(time);
enemy(time);
// 生成敌机子弹
enemyfire(time);
enemyfire(time);
// 英雄机子弹和敌机
collision(time);
collision(time);
// 敌机子弹和英雄机
crash(time);
crash(time);
// 礼物和英雄机的碰撞
giftcrash(time);
giftcrash(time);
// 时间的递增
time += 40;
try {
Thread.sleep(40);
} catch (Exception e) {
e.printStackTrace();
}
}
repaint();
}
}
// 飞机移动和操作
public void moving() {
if (up) {
hero.MoveUp();
}
if (down) {
hero.MoveDown();
}
if (left) {
hero.MoveLeft();
}
if (right) {
hero.MoveRight();
}
if (VK_Z && bomb > 0) {
// 播放爆炸音效
bombmusic.play();
bomb--;
// 全屏爆炸的效果
int l1 = enemy1.size();
int l2 = enemy2.size();
int l3 = enemy3.size();
for (int i = 0; i < l1; i++) {
for (int j = 0; j < l2; j++) {
for (int k = 0; k < l3; k++) {
Blast blast1 = new Blast(enemy1.get(i).x,
enemy1.get(i).y);
Blast blast2 = new Blast(enemy2.get(j).x,
enemy2.get(j).y);
Blast blast3 = new Blast(enemy3.get(k).x,
enemy3.get(k).y);
blast.add(blast1);
blast.add(blast2);
blast.add(blast3);
l1--;
l2--;
l3--;
break;
}
}
}
// 加上全屏敌机的分数
score += (1 * enemy1.size() + 2 * enemy2.size() + 3 * enemy3
.size());
// 敌机集合清空
enemy1.clear();
enemy2.clear();
enemy3.clear();
// 敌机子弹清空
enemybullet.clear();
scorelabel.setText("分数:" + score);
// 刷新显示炸弹数
bomblabel.setText("炸弹" + bomb);
}
if (VK_X) {
// 生成英雄机子弹对象
Herobullet herofire = hero.Herofire();
// 控制子弹的生成速度
if (time % 200 == 0) {
bulletmusic.play();
herobullet.add(herofire);
}
}
if (VK_ENTER) {
// 判断游戏的是否为初始状态
if (state == START && stage == 0) {
state = RUNNING;
stage = 1;
}else if(state == GAME_OVER){
state=RUNNING;
Restart();
}
}
}
//从新开始游戏
public void Restart(){
//所有对象集合初始化
herobullet.clear();
enemy1.clear();
enemy2.clear();
enemy3.clear();
enemybullet.clear();
state=1;
score=0;
life=20;
bomb=10;
//初始化面板
board();
}
// 敌机和英雄子弹子弹碰撞的方法
public void collision(long time) {
// 英雄机子弹集合的长度
int l1 = herobullet.size();
// A敌机集合的长度
int l2 = enemy1.size();
// B敌机集合的长度
int l3 = enemy2.size();
// C敌机集合的长度
int l4 = enemy3.size();
// 遍历A敌机和子弹集合
for (int i = 0; i < l1; i++) {
for (int j = 0; j < l2; j++) {
if (Flyer.boom(herobullet.get(i), enemy1.get(j))) {
// 一旦碰撞就开始播放爆炸音效
blastmusic.play();
Herobullet hb = herobullet.get(i);
Blast blast4 = new Blast(hb.x, hb.y);
// 加入爆炸对象集合
blast.add(blast4);
// 一旦碰撞,移除当前位置的英雄机子弹和敌机
herobullet.remove(herobullet.get(i));
enemy1.remove(enemy1.get(j));
score += 20;
scorelabel.setText("分数:" + score);
// 创建爆炸图效果
// 敌机和子弹集合的长度分别减1
l1--;
l2--;
// 返回上一次当前位置继续监测
i--;
j--;
// 一旦碰撞,跳出循环
break;
}
}
}
// 遍历B敌机和子弹集合
for (int i = 0; i < l1; i++) {
for (int j = 0; j < l3; j++) {
// 如果碰撞
if (Flyer.boom(herobullet.get(i), enemy2.get(j))) {
// 一旦碰撞就开始播放爆炸音效
blastmusic.play();
// 创建爆炸图效果
Herobullet hb = herobullet.get(i);
Blast blast1 = new Blast(hb.x, hb.y);
// 加入爆炸对象集合
blast.add(blast1);
// 一旦碰撞,移除当前位置的英雄机子弹和敌机
herobullet.remove(herobullet.get(i));
enemy2.remove(enemy2.get(j));
score += 30;
scorelabel.setText("分数:" + score);
// 敌机和子弹集合的长度分别减1
l1--;
l3--;
// 返回上一次当前位置继续监测
i--;
j--;
// 一旦碰撞,跳出循环
break;
}
}
}
// 遍历C敌机和子弹集合
for (int i = 0; i < l1; i++) {
for (int j = 0; j < l4; j++) {
if (Flyer.boom(herobullet.get(i), enemy3.get(j))) {
// 一旦碰撞就开始播放爆炸音效
blastmusic.play();
score += 50;
scorelabel.setText("分数:" + score);
// 创建爆炸图效果
Herobullet hb = herobullet.get(i);
Blast blast1 = new Blast(hb.x, hb.y);
// 加入爆炸对象集合
blast.add(blast1);
// 一旦碰撞,移除当前位置的英雄机子弹和敌机
herobullet.remove(herobullet.get(i));
enemy3.remove(enemy3.get(j));
// 敌机和子弹集合的长度分别减1
l1--;
l4--;
// 返回上一次当前位置继续监测
i--;
j--;
// 一旦碰撞,跳出循环
break;
}
}
}
}
// 判断礼物和英雄机碰撞的方法
public void giftcrash(long time) {
// 如果碰撞
if (Flyer.boom(hero, gift)) {
// 礼物初始化
gift = new Gift(0, 0);
// 获得礼物可能加生命,可能加导弹
if (r.nextInt(2) == 1) {
// 导弹个数不能大于5个
if (bomb > 5) {
bomb = 5;
// 不能小于0个
} else {
// 每次导弹加一颗
bomb++;
}
} else {
// 生命值不能大于20点
if (life > 20) {
life = 20;
} else {
// 每次生命值回复2点
life += 2;
}
}
lifelabel.setText("生命:" + life);
bomblabel.setText("导弹:" + bomb);
}
}
// 敌机子弹和英雄机的碰撞方法
public void crash(long time) {
int l3 = enemybullet.size();
for (int i = 0; i < l3; i++) {
if (Flyer.boom(enemybullet.get(i), hero)) {
enemybullet.remove(enemybullet.get(i));
life--;
lifelabel.setText("生命:" + life);
// 如果生命减少到0,游戏结束
if (life <= 0) {
state = GAME_OVER;
}
l3--;
i--;
break;
}
}
}
// 敌机移动
public void enemymoving(long time) {
for (int i = 0; i < enemy1.size(); i++) {
enemy1.get(i).move(time);
}
for (int i = 0; i < enemy2.size(); i++) {
enemy2.get(i).move(time);
}
for (int i = 0; i < enemy3.size(); i++) {
enemy3.get(i).move(time);
}
gift.move(time);
}
public void herobulletmoving(long time) {
for (int i = 0; i < herobullet.size(); i++) {
herobullet.get(i).move(time);
}
}
public void enemybulletmoving(long time) {
for (int i = 0; i < enemybullet.size(); i++) {
enemybullet.get(i).move(time);
}
}
public void enemyfire(long time) {
// 敌机A发射子弹
if (time % 2000 == 0) {
for (int i = 0; i < enemy1.size(); i++) {
Enemybullet b = enemy1.get(i).enemyfire();
enemybullet.add(b);
}
}
// 敌机B发射子弹
if (time % 3000 == 0) {
for (int i = 0; i < enemy2.size(); i++) {
Enemybullet b = enemy2.get(i).enemyfire();
enemybullet.add(b);
}
}
// 敌机C发射子弹
if (time % 4000 == 0) {
for (int i = 0; i < enemy3.size(); i++) {
Enemybullet b = enemy3.get(i).enemyfire();
enemybullet.add(b);
}
}
}
public void enemy(long time) {
// 生成敌机1的时间
if (time % 600 == 0) {
Enemy1 e = new Enemy1(r.nextInt(450), 0);
enemy1.add(e);
}
// 生成敌机2的时间
if (time % 400 == 0) {
Enemy2 e = new Enemy2(r.nextInt(450), 0);
enemy2.add(e);
}
// 生成礼物的时间
if (score != 0 && score % 1000 == 0) {
gift = new Gift(r.nextInt(450), 0);
}
// 生成敌机3的时间
if (time % 800 == 0) {
Enemy3 e = new Enemy3(r.nextInt(450), 0);
enemy3.add(e);
}
}
};
// 启动线程
game.start();
}
/*
* 连续背景的绘制
*/
protected void paintComponent(Graphics g) {
super.paintComponent(g);
try {
BufferedImage image;
if (backgroundmove > 600) {
backgroundmove = 0;
}
image = ImageIO.read(new FileInputStream("./素材/Maps/map3.jpg"));// 加载背景
g.drawImage(image, 0, backgroundmove, 600, 800, null);
backgroundmove += 1;
g.drawImage(image, 0, -600 + backgroundmove, 600, 800, null); // 使得背景是持续的
} catch (IOException e) {
e.printStackTrace();
}
}
// 分数、炸弹、生命面板
public void board() {
// 清除容器内所有内容
this.removeAll();
this.addKeyListener(this);
// 初始化礼物对象
gift = new Gift(0, 0);
// 关卡标签
pointlabel = new JLabel("第一关");
pointlabel.setForeground(Color.green);
Font font = new Font("黑体", Font.PLAIN, 20);
pointlabel.setFont(font);
// 分数标签
scorelabel = new JLabel("分数:" + score);
// 设置背景颜色
scorelabel.setForeground(Color.RED);
// 炸弹标签
bomblabel = new JLabel("导弹:" + bomb);
bomblabel.setForeground(Color.RED);
// 生命标签
lifelabel = new JLabel("生命:" + life);
lifelabel.setForeground(Color.RED);
// 游戏继续按钮
final JButton gameon = new JButton("继续");
gameon.setForeground(Color.RED);
// 设置按钮为透明
gameon.setContentAreaFilled(false);
// 游戏暂停按钮
JButton gamestop = new JButton("暂停");
gamestop.setForeground(Color.RED);
gamestop.setContentAreaFilled(false);
// 继续按钮添加监听
gameon.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (state == PAUSE) {
state = RUNNING;
/*
* 重新使JPanel成为焦点!一定需要从新请求焦点。不然暂停一次键盘就直接失灵了
*/
PlaneWars.this.requestFocusInWindow();
}
}
});
// 暂停按钮添加监听
gamestop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (state == RUNNING) {
state = PAUSE;
}
}
});
// 新建一个面板,把按钮和标签都加入到面板中间
JPanel jp = new JPanel();
// 设置背景颜色为黑色
jp.setBackground(Color.BLACK);
// 使用浮动布局管理器
jp.setLayout(new FlowLayout(FlowLayout.LEADING, 30, 10));
jp.add(pointlabel);
jp.add(bomblabel);
jp.add(scorelabel);
jp.add(lifelabel);
jp.add(gameon);
jp.add(gamestop);
// JPanel 面板添加这个面板
this.add(jp);
// 英雄机的初始位置
hero = new Hero(230, 600);
}
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
// 如果为初始状态
if (state == START) {
paintstart(g);
// 如果为游戏运行状态
} else if (state == RUNNING) {
// 绘制英雄机
painthero(g);
// 绘制敌机
paintenemy(g);
// 绘制一组敌机子弹
paintenemybullets(g);
// 绘制英雄机子弹
paintherobullets(g);
// 绘制爆炸效果和移除爆炸效果
paintblast(g);
// 绘制礼物
paintgift(g);
} else if (state == PAUSE) {
g.setFont(new Font("黑体", Font.BOLD, 50));
g.setColor(Color.RED);
g.drawString("游戏暂停!!!", 120, 330);
}
// 如果为游戏结束状态
else if (state == GAME_OVER) {
paintover(g);
}
}
// 该方法为绘制游戏结束界面
public void paintover(Graphics g) {
g.drawImage(ImageRead.b1, 0, 0, 500, 800, null);
g.drawImage(ImageRead.b2, 0, 0, 500, 150, null);
Font font1 = new Font("黑体", Font.ITALIC, 60);
Font font2 = new Font("黑体", Font.PLAIN, 30);
g.setColor(Color.RED);
g.setFont(font1);
g.drawString("GAME OVER", 100, 300);
g.setFont(font2);
g.drawString("score:" + score + "---你已经很棒啦!", 80, 400);
g.setFont(font2);
g.drawString("按ENTER键从新开始游戏", 100, 500);
}
// 该方法为绘制初始界面
public void paintstart(Graphics g) {
g.drawImage(ImageRead.b1, 0, 0, 500, 800, null);
g.drawImage(ImageRead.b2, 0, 0, 500, 150, null);
g.drawImage(ImageRead.b3, 50, 200, null);
g.drawImage(ImageRead.b4, 150, 200, 300, 400, null);
Font font = new Font("黑体", Font.PLAIN, 20);
g.setColor(Color.RED);
g.setFont(font);
g.drawString("按ENTER键开始游戏", 50, 500);
g.drawString("X:控制子弹,Z:控制超级武器", 50, 550);
g.drawString("方向键:↑,↓,←,→", 50, 600);
g.drawString("作者:poc999", 50, 650);
}
// 绘制礼物
public void paintgift(Graphics g) {
// 因为礼物的初始位置为坐标为0和0,
if (gift.x != 0 && gift.y != 0) {
g.drawImage(ImageRead.gift, gift.x, gift.y, 20, 20, null);
}
}
// 绘制英雄机
public void painthero(Graphics g) {
g.drawImage(ImageRead.hero, hero.x, hero.y, 60, 60, null);
}
// 绘制爆炸图
public void paintblast(Graphics g) {
int l3 = blast.size();
for (int i = 0; i < l3; i++) {
Blast b = blast.get(i);
// 绘制之后立即移除
b.draw(g);
blast.remove(b);
l3--;
i--;
break;
}
}
// 绘制所有敌机
public void paintenemy(Graphics g) {
for (int i = 0; i < enemy1.size(); i++) {
Enemy1 e = enemy1.get(i);
e.draw(g);
}
for (int i = 0; i < enemy2.size(); i++) {
Enemy2 e = enemy2.get(i);
e.draw(g);
}
for (int i = 0; i < enemy3.size(); i++) {
Enemy3 e = enemy3.get(i);
e.draw(g);
}
}
// 绘制A类敌机子弹
public void paintenemybullets(Graphics g) {
for (int i = 0; i < enemybullet.size(); i++) {
Enemybullet eb = enemybullet.get(i);
eb.draw(g);
}
}
// 绘制英雄机子弹
public void paintherobullets(Graphics g) {
for (int i = 0; i < herobullet.size(); i++) {
Herobullet hb = herobullet.get(i);
hb.draw(g);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
// 键盘按下
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
up = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_RIGHT:
right = true;
break;
case KeyEvent.VK_Z:
VK_Z = true;
break;
case KeyEvent.VK_X:
VK_X = true;
break;
case KeyEvent.VK_ENTER:
VK_ENTER = true;
break;
default:
break;
}
repaint();
}
// 键盘释放
@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
up = false;
break;
case KeyEvent.VK_DOWN:
down = false;
break;
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_RIGHT:
right = false;
break;
case KeyEvent.VK_Z:
VK_Z = false;
break;
case KeyEvent.VK_X:
VK_X = false;
break;
case KeyEvent.VK_ENTER:
VK_ENTER = false;
break;
default:
break;
}
}
}
资源下载地址:http://download.csdn.net/detail/weixin_38179324/9913390