玩家的飞机最初出现在底部中央,通过方向键控制飞机移动,通过空格键发射子弹。当玩家的飞机被击中时,飞机将重新回到底部中央,同时更换为可以发射两发子弹的飞机,当玩家被击中三次时,游戏结束。同时,飞机共有两组,若期间玩家的飞机都未被击中,则玩家获得胜利。
控制游戏的循环和面板的刷新,当在checkEvent中达到一定条件时更改stop_flag标志,结束游戏的循环
import javax.swing.*;
import java.awt.*;
import static java.lang.Thread.sleep;
public class GamePlay {
public static boolean stop_flag = false;//为true时游戏结束
public static boolean pause_flag = false;//为true时游戏暂停
private static int choose;
public static void main(String[] args) {
JFrame frame = new gameFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//控制游戏重新开始的循环
do {
//控制游戏结束的循环
while (!stop_flag) {
try {
sleep(5);//让线程暂停一短时间,以免游戏元素的位置刷新过快
} catch (InterruptedException e) {
}
if (!pause_flag) {
frame.getContentPane().repaint();
}
}
if(Plane.life_num==0)
choose=JOptionPane.showConfirmDialog(null,"是否重新开始:",
"你的生命数已经用尽",JOptionPane.YES_NO_OPTION);
else
choose=JOptionPane.showConfirmDialog(null,"是否重新开始:",
"恭喜你!通关了!",JOptionPane.YES_NO_OPTION);
if(choose==JOptionPane.YES_OPTION) {
stop_flag = false;
frame.dispose();
//重新游戏时初始化其中有意义的静态常量
Plane.count=1;
Enemy.enemy_group=1;
Plane.life_num=3;
enhanceElement.elementCatch=0;
frame=new gameFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}while(choose==JOptionPane.YES_OPTION);
}
}
作为一个游戏框架容器,用来添加菜单栏,相应的菜单和菜单项和游戏面板类。其中,菜单栏提供一些游戏属性的设置,游戏的说明等内容
import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import sun.audio.ContinuousAudioDataStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.InputStream;
class gameFrame extends JFrame {
public final static int WIDTH = 1200;
public final static int HEIGHT = 1000;
public static gamePanel panel;
JMenuBar menuBar;//声明一个菜单栏对象
JMenu menu, help, music,plane_choose;//声明菜单对象
JMenuItem plane_speed, enemy_speed,bullet_speed, exit, help1, about;//声明菜单项对象
JMenuItem plane1,plane2,plane3,plane4;
JRadioButtonMenuItem on, off;//复选框,将其加入JCheckBoxGroup()以实现单选
boolean music_flag = true;//控制音乐开关标记
InputStream in;//音频文件输入流
AudioStream audioStream;
Toolkit toolkit=Toolkit.getDefaultToolkit();
public gameFrame() {
//设置frame的大小,图标,标题
super("Plane::War");
//Dimension screenSize=toolkit.getScreenSize();
setSize(WIDTH, HEIGHT);
Image plane = new ImageIcon("image/plane3.png").getImage();
setIconImage(plane);
menuBar = new JMenuBar();
setJMenuBar(menuBar);
menu = new JMenu("菜单");
help = new JMenu("帮助");
music = new JMenu("音乐");
plane_choose=new JMenu("选择飞机");
plane_speed = new JMenuItem("飞机速度");
enemy_speed = new JMenuItem("敌机速度");
bullet_speed=new JMenuItem("子弹速度");
exit = new JMenuItem("退出");
help1 = new JMenuItem("帮助");
about = new JMenuItem("关于");
//存储飞机图像的菜单项
plane1=new JMenuItem(new ImageIcon("image/plane1.png"));
plane2=new JMenuItem(new ImageIcon("image/plane2.png"));
plane3=new JMenuItem(new ImageIcon("image/plane3.png"));
plane4=new JMenuItem(new ImageIcon("image/plane4.png"));
on = new JRadioButtonMenuItem("开", true);
off = new JRadioButtonMenuItem("关", false);
ButtonGroup group = new ButtonGroup();
group.add(on);
group.add(off);
music.add(on);
music.add(off);
menuBar.add(menu);
menuBar.add(help);
menuBar.add(plane_choose);
menu.add(plane_speed);
menu.add(enemy_speed);
menu.add(bullet_speed);
menu.add(music);
menu.add(exit);
help.add(help1);
help.add(about);
plane_choose.add(plane1);
plane_choose.add(plane2);
plane_choose.add(plane3);
plane_choose.add(plane4);
MenuItemListener listener = new MenuItemListener();//菜单项监听器
//为每个菜单项添加监听器
plane_speed.addActionListener(listener);
enemy_speed.addActionListener(listener);
bullet_speed.addActionListener(listener);
exit.addActionListener(listener);
help1.addActionListener(listener);
about.addActionListener(listener);
plane1.addActionListener(listener);
plane2.addActionListener(listener);
plane3.addActionListener(listener);
plane4.addActionListener(listener);
RadioButtonListener btnlistener = new RadioButtonListener();
on.addActionListener(btnlistener);
off.addActionListener(btnlistener);
try {
in = new FileInputStream("music/dragon rider.wav");
audioStream = new AudioStream(in);
} catch (Exception e) {
e.printStackTrace();
}
if (music_flag) {
AudioPlayer.player.start(audioStream);
}
panel = new gamePanel();
panel.setFocusable(true);//设置panel获得焦点事件
getContentPane().add(panel);
setVisible(true);
}
/*
内部动作监听类
实现对菜单项动作的监听
可以实现选择飞机,更改飞机速度,敌机速度,玩家子弹速度,还包括游戏说明
*/
private class MenuItemListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//游戏暂停标志
GamePlay.pause_flag=true;
JMenuItem source = (JMenuItem) e.getSource();
if (source == plane_speed) {
String msg = JOptionPane.showInputDialog(null,
"请输入飞机速度:(整数,初始速度为4)", null);
Plane.speed = Integer.parseInt(msg);
} else if (source == enemy_speed) {
String msg = JOptionPane.showInputDialog(null,
"请输入敌机速度:(整数,初始速度为1)", null);
Enemy.speed = Integer.parseInt(msg);
}else if(source==bullet_speed){
String msg = JOptionPane.showInputDialog(null,
"请输入玩家子弹速度:(整数,初始速度为5)", null);
Bullets.speed = Integer.parseInt(msg);
}else if(source==help1){
JOptionPane.showMessageDialog(null,
"本游戏中玩家通过方向键控制飞机上下左右移动,通过空格键发射子弹。"+
"\n玩家的飞机共有三次生命,期间可以通过吃到增强道具来强化能力。"+
"\n增强道具有两种,分别为发射两发子弹,子弹大小加倍。");
}else if(source==about){
JOptionPane.showMessageDialog(null,
"Plane::War" + "\n" + "2018级***");
}else if(source==exit){
System.exit(0);
}else if(source==plane1){
Plane.count=1;
panel.plane=new Plane();
}else if(source==plane2){
Plane.count=2;
panel.plane=new Plane();
}else if(source==plane3){
Plane.count=3;
panel.plane=new Plane();
}else if(source==plane4){
Plane.count=4;
panel.plane=new Plane();
}
GamePlay.pause_flag=false;
//gameFrame.this.notifyAll();
}
}
//对单选按钮的监听
private class RadioButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JRadioButtonMenuItem source = (JRadioButtonMenuItem) e.getSource();
if (source == on) {
music_flag = true;
AudioPlayer.player.start(audioStream);
} else {
music_flag = false;
AudioPlayer.player.stop(audioStream);
}
}
}
}
作为游戏的主面板,用于添加飞机,敌机,飞机子弹,敌机子弹等游戏元素,同时完成对这些元素在指定位置的绘制,这个类同时创建好两个标签game_stop和game_win,并在其中添加图片。当玩家被击中三次时,将game_stop标签加入面板,当玩家获胜时将game_win标签加入面板。同时包含一个处理键盘事件的内部类,用于控制玩家飞机的移动。
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Random;
class gamePanel extends JPanel {
public Plane plane;
public ArrayList bulletlist;
public ArrayList enemylist;
public ArrayList enemybulletlist;
public ArrayList elementlist=new ArrayList();
private checkEvent checkevent;
public static JLabel game_stop=new JLabel(new ImageIcon("image/over.png"));
public static JLabel game_win=new JLabel(new ImageIcon("image/game_win.png"));
public boolean shot_flag=false;
public gamePanel() {
//在创建游戏面板时创建飞机对象,敌机对象,子弹对象
plane = new Plane();
enemylist = new ArrayList();
bulletlist = new ArrayList();
enemybulletlist=Enemy.enemybulletlist;
//在创建面板对象时,同时创建敌机对象,
for (int i = 0; i < 20; i++)
enemylist.add(new Enemy(i));
checkevent = new checkEvent(plane, enemylist, bulletlist,enemybulletlist,elementlist,this);
//添加键盘事件接口
myKeyAdapter keyadapter = new myKeyAdapter();
addKeyListener(keyadapter);
setVisible(true);
}
//绘制panel背景
public void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon image=new ImageIcon("image/background"+Enemy.enemy_group+".jpg");
g.drawImage(image.getImage(),0,0,this.getWidth(),this.getHeight(),null);
}
public void paint(Graphics g) {
super.paint(g);
checkevent.check();
//绘制飞机对象
Plane.updatePosition();
g.drawImage(plane.getPlane(), plane.getX(), plane.getY(), this);
enhanceElement.updatePosition(elementlist);
for(int i=0;i<elementlist.size();i++){
enhanceElement temp=(enhanceElement) elementlist.get(i);
g.drawImage(temp.element,temp.x,temp.y,temp.element_width,temp.element_height,this);
}
/*
先绘制玩家子弹对象,通过玩家子弹的color属性设置画笔设置画笔颜色,
以实现对敌机子弹对象的更改,实现彩色子弹
*/
//绘制子弹对象
Bullets.updatePosition(bulletlist);
for (int i = 0; i < bulletlist.size(); i++) {
Bullets bullet = (Bullets) bulletlist.get(i);
g.setColor(bullet.color);
g.fillOval(bullet.getX(), bullet.getY(), bullet.width, bullet.height);
//System.out.println(bulletlist.size());
}
//绘制敌机子弹对象
EnemyBullet.updatePosition(enemybulletlist);
for(int i=0;i<enemybulletlist.size();i++){
EnemyBullet enemyBullet=(EnemyBullet) enemybulletlist.get(i);
g.fillOval(enemyBullet.getX(),enemyBullet.getY(),enemyBullet.width,enemyBullet.height);
}
Enemy.updatePostion(enemylist);
for (int i = 0; i < enemylist.size(); i++) {
Enemy enemy = (Enemy) enemylist.get(i);
g.drawImage(enemy.getImage(), enemy.getX(), enemy.getY(), Enemy.enemy_width, Enemy.enemy_height, this);
}
}
//内部类,实现对键盘事件的响应,控制飞机的移动及子弹的添加
private class myKeyAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
//plane.moveup();
Plane.up_flag=true;
} //按压上键
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
//plane.movedown();
Plane.down_flag=true;
} //按压下键
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
//plane.moveleft();
Plane.left_flag=true;
} //按压左键
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
//plane.moveright();
Plane.right_flag=true;
} //按压右键
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
//创建子弹时,将其初始位置设置为飞船上面中间的坐标
try {
AudioPlayer.player.start(new AudioStream(new FileInputStream("music/shot.wav")));
} catch (Exception e1) {
e1.printStackTrace();
}
if(enhanceElement.elementCatch==2){
bulletlist.add(new Bullets(plane.getX() + plane.plane_width / 2 - Bullets.width / 2, plane.getY()));
}
if(enhanceElement.elementCatch==1){
//Bullets.width=30;
//Bullets.height=30;
bulletlist.add(new Bullets(plane.getX() + plane.plane_width / 2 - Bullets.width / 2-30, plane.getY()));
bulletlist.add(new Bullets(plane.getX() + plane.plane_width / 2 - Bullets.width / 2+30, plane.getY()));
}
else
bulletlist.add(new Bullets(plane.getX() + plane.plane_width / 2 - Bullets.width / 2, plane.getY()));
}
repaint();
}
public void keyReleased(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_UP) {
//plane.moveup();
Plane.up_flag=false;
} //按压上键
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
//plane.movedown();
Plane.down_flag=false;
} //按压下键
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
//plane.moveleft();
Plane.left_flag=false;
} //按压左键
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
//plane.moveright();
Plane.right_flag=false;
}//按压右键
repaint();
}
}
}
用于创建玩家飞机的类,主要包含坐标,飞机图像,飞机速度,图像的宽度和高度等属性。根据面向对象的原则,在Plane类中还包括对飞机位置更新的方法。
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.IOException;
public class Plane {
public static int x,y;//飞机坐标
private static final int panel_width=gameFrame.WIDTH-22;//获取panel的高度宽度(22,81为与frame的差额)
private static final int panel_height=gameFrame.HEIGHT-81;
public static int plane_width,plane_height;//存储飞机宽度和高度的静态变量
private Image plane;
public static int speed=4;
public static int count=1;//加载飞机图像标记
public static int life_num=3;//生命数量
public static boolean up_flag=false;
public static boolean down_flag=false;
public static boolean left_flag=false;
public static boolean right_flag=false;
public Plane(){
try{
plane= ImageIO.read(new File("image/plane"+count+".png"));
plane_width=plane.getWidth(null);
plane_height=plane.getHeight(null);
}
catch(IOException e){System.out.println(e.toString());}
//将飞船坐标设为底部中央
x=panel_width/2-plane_width/2;
y=panel_height-plane_height;
}
//获取飞船的private属性
public int getX(){return x;}
public int getY(){return y;}
public Image getPlane(){return plane;}
/*
位置更新静态方法,通过类名在paint中调用,当相关属性为真时控制玩家飞机的移动
*/
public static void updatePosition(){
if(up_flag&&y>0)
y=y-speed;
if(down_flag&&(y+plane_height)<panel_height)
y=y+speed;
if(left_flag&&x>0)
x=x-speed;
if(right_flag&&(x+plane_width)<panel_width)
x=x+speed;
}
public void moveup(){
if(y>0)
y=y-speed;
}
public void movedown(){
if((y+plane_height)<panel_height)
y=y+speed;
}
public void moveleft(){
if(x>0)
x=x-speed;
}
public void moveright(){
if((x+plane_width)<panel_width)
x=x+speed;
}
}
用于创建玩家飞机发射子弹的对象,也是属于Plane类的属性,不过作为一个独立的类会更容易操作和设置。同时,由于子弹对象的创建是由于gamePanel中处理键盘事件来创建。所以,将其作为一个独立类。主要包括坐标,子弹的宽度和高度,速度等属性。
import java.awt.*;
import java.util.ArrayList;
import java.util.Random;
public class Bullets {
private int x,y;//子弹的坐标
public static int width=15,height=15;//子弹大小常量
public static int speed=5;//子弹速度
public final Color color;
public Bullets(int x,int y){
//如果捕获到第二种增强道具,子弹大小加倍,否则将子弹大小重置为默认大小
if(enhanceElement.elementCatch==2){
width=30;
height=30;
}else{
width=15;
height=15;
}
this.x=x;
this.y=y;
//此处实现对每个子弹颜色的设置
Random rand=new Random();
color=new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));
}
//玩家飞机子弹位置的更新及边界检测
public static void updatePosition(ArrayList bulletlist){
for(int i=0;i<bulletlist.size();i++){
Bullets bullet=(Bullets) bulletlist.get(i);
if(bullet.y<0)
bulletlist.remove(i);
else
bullet.y-=speed;
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
用于创建敌机对象,主要包括坐标,敌机宽度高度,速度,move_count(记录敌机移动次数,到达一定次数后发射子弹,每个对象都有这个属性),enemy_group(用于记录敌机编组,依据此属性来选择加载敌机的图像,飞机位置的设置及飞机运动模式的选择)。在此类中有updatePosition方法,它依据enemy_group属性来更新敌机编组的位置。同时,由于敌机子弹是基于move_count属性来设置,所以在此类中包含子弹这一属性,表现为用动态数组来存储EnemyBullet对象。
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class Enemy {
private Image enemy;//enemy图像
public int x, y;//enemy坐标
public static int enemy_width = 34, enemy_height = 24;//敌机宽度,高度静态常量
static int panel_width = gameFrame.WIDTH - 22;
static int panel_height = gameFrame.HEIGHT - 81;
public static int speed = 1;
Toolkit toolkit = Toolkit.getDefaultToolkit();
private boolean flag;
//敌机移动标记,true向下移动,false向上移动,第一种运动模式标记,第二种运动模式中作为开始随机移动的标记
private int move_count;
private int t;
public static ArrayList enemybulletlist=new ArrayList();//所有敌机共用一个敌机子弹动态数组
public static int enemy_group=1;//根据enemy_group来加载图像和设置位置,更新位置
public Enemy(int i) {
try{enemy= ImageIO.read(new File("image/enemy"+enemy_group+".png"));}
catch(IIOException e){e.printStackTrace();}
catch (IOException e){System.out.println(e.getMessage());}
enemy_width=enemy.getWidth(null);
enemy_height=enemy.getHeight(null);
//根据i完成对飞机初始位置的设置,i为在动态数组中的位置
if (enemy_group == 1) {
x = panel_width + 2 * enemy_width * (i - 1);
y = panel_height / 5 - 2 * enemy_height * (i - 1);
//enemy = toolkit.getImage("image/enemy1.jpg");
flag = true;
move_count=0;
}
if (enemy_group == 2) {
//enemy = toolkit.getImage("image/enemy1.jpg");
//System.out.println(enemy.getHeight(null));
//enemy_width = 46;
//enemy_height = 60;
flag = false;
x = 3 * enemy_width * (-i);
y = panel_height / 3;
move_count = 0;
}
}
//更新敌机位置,mark标志敌机之后的运动轨迹
public static void updatePostion(ArrayList enemylist) {
//System.out.println(enemylist.size());检测越界的敌机是否移出动态数组
if (enemy_group == 1) {
for (int i = 0; i < enemylist.size(); i++) {
Enemy temp = (Enemy) enemylist.get(i);
//判断敌机位置
if (temp.y < panel_height / 6)
temp.flag = true;
if (temp.y > panel_height / 3)
temp.flag = false;
/*
飞机最初在右边界
控制敌机在gamePanel的高度1/6至1/3处移动
当到达左边界时以3倍速度向下移动
当到达下边界时删除这个敌机对象
*/
if (temp.y > panel_height) {
enemylist.remove(i);
//System.out.println(enemylist.size());
}
if (temp.x < 0)
temp.y += 3 * speed;
else if (temp.flag) {
temp.x -= speed;
temp.y += speed;
} else {
temp.x -= speed;
temp.y -= speed;
}
temp.move_count++;
//此处是一个修正,让前面敌机产生子弹的频率较慢,以防止这一组敌机同时产生子弹
if(temp.move_count%((20-i)*50)==0)
enemybulletlist.add(new EnemyBullet(temp.x+enemy_width/2-EnemyBullet.width/2,temp.y+enemy_height));
}
}
if (enemy_group == 2) {
Random rand = new Random();
for (int i = 0; i < enemylist.size(); i++) {
Enemy temp = (Enemy) enemylist.get(i);
//当敌机的x移动到400处时,开始随机移动
if (temp.x > 400)
temp.flag = true;
else
temp.x += 3 * speed;
//当开始随机移动后判断是否超出边界,因为初始位置有些敌机放在外面
if (temp.flag && (temp.x < 0 || temp.x > panel_width || temp.y < 0 || temp.y > panel_height))
enemylist.remove(i);
//如果move_count为300倍数且开始随机移动,则随机生成每个敌机的属性t
if (temp.flag && temp.move_count%300== 0) {
temp.t = rand.nextInt(4);
}
/*
随机移动时,依据每个敌机的属性t决定向哪移动
当向某一方向移动300次后,重置move_count
决定下一次的移动方向
*/
if (temp.flag) {
if (temp.t == 0) {
temp.x += 2*speed;
temp.y -= speed;
} else if (temp.t == 1) {
temp.x -= speed;
temp.y -= speed;
} else if (temp.t == 2) {
temp.x -= speed;
temp.y += 2*speed;
} else {
temp.x += 2*speed;
temp.y += 2*speed;
}
temp.move_count++;
if(temp.move_count%200==0)
enemybulletlist.add(new EnemyBullet(temp.x+enemy_width/2-EnemyBullet.width,temp.y+enemy_height));
}
}
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return enemy;
}
}
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class enhanceElement {
public int x,y;
public Image element;
static int panel_width = gameFrame.WIDTH - 22;
static int panel_height = gameFrame.HEIGHT - 81;
public static int element_width,element_height;
public static int speed=1;
public int move_count;
public int t;//控制移动方向
public int elementKind;
public static int elementCatch=0;
Random rand = new Random();
public enhanceElement(){
try {
//随机选择加载增强道具
elementKind=rand.nextInt(2)+1;
element = ImageIO.read(new File("image/element"+elementKind+".png"));
element_width=element.getWidth(null);
element_height=element.getHeight(null);
} catch(IOException e){System.out.println(e.toString());}
//初始位置在屏幕中上方的随机位置
x=rand.nextInt(200)+500;
y=rand.nextInt(100);
move_count=0;
}
public static void updatePosition(ArrayList elementlist){
Random rand = new Random();
for (int i = 0; i < elementlist.size(); i++) {
enhanceElement temp = (enhanceElement) elementlist.get(i);
if ( (temp.x < 0 || temp.x > panel_width || temp.y < 0 ))
temp.t = rand.nextInt(4);
if(temp.y > panel_height)
elementlist.remove(i);
//如果move_count为300倍数且开始随机移动,则随机生成每个敌机的属性t
if ( temp.move_count%300== 0) {
temp.t = rand.nextInt(4);
}
/*
随机移动时,依据每个敌机的属性t决定向哪移动
当向某一方向移动300次后,重置move_count
决定下一次的移动方向
*/
if (temp.t == 0) {
temp.x += speed;
temp.y += speed;
} else if (temp.t == 1) {
temp.x -= 2*speed;
temp.y += speed;
} else if (temp.t == 2) {
temp.x -= speed;
temp.y += 2*speed;
} else {
temp.x += speed;
temp.y += 2*speed;
}
temp.move_count++;
}
}
}
用于创建敌机子弹对象,主要包含坐标,宽度高度,速度等属性,包含更新子弹位置的方法。
import java.util.ArrayList;
public class EnemyBullet {
private int x,y;//子弹的坐标
private final int panel_width=gameFrame.WIDTH-22;//获取panel的高度宽度(22,81为与frame的差额)
private static int panel_height=gameFrame.HEIGHT-81;
public static int width=15,height=15;//子弹大小常量
public static int speed=4;//子弹速度
public EnemyBullet(int x,int y){
this.x=x;
this.y=y;
}
public static void updatePosition(ArrayList enemybulletlist){
for(int i=0;i<enemybulletlist.size();i++){
EnemyBullet temp=(EnemyBullet) enemybulletlist.get(i);
if(temp.y>panel_height)
enemybulletlist.remove(i);
else
temp.y+=speed;
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
用于做各种碰撞检测,因此需要包括玩家飞机对象,玩家子弹对象,敌机对象,敌机子弹对象,同时还要有游戏主面板对象(在做检测时,若玩家飞机被击中,需要通过面板来重新生成飞机对象)(这里不包括边界检测,边界检查对应类的updatePosition类中来实现)。
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import java.awt.*;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Random;
import static java.lang.Thread.sleep;
public class checkEvent {
private Plane plane;
private ArrayList enemylist;
private ArrayList bulletlist;
private gamePanel panel;
private ArrayList enemybulletlist;
private ArrayList elementlist;
Random rand=new Random();
public checkEvent(Plane plane, ArrayList enemylist, ArrayList bulletlist, ArrayList enemybulletlist,ArrayList elementlist, gamePanel panel) {
this.plane = plane;
this.enemylist = enemylist;
this.bulletlist = bulletlist;
this.enemybulletlist = enemybulletlist;
this.elementlist=elementlist;
this.panel = panel;
}
/*
碰撞检测方法
玩家飞机与敌机的碰撞,玩家飞机与敌机子弹的碰撞
玩家飞机子弹与敌机的碰撞,玩家飞机与增强道具的碰撞
同时,实现增强道具的随机添加
*/
public void check() {
//捕获数组越界异常
try {
//增强道具出现频率
if(rand.nextInt(1000)==1&&elementlist.size()<2){
elementlist.add(new enhanceElement());}
//当第二组敌机从屏幕上消失时,游戏结束,玩家获胜
if (Enemy.enemy_group == 2 && enemylist.size() == 0) {
panel.add(gamePanel.game_win);
GamePlay.stop_flag = true;
//panel.repaint();
} else {
if (enemylist.size() == 0) {
Enemy.enemy_group++;
for (int i = 0; i < 50; i++)
(panel.enemylist).add(new Enemy(i));
enemylist = panel.enemylist;
}
/*
检测子弹与敌机的碰撞
先检测子弹数量,若为0,则不会与敌机碰撞
*/
for (int i = 0; i < bulletlist.size(); i++) {
for (int j = 0; j < enemylist.size(); j++) {
Enemy temp1 = (Enemy) enemylist.get(j);
Bullets temp2 = (Bullets) bulletlist.get(i);
Rectangle rect1 = new Rectangle(temp1.x, temp1.y, temp1.enemy_width, temp1.enemy_height);
Rectangle rect2 = new Rectangle(temp2.getX(), temp2.getY(), temp2.width, temp2.height);
if (rect1.intersects(rect2)) {
bulletlist.remove(i);
enemylist.remove(j);
}
}
}
/*
检测飞机与敌机的碰撞,在碰撞后休眠一段时间
*/
for (int i = 0; i < enemylist.size(); i++) {
Enemy temp1 = (Enemy) enemylist.get(i);
Rectangle rect1 = new Rectangle(temp1.x, temp1.y, temp1.enemy_width, temp1.enemy_height);
Rectangle rect3 = new Rectangle(plane.x, plane.y, plane.plane_width, plane.plane_height);
if (rect1.intersects(rect3)) {
enemylist.remove(i);
sleep(1000);
Plane.life_num--;
if (Plane.life_num <= 0) {
panel.add(gamePanel.game_stop);
GamePlay.stop_flag = true;
} else {
//飞机被碰撞后,初始化为无增强道具
enhanceElement.elementCatch=0;
panel.plane = new Plane();
plane = panel.plane;
}
}
}
/*
玩家飞机与增强道具的碰撞
*/
for(int i=0;i<elementlist.size();i++){
enhanceElement temp = (enhanceElement) elementlist.get(i);
Rectangle rect1 = new Rectangle(temp.x, temp.y, temp.element_width, temp.element_height);
Rectangle rect2 = new Rectangle(plane.x, plane.y, plane.plane_width, plane.plane_height);
if (rect1.intersects(rect2)) {
enhanceElement.elementCatch =temp.elementKind ;
try {
AudioPlayer.player.start(new AudioStream(new FileInputStream("music/pickelement.wav")));
} catch (Exception e1) {
e1.printStackTrace();
}
elementlist.remove(i);
}
}
/*
检测敌机子弹与我的飞机碰撞,在碰撞后休眠一段时间
*/
for (int i = 0; i < enemybulletlist.size(); i++) {
EnemyBullet temp = (EnemyBullet) enemybulletlist.get(i);
Rectangle rect1 = new Rectangle(temp.getX(), temp.getY(), temp.width, temp.height);
Rectangle rect2 = new Rectangle(plane.x, plane.y, plane.plane_width, plane.plane_height);
if (rect1.intersects(rect2)) {
enemybulletlist.remove(i);
sleep(1000);
Plane.life_num--;
if (Plane.life_num < 0) {
panel.add(gamePanel.game_stop);
GamePlay.stop_flag = true;
} else {
//飞机被碰撞后,初始化为无增强道具
enhanceElement.elementCatch=0;
panel.plane = new Plane();
plane = panel.plane;
}
}
}
}
} catch (IndexOutOfBoundsException e) {
System.out.println(e.toString());
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}
}