飞机大战Java源代码
作者:互联网
很快,大二这个学期就要完结了,所学的大部分课程都快要结束了,Java课程也是如此。而Java这门课程也有一个惯例就是要做一个课程设计,老师给了我们三个选择,分别是飞机大战、推箱子和学生成绩管理系统。在经过深思熟虑后,我选择了飞机大战。一方面是觉得他比较有趣和好玩,另一方面,觉得这难度也适中,所以就选择了它。
现在,我对这个飞机大战进行解说。主要分为六个部分,分别是底层窗口和容器类、各种组件类、碰撞类、监听器类、线程类和音效媒体类。
游戏运行图片如下:
一 底层容器和窗口
在利用Java制作飞机大战这个游戏时,首先就要构造一个窗口。只有创建了窗口之后,你后面的游戏背景图片、飞机、子弹和空投等等,才能放入界面中。
Main主程序:程序的运行由此开始。
public class Main {
public static void main(String[] args) {
new BaseFrame();
String bg="Music/bg.wav";
Music music = new Music();
music.playMusic(bg);
}
}
在底层容器中,我是利用JFrame去构造。创建BaseFrame类去继承JFrame,然后再对鼠标设立监听器去控制英雄机的移动。后面再在创建MyPanel类去继承JPanel去实现窗口。
BaseFrame类:
import java.awt.*;
import javax.swing.*;
public class BaseFrame extends JFrame{
public static int frameWidth=345;
public static int frameHeight=575;
public Graphics g;
public MyPanel myPanel;
//存放的是鼠标监听器
public FrameMouseListener frameMouseListener;
public FrameMouseClick frameMouseClick;
//设置监听器
public void setTouchListener1() {
this.frameMouseListener=new FrameMouseListener();
this.frameMouseListener.baseFrame=this;
//注册监听器
this.addMouseMotionListener(this.frameMouseListener);
}
public void setTouchListener2() {
this.frameMouseClick=new FrameMouseClick();
this.frameMouseClick.baseFrame=this;
//注册监听器
this.addMouseListener(this.frameMouseClick);
}
public BaseFrame() {
super("飞机大战");
//获得屏幕的分辨率
Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
//设置窗口的大小和位置
this.setBounds(((int)screenSize.getWidth()-frameWidth)/2,50,frameWidth,frameHeight);
//设置布局方式
this.setLayout(null);
//创建一个MyPanel对象
this.myPanel=new MyPanel();
//设置MyPanel对象的大小和位置
this.myPanel.setBounds(0,0,frameWidth,frameHeight);
//设置监听器
setTouchListener2();
setTouchListener1();
//将组件添加到窗口
this.add(this.myPanel);
//显示窗口
this.setVisible(true);
//设置窗口的关闭行为
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
MyPanel类:去存放飞机、子弹等等小组件,里面利用的计时器timer去控制整个游戏的进行,包括背景图的移动,子弹的发射,敌机的前进,空投的下落等等。
import java.awt.*;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class MyPanel extends JPanel{
Random ran=new Random();
//存放的是背景图片
public Image bgImage;
public Image image1;
public Image image2;
public Image image3;
public int timer=0;
public int top=0;
public long score=0;
public int flag=0;
public DrawableThread drawableThread;
public Player player;
public Crash crash;
public Boss boss;
public int lives=3;
public int drop=0;
public int boss_flag=0;
public Music music = new Music();
public String all_bomb="Music/all_bomb.wav";
public ArrayList<Enemy> enemies=new ArrayList<Enemy>();
public ArrayList<Bullet> bullets=new ArrayList<Bullet>();
public ArrayList<Airdrop> airdrops=new ArrayList<Airdrop>();
public ArrayList<BossBullet> bossBullets=new ArrayList<BossBullet>();
public MyPanel() {
this.image1=Toolkit.getDefaultToolkit().getImage("Picture/start.png");
this.image2=Toolkit.getDefaultToolkit().getImage("Picture/gameover.png");
this.image3=Toolkit.getDefaultToolkit().getImage("Picture/Victory.png");
this.bgImage=Toolkit.getDefaultToolkit().getImage("Picture/background.png");
this.player=new Player(this);
this.boss=new Boss(this);
this.crash=new Crash(this);
//创建线程 重绘Panel
this.drawableThread=new DrawableThread(this);
//启动线程
this.drawableThread.start();
}
//绘制组件
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(this.flag==0) {
g.drawImage(image1, 0, 0, this.image1.getWidth(this), this.image1.getHeight(this),null);
}
if(this.flag==1) {
//绘制背景图
g.drawImage(this.bgImage,0,top-this.bgImage.getHeight(this),this.bgImage.getWidth(this),this.bgImage.getHeight(this),null);
g.drawImage(this.bgImage,0,top,this.bgImage.getWidth(this),this.bgImage.getHeight(this),null);
timer++;
if(timer==10000)
timer=0;
//实现图片下移
if(timer%5==0) {
top++;
if(top>=this.bgImage.getHeight(this))
top=0;
}
//绘制玩家
this.player.drawSelf(g);
if(this.score>450&&this.score<500)
{
g.setFont(new Font("黑体",Font.PLAIN,40));
g.setColor(Color.RED);
g.drawString("BOSS即将来临!", 30, 120);
}
//绘制Boss
if(this.score>500) {
this.boss.drawSelf(g);
this.boss_flag=1;
}
if(this.boss.lives<0&&(this.boss.y+this.boss.height)<0) {
this.flag=3;
this.music.playMusic(all_bomb);
}
g.setFont(new Font("宋体",Font.PLAIN,20));
g.setColor(Color.WHITE);
g.drawString("分数:"+score, BaseFrame.frameWidth/15, BaseFrame.frameHeight/10);
g.drawString("生命:"+lives,BaseFrame.frameWidth/15, BaseFrame.frameHeight/10+20);
if(timer%20==0) {
if(this.player.attackMode==1) {
//创建子弹
Bullet bullet=new Bullet(this);
//设置坐标
bullet.x=this.player.x+this.player.width/2-bullet.width/2;
bullet.y=this.player.y;
//存入arraylist中
this.bullets.add(bullet);
}
if(this.player.attackMode==2) {
//创建子弹
Bullet bullet1=new Bullet(this);
//设置坐标
bullet1.x=this.player.x+this.player.width/2-bullet1.width/2;
bullet1.y=this.player.y;
//存入arraylist中
this.bullets.add(bullet1);
//创建子弹
Bullet bullet2=new Bullet(this);
//设置坐标
bullet2.x=this.player.x+this.player.width/2-bullet2.width/2-20;
bullet2.y=this.player.y;
//存入arraylist中
this.bullets.add(bullet2);
//创建子弹
Bullet bullet3=new Bullet(this);
//设置坐标
bullet3.x=this.player.x+this.player.width/2-bullet3.width/2+20;
bullet3.y=this.player.y;
//存入arraylist中
this.bullets.add(bullet3);
}
//创建Boss子弹
if(timer%200==0&&this.score>500&&this.boss.lives>0) {
BossBullet bossBullet=new BossBullet(this);
bossBullet.x=this.boss.x+this.boss.width/2-bossBullet.width/2;
bossBullet.y=this.boss.y+this.boss.height;
this.bossBullets.add(bossBullet);
}
//创建敌机
if(timer%50==0) {
Enemy enemy=new Enemy(this);
enemy.x=ran.nextInt(306);//随机生成x坐标
enemy.y=-30;
this.enemies.add(enemy);
}
//创建空投
if(timer%1000==0) {
Airdrop airdrop=new Airdrop(this);
airdrop.x=ran.nextInt(346);//随机生成x坐标
airdrop.y=-40;
this.airdrops.add(airdrop);
}
}
//画出所有子弹
for(int i=0;i<bullets.size();i++)
this.bullets.get(i).drawSelf(g);
//画出Boss子弹
for(int i=0;i<bossBullets.size();i++)
this.bossBullets.get(i).drawSelf(g);
//画出敌机
for(int i=0;i<enemies.size();i++) {
this.enemies.get(i).drawSelf(g);
}
//画出空投
for(int i=0;i<airdrops.size();i++) {
this.airdrops.get(i).drawSelf(g);
if(this.crash.Boom3(this.airdrops.get(i), this.player.x, this.player.y)) {
this.airdrops.remove(i);
this.drop++;
}
}
if(this.drop>=3)
this.player.attackMode=2;
//子弹与敌机碰撞
for(int i=0;i<bullets.size();i++) {
Bullet bullet=this.bullets.get(i);
for(int j=0;j<enemies.size();j++) {
Enemy enemy=this.enemies.get(j);
if(this.crash.Boom1(bullet, enemy)) {
this.enemies.remove(j);
this.bullets.remove(i);
this.score+=10;
break;
}
}
}
//boss被子弹击中
for(int i=0;i<bullets.size();i++) {
Bullet bullet=this.bullets.get(i);
if(this.crash.Boom5(bullet, this.boss)) {
this.boss.lives--;
this.score+=2;
this.bullets.remove(i);
}
}
//英雄机与敌机相撞
for(int i=0;i<enemies.size();i++) {
if(this.crash.Boom2(this.enemies.get(i),this.player.x, this.player.y))
{
this.enemies.remove(i);
this.lives--;
if(this.lives==0)
this.flag=2;
break;
}
}
//英雄机被boss子弹击中
for(int i=0;i<bossBullets.size();i++) {
if(this.crash.Boom4(this.bossBullets.get(i), this.player.x, this.player.y)) {
this.bossBullets.remove(i);
this.lives--;
if(this.lives==0)
this.flag=2;
break;
}
}
}
//游戏失败界面
if(this.flag==2) {
g.drawImage(image2, 0, 0, this.image2.getWidth(this), this.image2.getHeight(this),null);
g.setFont(new Font("黑体",Font.PLAIN,20));
g.setColor(Color.BLACK);
g.drawString("分 数:"+this.score, 120, 300);
}
//游戏胜利界面
if(this.flag==3) {
g.drawImage(image3, 0, 0, this.image3.getWidth(this), this.image3.getHeight(this),null);
g.setFont(new Font("黑体",Font.PLAIN,20));
g.setColor(Color.BLACK);
g.drawString("分 数:"+this.score, 120, 300);
g.drawString("恭喜你击败了BOSS,获得了胜利", 20, 350);
}
}
}
二 各种组件类
各种组件类中就比较多了,包括英雄机类,子弹类,空投类,boss类等等,以下一一通过代码展示。
英雄机类:
import java.awt.*;
import javax.swing.*;
public class Player {
public MyPanel myPanel;
public int width=60;
public int height=61;
public int x;
public int y;
public int attackMode=1;//火力等级
public int imageindex=0;//存放当前图片下标
public Image[] images=new Image[] {
Toolkit.getDefaultToolkit().getImage("Picture/player1.png"),
Toolkit.getDefaultToolkit().getImage("picture/player2.png"),
Toolkit.getDefaultToolkit().getImage("Picture/playerX.png")
};
public Player(MyPanel myPanel) {
this.myPanel=myPanel;
this.x=(BaseFrame.frameWidth-this.width)/2;
this.y=(BaseFrame.frameHeight-this.height+260)/2;
}
public void drawSelf(Graphics g) {
g.drawImage(this.images[imageindex], x, y, width, height, null);
if(this.myPanel.timer%50==0) {
if(this.myPanel.score<=300) {
imageindex++;
if(this.imageindex==2)
this.imageindex=0;
}
else {
imageindex=2;
}
}
}
}
敌机类:
import java.awt.*;
import java.util.Random;
import javax.swing.*;
public class Enemy {
public MyPanel myPanel;
public int width=40;
public int height=25;
public int x;
public int y;
public Image image;
public Enemy(MyPanel myPanel) {
this.myPanel=myPanel;
this.image=Toolkit.getDefaultToolkit().getImage("Picture/enemy.png");
}
public void drawSelf(Graphics g) {
g.drawImage(this.image, x, y, width, height, null);
if(this.myPanel.timer%1==0)
y++;
if(y+height>BaseFrame.frameHeight)
this.myPanel.enemies.remove(this);
}
}
boss类:
import java.awt.*;
public class Boss {
public MyPanel myPanel;
public int width=100;
public int height=73;
public int x;
public int y;
public Image image;
public int flag=1;
public int lives=500;
public Boss(MyPanel myPanel) {
this.myPanel=myPanel;
this.image=Toolkit.getDefaultToolkit().getImage("Picture/Boss.png");
this.x=(BaseFrame.frameWidth-this.width)/2;
this.y=0;
}
public void drawSelf(Graphics g) {
g.drawImage(this.image, x, y, width, height, null);
if(this.myPanel.timer%3==0&&this.y<=100&&lives>0)
this.y++;
if(lives<0)
this.y--;
if(this.myPanel.timer%3==0&&this.y>100) {
if(this.x+this.width>BaseFrame.frameWidth)
flag=0;
if(this.x==0)
flag=1;
if(flag==1)
this.x++;
if(flag==0)
this.x--;
}
}
}
空投类:
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Random;
public class Airdrop {
public MyPanel myPanel;
public int width=40;
public int height=40;
public int x;
public int y;
public int flag=0;
Random ran;
public Image image;
public Airdrop(MyPanel myPanel) {
this.myPanel=myPanel;
this.image=Toolkit.getDefaultToolkit().getImage("Picture/airdrop.png");
}
public void drawSelf(Graphics g) {
g.drawImage(this.image, x, y, width, height, null);
if(this.myPanel.timer%3==0) {
y++;
if(flag==0) {
x++;
}
if(flag==1) {
x--;
}
if(this.x+40>BaseFrame.frameWidth)
flag=1;
if(this.x<0)
flag=0;
}
if(y+height>BaseFrame.frameHeight)
this.myPanel.airdrops.remove(this);
}
}
英雄机子弹类:
import javax.swing.*;
import java.awt.*;
public class Bullet {
public MyPanel myPanel;
public int width=6;
public int height=14;
public int x;
public int y;
public int index=0;
public Image[] bulletImage=new Image[] {
Toolkit.getDefaultToolkit().getImage("Picture/ammo.png"),
Toolkit.getDefaultToolkit().getImage("Picture/bullet1.png")
};
public Bullet(MyPanel myPanel) {
this.myPanel=myPanel;
}
//画子弹
public void drawSelf(Graphics g) {
g.drawImage(this.bulletImage[index], x, y, width, height, null);
if(this.myPanel.timer%1==0)
y--;
if(y<0)
this.myPanel.bullets.remove(this);
if(this.myPanel.score>100)
index=1;
}
}
boss子弹类:
import java.awt.*;
public class BossBullet {
public MyPanel myPanel;
public int width=20;
public int height=20;
public int x;
public int y;
public int index=0;
public Image[] images=new Image[] {
Toolkit.getDefaultToolkit().getImage("Picture/BossBullet.png"),
Toolkit.getDefaultToolkit().getImage("Picture/BossBullet1.png"),
Toolkit.getDefaultToolkit().getImage("Picture/BossBullet2.png")
};
public BossBullet(MyPanel myPanel) {
this.myPanel=myPanel;
}
public void drawSelf(Graphics g) {
g.drawImage(this.images[index], x, y, width, height, null);
if(this.myPanel.timer%1==0)
y++;
if(y>580)
this.myPanel.bossBullets.remove(this);
if(this.myPanel.timer%2==0) {
index++;
if(index==images.length)
index=0;
}
if(y>BaseFrame.frameHeight)
this.myPanel.bossBullets.remove(this);
}
}
三 组件碰撞类
因为飞机大战中,重要利用的就是各种组件相碰撞而制作成的游戏,所以这部分肯定少不了。这里需要对各种组件进行判断,看他们是否相碰撞,判断的依据就是他们之间的距离是否小于最小距离。
碰撞类:
public class Crash {
public MyPanel myPanel;
Music music = new Music();
public String enemy_bomb="Music/enemy_bomb.wav";
public String hero_bomb="Music/hero_bomb.wav";
public String boss_boom="Music/10804.wav";
public Crash(MyPanel myPanel) {
this.myPanel=myPanel;
}
//判断子弹和敌机碰撞
public boolean Boom1(Bullet bullet,Enemy enemy) {
int bulletx,bullety;
int enemyx,enemyy;
boolean crash=false;
//子弹坐标
bulletx=bullet.x+3;
bullety=bullet.y+7;
//敌机坐标
enemyx=enemy.x+20;
enemyy=enemy.y+12;
if(Math.abs(enemyx-bulletx)<20&&Math.abs(bullety-enemyy)<12) {
crash=true;//如果相撞返回真
music.playMusic(enemy_bomb);
}
return crash;
}
//判断子弹击中boss机
public boolean Boom5(Bullet bullet,Boss boss) {
int bulletx,bullety;
int bossx,bossy;
boolean crash=false;
//子弹坐标
bulletx=bullet.x+4;
bullety=bullet.y+9;
//敌机坐标
bossx=boss.x+50;
bossy=boss.y+36;
if(Math.abs(bulletx-bossx)<50&&Math.abs(bullety-bossy)<36&&this.myPanel.boss_flag==1) {
crash=true;//如果相撞返回真
music.playMusic(enemy_bomb);
}
return crash;
}
//飞机碰撞敌机
public boolean Boom2(Enemy enemy,int x,int y) {
int enemyx,enemyy;
boolean crash=false;
//敌机坐标
enemyx=enemy.x+20;
enemyy=enemy.y+12;
//英雄机坐标
x=x+40;
y=y+36;
//相撞条件
if(Math.abs(x-enemyx)<50&&Math.abs(y-enemyy)<50) {
crash=true;
music.playMusic(hero_bomb);
}
return crash;
}
//英雄机被Boss的子弹击中
public boolean Boom4(BossBullet bossBullet,int x,int y) {
int bossbx,bossby;
boolean crash=false;
//敌机坐标
bossbx=bossBullet.x+10;
bossby=bossBullet.y+10;
//英雄机坐标
x=x+45;
y=y+36;
//相撞条件
if(Math.abs(x-bossbx)<50&&Math.abs(y-bossby)<50) {
crash=true;
music.playMusic(hero_bomb);
}
return crash;
}
//飞机获取空投
public boolean Boom3(Airdrop airdrop,int x,int y) {
int airdropx,airdropy;
boolean crash=false;
//空投坐标
airdropx=airdrop.x;
airdropy=airdrop.y;
//英雄机坐标
x=x-30;
y=y-30;
//相撞条件
if(airdropx>x+20&&y-airdropy<20&&airdropx<x+60)
crash=true;
return crash;
}
}
四 线程类
这里主要控制游戏的进行,飞机大战中利用了线程去实现,从而使游戏的表现更好,能一致进行。
线程类:
import java.awt.*;
import javax.swing.*;
public class DrawableThread extends Thread{
public MyPanel myPanel;
public DrawableThread(MyPanel myPanel) {
this.myPanel=myPanel;
}
public void run() {
while(true) {
this.myPanel.repaint();//重绘调用paintComponent
try {
Thread.currentThread().sleep(1);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
五 监听器类
这里主要使用监听器去实现用鼠标控制英雄机的移动,和用鼠标控制游戏的开始和结束。
控制英雄机的移动:
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
public class FrameMouseListener extends MouseMotionAdapter{
public BaseFrame baseFrame;
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
this.baseFrame.myPanel.player.x=e.getX()-this.baseFrame.myPanel.player.width/2;
this.baseFrame.myPanel.player.y=e.getY()-this.baseFrame.myPanel.player.height/2;
}
}
控制游戏的开始和结束:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
public class FrameMouseClick extends MouseAdapter{
public BaseFrame baseFrame;
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(this.baseFrame.myPanel.flag==2||this.baseFrame.myPanel.flag==3)
{
this.baseFrame.dispose();//直接退出
new BaseFrame();
}
this.baseFrame.myPanel.flag=1;
}
}
六 音效媒体类
为了增加游戏的体验感和沉浸感,我给游戏添加了游戏背景音乐和子弹击中音效和英雄机死亡音效,效果不错。
import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class Music {
void playMusic(String musicLocation)
{
try
{
File musicPath = new File(musicLocation);
if(musicPath.exists())
{
AudioInputStream audioInput = AudioSystem.getAudioInputStream(musicPath);
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
clip.loop(0);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
以上所有的代码展示完毕,感谢你的浏览。
标签:Java,int,大战,player,import,new,源代码,public,myPanel 来源: https://blog.csdn.net/zhimingdaye/article/details/112912100