【java设计】:全民飞机大战小游戏制作

 

d6177ec047e2482f8a605733016cb3c3.png

文章目录


前言

一、全民飞机大战

二、计划安排

三、源码图和类图展示

四、源码展示

Fire类:

GameMain类:

GamePanel类:

Hero类:

Image类:

PlaySound类:

Sp类:

总结


 


前言

        终于回归了,最近忙于期末考试和一些课程设计,琐事什么的,一直没更新,今天算是终于忙完了,趁着热乎劲,抓紧把这段时间的收获分享给大家,希望大家看到能有所收获。帮助大家完成java的基础学习。欢迎大家的阅读,记得点点赞哦~

        以下内容都在自己手敲,个人的一些学习内容,可以学习。


一、全民飞机大战

        应学校要求,课程设计得做一个全民飞机大战的小游戏,表现下一个学期的java学习能力,课程设计就给了两天时间,比较急,以下作品也比较粗糙,大家海涵。

        完成效果图:

                        c968a337c17045e0a52836fd1d98ded3.png

        项目介绍:

        本程序实现的主要功能有玩家飞机的控制、玩家飞机子弹发射、敌机移动、敌机子弹发射、boss飞机的折线运动、boss飞机的子弹发射、玩家战机的选择(五种战机)、飞机与飞机、飞机与子弹之间的碰撞。

        本程序包括七个类和一个声音文件和图片文件,其中七个类中包括:主类(GameMain),里面的main方法是程序的入口;GamePanel类,功能是实现窗体主面板的界面布局,包括一个键盘监听方法;GamePanel类,是游戏的主要面板,有一个内部类(GamePanel)继承(JPanel)用于实现游戏地图的面板,内部类中包括paint方法绘制游戏飞机、子弹等,run方法用于启动线程,draw方法控制画布上的飞机、子弹等的变化,adapter用于键盘监听;玩家飞机(Hero)敌机类(Sp)、子弹类(Fire)、boss飞机类(Image)都是绘制飞机、子弹等的类,其中都有绘制的方法和移动的方法以及获取坐标的方法;碰撞类(Collide),实现飞机与敌机、飞机与子弹等碰撞的判断和碰撞后的操作;Break类,包括实现玩家飞机、敌机的方法; PlaySound类,包括打开声音文件的方法(open)、建立音频行的方法(play)、暂停声音的方法(stop)、开始播放的方法(start)、回放背景音乐的方法(loop)。


二、计划安排

  1.          1、了解并复习JFrame、JPanel、IO输入输出流、ImageIO、BufferedImage、arraylist、try……catch异常处理、Random类、gui、事件处理监听器、泛型、线程等等知识点。
    1.        2、新建工程,收集图片存入img包,并新建了LHB_Fly_Pack包,编写GamePanel、GameMain类,构建工程主体框架。Sp代表敌机,Fire代表子弹开火,Hero代表英雄机、Image显示图片、PlaySound播放音乐。
      1.           3、玩家飞机子弹的实现:玩家飞机子弹对象用一个ArrayList存储,在固定时间间隔后绘制一个子弹对象并加入数组,当子弹超过地图时从数组中移除子弹对象。敌机子弹的实现:所有敌机子弹对象都是用一个ArrayList存储,但每一个子弹对象依赖于每一架敌机,在循环绘制敌机时绘制每一架敌机的子弹;
        1.           4、声音的实现:游戏声音的控制封装为一个PlaySound类,有根据传入的路径打开音频文件、建立音频行、通过调用音频行对象的start方法开始播放、通过调用音频行对象的stop方法暂停播放、通过调用音频行对象的loop方法重复播放等几个方法,当需要控制声音时调用相应方法。
          1.           5、调试、解决bug,对功能进行集成。
            1.           6、生成类图,对之前代码进行精简,没必要的程序进行删除,对于那种冗长的程序代码进行修改,对程序的流程进行最后一遍审查,对照类图进行对比,与同学交流技术,看看自己的程序是否有些逻辑错误,对比之后最后调试得到最后的一次代码
              1.          7、编写课程报告,生成.jar文件,完成课程设计报告并提交电子档设计报告及所有代码+jar文件。
              2.  


                三、源码图和类图展示

              3. f5cf4631d6d34dd5a1c5fb8a4337b27d.png

                类图

                247440cceeee4e148860362568458d84.png

                源码工程图

              4. d6177ec047e2482f8a605733016cb3c3.png

四、源码展示

Fire类:

package LHB_Fly_Pack;

import java.awt.image.BufferedImage;
/*
 * hx,hy为  横、纵坐标
 * dir 方向
 */
public class Fire extends Hero {
    BufferedImage img;
    int x,y,w,h;
    int dir;
    public Fire(int hx,int hy,int dir) { //dir:方向
        img= Image.getImage("/img/fire.png");
        w=img.getWidth()/4;
        h=img.getHeight()/4;
        x=hx;
        y=hy;
        this.dir=dir;
    }
    public void move() {
        if(dir==0){//左上飞
            x-=2;
            y-=10;
        }else if(dir==1){//垂直飞
            y-=10;
        }else if(dir==2){//右上飞
            x+=2;
            y-=10;
        }
    }
}

GameMain类:

package LHB_Fly_Pack;
import javax.swing.*;
import javax.swing.JFrame;
public class GameMain extends JFrame {
    static PlaySound p;//声音对象
    public GameMain() {
        setTitle("Java课程设计——全民飞机大战");
        setSize(512, 768);
        this.setLocationRelativeTo(null);// 屏幕左上角居中
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        GameMain frame = new GameMain();
        GamePanel panel = new GamePanel();
        if(p == null) {//声音设置
            p = new PlaySound();
            p.open("sounds\\OPSound.mid");
            p.play();
            p.loop();
            p.start();
        }
        frame.add(panel);
        frame.setVisible(true);
        panel.action();
    }
}

GamePanel类:

package LHB_Fly_Pack;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.*;

public class GamePanel extends JPanel {
	BufferedImage bg;// 定义背景图
	Hero hero;
	ArrayList<Sp> eps = new ArrayList<Sp>();
	ArrayList<Fire> fires = new ArrayList<Fire>();
	int score = 0; //分数显示
	int score1 = 0; //分数显示

	int score2 = 50;

	public GamePanel() {
		bg = Image.getImage("/img/bg2.jpg");
		hero = new Hero();
		MouseAdapter adapter = new MouseAdapter() {
			public void mouseMoved(MouseEvent e) {
				int mx = e.getX(); // 横坐标
				int my = e.getY(); // 纵坐标
				hero.moveToMouse(mx, my);
				repaint(); //
			};
		};
		addMouseListener(adapter);
		addMouseMotionListener(adapter);
	}
	public void action() {
		(new Thread() {
			@Override
			public void run() {
				super.run();
				while (true) {
					// 敌机入场
					epEnter();
					// 敌机移动
					epMove();
					// 产生子弹
					shoot();
					// 子弹移动
					fireMove();
					// 判断子弹是否击中敌机
					shootEp();
					// 判断是否撞机
					shootSp();
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (score >= score2) {
						bg = Image.getImage("\\img\\start.jpg");
					}
					repaint();
				}
			}

			private void shootEp() {
				// TODO Auto-generated method stub

				for (int i = 0; i < fires.size(); i++) {
					Fire f = fires.get(i);
					bang(f);
				}
			}

			private void bang(Fire f) {
				for (int i = 0; i < eps.size(); i++) {
					Sp ep = eps.get(i);
					if (ep.shootBy(f)) {
						eps.remove(ep); // 删除敌机
						fires.remove(f); // 删除弹药
						score+=1;
					}
				}
			}
			private void shootSp() {
				for (int i = 0; i < fires.size(); i++) {
					Fire f = fires.get(i);
					Over(f);
				}
			}

			private void Over(Fire f) {
				for (int i = 0; i < eps.size(); i++) {
					Sp ep = eps.get(i);
					if (ep.shootSy(f)) {
						score1+=1;
					}
				}
			}

			private void fireMove() {
				for (int i = 0; i < fires.size(); i++) {
					Fire fire = fires.get(i);
					fire.move();
				}
			}
			int findex = 0;
			private void shoot() {
				findex++;
				if (findex > 20) {
					Fire fire = new Fire(hero.x + 15, hero.y, 0);// 左侧子弹
					Fire fire1 = new Fire(hero.x + 75, hero.y, 2);// 右侧子弹
					Fire fire2 = new Fire(hero.x + 45, hero.y - 20, 1);// 居中子弹位置
					fires.add(fire);
					fires.add(fire1);
					fires.add(fire2);
					findex = 0;
				}

			}
			private void epMove() {
				for (int i = 0; i < eps.size(); i++) {
					Sp ep = eps.get(i);
					ep.move();
				}
			}
		}).start();
	}
	int num = 0;
	private void epEnter() {
		num++;
		if (num >= 5) {
			Sp ep = new Sp();
			eps.add(ep);
			num = 0;
		}
	}

	@Override // 专用画图方法paint() ,Graphics g-->画笔
	public void paint(Graphics g) {
		g.drawImage(bg, 0, 0, null); // 画背景图片
		g.drawImage(hero.img, hero.x, hero.y, null);// 画英雄机
		// 画敌机
		for (int i = 0; i < eps.size(); i++) {
			// System.out.println(eps.size());
			Sp ep = eps.get(i);
			g.drawImage(ep.img, ep.x, ep.y, ep.w, ep.h, null);
		}
		// 画子弹
		for (int i = 0; i < fires.size(); i++) {
			Fire fire = fires.get(i);
			g.drawImage(fire.img, fire.x, fire.y, fire.w, fire.h, null);
		}
		// 画分数
		for(int i=0; i < fires.size(); i++) {
			g.setColor(Color.RED);
			g.setFont(new Font("宋体",Font.BOLD,25));
			g.drawString("得分:"+score, 360, 30);
			if (score >= score2) {
				g.setColor(Color.RED);
				g.setFont(new Font("宋体",Font.BOLD,50));
				g.drawString("恭喜!游戏已通关!!!"+score, 20, 300);
			}
		}
	}
}

Hero类:

package LHB_Fly_Pack;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
public class Hero {
    private boolean isPress01, isPress02, isPress03, isPress04;//按键状态
    BufferedImage img;
    int x,y,w,h;
    public Hero() {
        // TODO Auto-generated constructor stub
        img= Image.getImage("/img/hero.png");
        x=200;
        y=600;
        w=img.getWidth();
        h=img.getHeight();
    }
    public void moveToMouse(int mx,int my){
        x=mx-w/2;
        y=my-h/2;
    }
    /**
     * 玩家飞机移动键盘监听方法
     */
    void adapter(Canvas c) {

        c.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub

                int key = e.getKeyCode();
                if(key == KeyEvent.VK_UP)
                    isPress01 = true;

                if(key == KeyEvent.VK_DOWN)
                    isPress02 = true;

                if(key == KeyEvent.VK_LEFT)
                    isPress03 = true;

                if(key == KeyEvent.VK_RIGHT)
                    isPress04 = true;

            }

            @Override
            public void keyReleased(KeyEvent e) {
                // TODO Auto-generated method stub
                int key = e.getKeyCode();
                if(key == KeyEvent.VK_UP)
                    isPress01 = false;

                if(key == KeyEvent.VK_DOWN)
                    isPress02 = false;

                if(key == KeyEvent.VK_LEFT)
                    isPress03 = false;

                if(key == KeyEvent.VK_RIGHT)
                    isPress04 = false;
            }

        });

    }
}

Image类:

package LHB_Fly_Pack;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
public class Image {
    static BufferedImage img;
    public static BufferedImage getImage(String path){
        try {
            img=ImageIO.read(Image.class.getResource(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return img;
    }
}

PlaySound类:

package LHB_Fly_Pack;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;


public class PlaySound extends Hero {

	private File file; ;//音频文件
	private AudioInputStream stream;//音频输入
	private AudioFormat format;//音频格式
	private DataLine.Info info;//音频行信
	private Clip clip;//音频
	static boolean[] b = new boolean[]{true, true, true, true};//控制声音播放

	void open(String s) {
		file = new File(s);//音频文件对象
		try {
			stream = AudioSystem.getAudioInputStream(file);//音频输入流对
			format = stream.getFormat();//音频格式对象
		} catch (UnsupportedAudioFileException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	void play() {
		info = new DataLine.Info(Clip.class, format);//音频行信息对
		try {
			clip = (Clip) AudioSystem.getLine(info);//音频行对
			clip.open(stream);//将音频数据读入音频行
		} catch (LineUnavailableException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 停止播放
	 */
	void stop() {
		clip.stop();//暂停音频播放
	}
	void start() {
		clip.start();//播放音频
	}

	void loop() {
		clip.loop(20);//回放
	}
}

Sp类:

package LHB_Fly_Pack;

import java.awt.image.BufferedImage;
import java.util.Random;

public class Sp extends PlaySound {
    BufferedImage img;
    int x,y,w,h;
    Random rnd=new Random();
    int sp;
    public Sp() {
        // TODO Auto-generated constructor stub 构造方法
        int index=rnd.nextInt(15)+1;  //rnd.nextInt(15)取值范围从[0,15),+1后取值范围[1,16)
        String epName="/img/ep"+(index>=10?"":"0")+index+".png";
        //ep后的数字越大,敌机体积越大,速度越小
        img= Image.getImage(epName);
        w=img.getWidth();
        h=img.getHeight();
        x=rnd.nextInt(512-w);
        y=-h;
        sp=10-index;//敌机速度,取的index越大,体积越大,速度越慢
    }
    public void move() {
        // TODO Auto-generated method stub
        y+=sp;

    }
    public boolean shootBy(Fire f) {
        // TODO Auto-generated method stub
        boolean hi=false;//设置默认值false
        if((f.x+f.w>=x)&&(x+w>=f.x)&&(f.y+f.h>=y)&&(y+h>=f.y)){
            hi=true;
        }
        return hi;
    }
    //撞敌机
    public boolean shootSy(Fire f) {
        boolean hi=false;//设置默认值false
        if((f.x+f.w>=x)&&(x+w>=f.x)&&(f.y+f.h>=y)&&(y+h>=f.y)){
            hi=true;
        }
        return hi;
    }
}

总结

        以上即是课程设计工程内容,一开源,如需工程实例(+课程报告),请加工作号。

        希望源码对初学者有所帮助,谢谢各位的支持。

        工作号:buildupup(vx)

        08a3c531b4ab45b2827fd58dc4a065be.png

       百度网盘资源:链接:https://pan.baidu.com/s/1vGM3xiUFoXvPnCcMKPAPnA 

 

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值