本篇博客是对飞机大战游戏使用代码的展示
重难点:
首先需要鼠标能够控制战机,使鼠标在窗口内时始终能够使战机的位置与鼠标相同,实现鼠标控制战斗机移动。
其次需要能够以一定的速度产生子弹和敌机,并且以一定的速度移动,为了实现这部分的功能,我们需要使用线程来完成。(Timer也可以实现这块功能,但过多使用Timer会使程序变得不稳定,会经常报错)JAVA 线程的介绍与使用
再然后就是判断子弹与敌机相撞,战机与敌机相撞,这就需要用到遍历,需要遍历的是场上的子弹与敌机,这就需要我们使用ArrayList来存储场上的敌机与子弹,当敌机与子弹离开画面使,便从ArrayList中移除,这样便可以保证遍历的是场上的敌机与子弹。
鼠标控制战机
class mouse1 extends MouseMotionAdapter{
@Override
public void mouseMoved(MouseEvent e) {
X=e.getX();//得到鼠标X坐标
Y=e.getY();//得到鼠标Y坐标
jl2.setLocation(X-30, Y-35);
//战机根据鼠标设置位置
//通过监听器,只要鼠标移动就执行,
//图片根据显示效果更改坐标值
}
}
子弹与敌机的产生
//敌机生成(线程代码)
class enemyCreate extends Thread{
public void run() {
while(true) {
try {
this.sleep(1000);//1000毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageIcon image_enemy=new ImageIcon("game_image/enemy.png");//敌机图片路径
enemy[enemy_num]=new JLabel(image_enemy);
Random random=new Random();
enemy[enemy_num].setBounds(random.nextInt(image1.getIconWidth()), 0, image_enemy.getIconWidth(), image_enemy.getIconHeight());//设置敌机生成位置和大小(位置横坐标通过Random随机生成)
layeredPane.add(enemy[enemy_num], JLayeredPane.MODAL_LAYER);
a1.add(enemy[enemy_num]);//将每一个生成的敌机存放到ArrayList中
enemy_num++;
}
}
}
//子弹生成(线程代码)
class ammoCreate extends Thread{
public void run() {
while(true) {
try {
this.sleep(1000);//1000毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageIcon image_ammo=new ImageIcon("game_image/ammo.png");//子弹图片路径
ammo[ammo_num]=new JLabel(image_ammo);
ammo[ammo_num].setBounds(X, Y-40, image_ammo.getIconWidth(), image_ammo.getIconHeight());//子弹位置和大小(X,Y为鼠标的X,Y坐标)
layeredPane.add(ammo[ammo_num], JLayeredPane.MODAL_LAYER);
a2.add(ammo[ammo_num]);//将每一个生成的子弹存放到ArrayList中
ammo_num++;
}
}
}
敌机与子弹的移动
//敌机移动(线程代码)
class enemyMove extends Thread{
public void run() {
while(true) {
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
a1.get(i).setLocation(a1.get(i).getX(), a1.get(i).getY()+10);//敌机移动,在原基础向下移动10
if(a1.get(i).getY()>=image1.getIconHeight()) {//敌机移动到窗口外,变得不可见,然后从对应的ArrayList中移除
a1.get(i).setVisible(false);
a1.remove(i);
}
}
}
}
}
//子弹移动(线程代码)
class ammoMove extends Thread{
public void run() {
while(true) {
for(int i=0;i<a2.size();i++) {//遍历子弹的ArrayList
a2.get(i).setLocation(a2.get(i).getX(),a2.get(i).getY()-10);//位置移动,在原基础向上移动10
if(a2.get(i).getY()<=-30) {//子弹移动到窗口外,变得不可见,然后从对应的ArrayList中移除
a2.get(i).setVisible(false);
a2.remove(i);
}
}
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
相撞判断
//战机与敌机相撞(线程代码)
class playerBoom extends Thread{
public void run() {
while(true) {
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
if(a1.get(i).isVisible()) {//当敌机可视
if(jl2.getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&jl2.getY()-a1.get(i).getY()>=-jl2.getHeight()) {//敌机与战机相遇
if(jl2.getX()-a1.get(i).getX()>=-jl2.getWidth()&&jl2.getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
a1.get(i).setVisible(false);//敌机不可视
//游戏结束
new game_plane_3();
dispose();
return;//结束该线程
}
}
}
}
}
}
}
//子弹与敌机相撞(线程代码)
class ammoBoom extends Thread{
public void run() {
while(true) {
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
for(int j=0;j<a2.size();j++) {//遍历子弹对应的ArrayList
if(a1.get(i).isVisible()&&a2.get(j).isVisible()) {//当子弹与敌机都可视
if(a2.get(j).getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&a2.get(j).getY()-a1.get(i).getY()>=-10) {//子弹与敌机相遇
if(a2.get(j).getX()-a1.get(i).getX()>=-a2.get(j).getWidth()&&a2.get(j).getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
a1.get(i).setVisible(false);//对应的敌机不可视
a2.get(j).setVisible(false);//对应的子弹不可视
}
}
}
}
}
}
}
}
完整代码
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class game_plane_2 extends JFrame{
ImageIcon image1=new ImageIcon("game_image/background.png");//背景图片路径
ImageIcon image2=new ImageIcon("game_image/player1.png");//战机图片路径
JLabel[] enemy=new JLabel[50000];
ArrayList<JLabel> a1=new ArrayList<JLabel>();//存放敌机
JLabel[] ammo=new JLabel[50000];
ArrayList<JLabel> a2=new ArrayList<JLabel>();//存放子弹
JLabel jl1=new JLabel(image1);
JLabel jl2=new JLabel(image2);
JLayeredPane layeredPane=new JLayeredPane();
int X=200,Y=500;//记录鼠标位置X,Y
int enemy_num=0,ammo_num=0;
public game_plane_2() {
jl1.addMouseMotionListener(new mouse1());//添加监听器
jl2.setBounds(X, Y, image2.getIconWidth(), image2.getIconHeight());//战机位置和大小
jl1.setBounds(0, 0, image1.getIconWidth(), image1.getIconHeight());//背景位置和大小
layeredPane.add(jl1, JLayeredPane.DEFAULT_LAYER);
layeredPane.add(jl2, JLayeredPane.MODAL_LAYER);
new enemyCreate().start();//敌机生成的线程启动
new ammoCreate().start();//子弹生成的线程启动
new enemyMove().start();//敌机移动的线程启动
new ammoMove().start();//子弹移动的线程启动
new ammoBoom().start();//子弹与敌机相撞的线程启动
new playerBoom().start();//战机与敌机相撞的线程启动
this.setLayeredPane(layeredPane);
this.setTitle("飞机大战");//窗体标题
this.setResizable(false);//窗体不可最大化
this.setSize(image1.getIconWidth(),image1.getIconHeight());//设置大小
this.setLocationRelativeTo(null);//窗体位置
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);//窗体关闭
this.setVisible(true);//窗体可视
}
class mouse1 extends MouseMotionAdapter{
@Override
public void mouseMoved(MouseEvent e) {
X=e.getX();//得到鼠标X坐标
Y=e.getY();//得到鼠标Y坐标
jl2.setLocation(X-30, Y-35);
//战机根据鼠标设置位置
//通过监听器,只要鼠标移动就执行,
//图片根据显示效果更改坐标值
}
}
//战机与敌机相撞(线程代码)
class playerBoom extends Thread{
public void run() {
while(true) {
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
if(a1.get(i).isVisible()) {//当敌机可视
if(jl2.getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&jl2.getY()-a1.get(i).getY()>=-jl2.getHeight()) {//敌机与战机相遇
if(jl2.getX()-a1.get(i).getX()>=-jl2.getWidth()&&jl2.getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
a1.get(i).setVisible(false);//敌机不可视
//游戏结束
new game_plane_3();
dispose();
return;//结束该线程
}
}
}
}
}
}
}
//子弹与敌机相撞(线程代码)
class ammoBoom extends Thread{
public void run() {
while(true) {
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
for(int j=0;j<a2.size();j++) {//遍历子弹对应的ArrayList
if(a1.get(i).isVisible()&&a2.get(j).isVisible()) {//当子弹与敌机都可视
if(a2.get(j).getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&a2.get(j).getY()-a1.get(i).getY()>=-10) {//子弹与敌机相遇
if(a2.get(j).getX()-a1.get(i).getX()>=-a2.get(j).getWidth()&&a2.get(j).getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
a1.get(i).setVisible(false);//对应的敌机不可视
a2.get(j).setVisible(false);//对应的子弹不可视
}
}
}
}
}
}
}
}
//敌机移动(线程代码)
class enemyMove extends Thread{
public void run() {
while(true) {
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
a1.get(i).setLocation(a1.get(i).getX(), a1.get(i).getY()+10);//敌机移动,在原基础向下移动10
if(a1.get(i).getY()>=image1.getIconHeight()) {//敌机移动到窗口外,变得不可见,然后从对应的ArrayList中移除
a1.get(i).setVisible(false);
a1.remove(i);
}
}
}
}
}
//子弹移动(线程代码)
class ammoMove extends Thread{
public void run() {
while(true) {
for(int i=0;i<a2.size();i++) {//遍历子弹的ArrayList
a2.get(i).setLocation(a2.get(i).getX(),a2.get(i).getY()-10);//位置移动,在原基础向上移动10
if(a2.get(i).getY()<=-30) {//子弹移动到窗口外,变得不可见,然后从对应的ArrayList中移除
a2.get(i).setVisible(false);
a2.remove(i);
}
}
try {
this.sleep(100);//100毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//敌机生成(线程代码)
class enemyCreate extends Thread{
public void run() {
while(true) {
try {
this.sleep(1000);//1000毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageIcon image_enemy=new ImageIcon("game_image/enemy.png");//敌机图片路径
enemy[enemy_num]=new JLabel(image_enemy);
Random random=new Random();
enemy[enemy_num].setBounds(random.nextInt(image1.getIconWidth()), 0, image_enemy.getIconWidth(), image_enemy.getIconHeight());//设置敌机生成位置和大小(位置横坐标通过Random随机生成)
layeredPane.add(enemy[enemy_num], JLayeredPane.MODAL_LAYER);
a1.add(enemy[enemy_num]);//将每一个生成的敌机存放到ArrayList中
enemy_num++;
}
}
}
//子弹生成(线程代码)
class ammoCreate extends Thread{
public void run() {
while(true) {
try {
this.sleep(1000);//1000毫秒执行一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ImageIcon image_ammo=new ImageIcon("game_image/ammo.png");//子弹图片路径
ammo[ammo_num]=new JLabel(image_ammo);
ammo[ammo_num].setBounds(X, Y-40, image_ammo.getIconWidth(), image_ammo.getIconHeight());//子弹位置和大小(X,Y为鼠标的X,Y坐标)
layeredPane.add(ammo[ammo_num], JLayeredPane.MODAL_LAYER);
a2.add(ammo[ammo_num]);//将每一个生成的子弹存放到ArrayList中
ammo_num++;
}
}
}
}
如有错误
欢迎指出
下一篇:用JAVA制作小游戏——飞机大战(三)(待发布)