飞机大战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();
		}
	}

}

以上所有的代码展示完毕,感谢你的浏览。

package cn.feike.shoot; import java.awt.Graphics; import java.awt.image.BufferedImage; public abstract class FlyingObject { protected double x;//物体的x坐标 protected double y;//物体的y坐标 protected double width;//物体的宽 protected double heigth;//物体的高 protected BufferedImage image;//当前正在显示的图片 protected int index = 0;//图片数组下标序号,子类中使用 protected double step;//飞行物每次(1/24秒)移动的距离 protected int life;//命 protected int state;//飞行物的状态 public static final int ACTIVE=0;//活着状态 public static final int DEAD=1;//死亡状态 public static final int REMOVE=2;//回收状态 //默认构造器 public FlyingObject() { life = 1; state = ACTIVE; } //有参构造器 public FlyingObject(double width,double heigth){ this();//调用无参数的构造器,必须写在第一行. this.x = (int)(Math.random()*(480-width)); this.y = -heigth; this.width = width; this.heigth = heigth; step = Math.random()*3+0.8;//初始化step为[0.8,3.8)之间的数 } //重写toString方法 public String toString() { return x+","+y+","+width+","+heigth+","+image; } //重写paint,方便子类对象的使用 public void paint(Graphics g) { g.drawImage(image, (int)x, (int)y, null);//绘制图片 } //飞行物移动的move方法 /** * 重构了move,方法实现播放销毁动画功能 */ public void move(){ if(state == ACTIVE){ y += step; return ; } if(state == DEAD){ //从子类对象中获取下一张照片 BufferedImage img = nextImage(); if(img == null){ state = REMOVE;//没有照片则回收 }else{ image = img;//否则把子类的图片传给image } //越界则销毁 if(y>=825){ state = REMOVE; } } } /** * 子类中必须有的方法,返回下一个要播放的照片引用, * 如果返回null表示没有可播放的照片了. */ protected abstract BufferedImage nextImage(); /** * 飞行物被打了一下 */ public void hit(){ if(life>0){ life--; } if(life==0){ state = DEAD; } } /** * 碰撞检测的方法 * 检测物体的位置是否在碰撞的范围内. * (子弹是否在飞行物的碰撞范围内) */ public boolean duang(FlyingObject obj){ //this(x,y,w,h) //obj(x,y,w,h) double x1 = this.x - obj.width; double x2 = this.x + this.width; double y1 = this.y - obj.width; double y2 = this.y + this.heigth; return x1<obj.x&&obj;.x<x2&&y1;<obj.y&&obj;.y<y2; } /** 重构FlyingObject,添加了状态检查方法 */ /** 检查飞行物死了吗 */ public boolean isDead(){ return state == DEAD; } /** 检查飞行物是否活动的 */ public boolean isActive(){ return state == ACTIVE; } /** 检查飞行是否可以被删除*/ public boolean canRemove(){ return state == REMOVE; } /** 飞行物添加"去死"方法*/ public void goDead(){ if(isActive()){ state = DEAD; } } }
好的,以下是一个简单的Java游戏飞机大战的实现思路和部分关键代码,包含登录注册功能,供您参考: 1. 确定需求:游戏需要支持注册、登录、游戏主界面、游戏结束等功能。 2. 设计数据库:根据需求设计数据库,包括用户表、游戏记录表等。 3. 编写后端代码:使用Java语言和Spring框架编写后端代码,包括数据访问层、业务逻辑层和控制层。 ```java // 数据访问层 @Repository public interface UserRepository extends JpaRepository<User, Long> { User findByUsername(String username); } @Repository public interface GameRecordRepository extends JpaRepository<GameRecord, Long> { } // 业务逻辑层 @Service public class UserService { @Autowired private UserRepository userRepository; public User register(User user) { return userRepository.save(user); } public User login(String username, String password) { User user = userRepository.findByUsername(username); if (user == null || !user.getPassword().equals(password)) { return null; } return user; } } @Service public class GameRecordService { @Autowired private GameRecordRepository gameRecordRepository; public void save(GameRecord gameRecord) { gameRecordRepository.save(gameRecord); } public List<GameRecord> getGameRecordsByUserId(Long userId) { return gameRecordRepository.findAllByUserId(userId); } } // 控制层 @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @PostMapping("") public User register(@RequestBody User user) { return userService.register(user); } @PostMapping("/login") public User login(@RequestParam String username, @RequestParam String password) { return userService.login(username, password); } } @RestController @RequestMapping("/api/gameRecords") public class GameRecordController { @Autowired private GameRecordService gameRecordService; @PostMapping("") public void save(@RequestBody GameRecord gameRecord) { gameRecordService.save(gameRecord); } @GetMapping("/{userId}") public List<GameRecord> getGameRecordsByUserId(@PathVariable Long userId) { return gameRecordService.getGameRecordsByUserId(userId); } } ``` 4. 编写前端页面:使用HTML、CSS和JavaScript等技术编写前端页面,包括登录页面、注册页面、游戏主界面、游戏结束页面等。 ```html <!-- 登录页面 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <form action="/api/users/login" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username"><br> <label for="password">密码:</label> <input type="password" id="password" name="password"><br> <button type="submit">登录</button> </form> </body> </html> <!-- 注册页面 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body> <form action="/api/users" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username"><br> <label for="password">密码:</label> <input type="password" id="password" name="password"><br> <button type="submit">注册</button> </form> </body> </html> <!-- 游戏主界面 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>飞机大战</title> <style> #game-board { width: 600px; height: 800px; margin: 0 auto; border: 1px solid #000; } </style> </head> <body> <div id="game-board"></div> <script src="/js/game.js"></script> </body> </html> <!-- 游戏结束页面 --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>游戏结束</title> </head> <body> <h1>游戏结束</h1> <p>您的得分是:{{ score }}</p> <form action="/api/gameRecords" method="post"> <input type="hidden" name="userId" value="{{ userId }}"> <input type="hidden" name="score" value="{{ score }}"> <button type="submit">保存记录</button> </form> <a href="/game">重新开始</a> </body> </html> ``` 5. 编写游戏代码:使用Java语言和Swing框架编写游戏代码,包括游戏主界面、游戏逻辑等。 ```java public class GameBoard extends JPanel implements ActionListener { private Timer timer; private List<EnemyPlane> enemyPlanes; private PlayerPlane playerPlane; public GameBoard() { setPreferredSize(new Dimension(600, 800)); setBackground(Color.WHITE); setFocusable(true); addKeyListener(new GameKeyListener()); playerPlane = new PlayerPlane(300, 700); enemyPlanes = new ArrayList<>(); for (int i = 0; i < 5; i++) { enemyPlanes.add(new EnemyPlane(50 + i * 100, 50)); } timer = new Timer(10, this); timer.start(); } @Override public void actionPerformed(ActionEvent e) { update(); repaint(); } private void update() { playerPlane.move(); for (EnemyPlane enemyPlane : enemyPlanes) { enemyPlane.move(); } checkCollision(); } private void checkCollision() { Rectangle playerRect = playerPlane.getRect(); for (EnemyPlane enemyPlane : enemyPlanes) { Rectangle enemyRect = enemyPlane.getRect(); if (playerRect.intersects(enemyRect)) { gameOver(); } } } private void gameOver() { timer.stop(); String userId = JOptionPane.showInputDialog("请输入您的用户名"); int score = playerPlane.getScore(); GameRecord gameRecord = new GameRecord(userId, score); HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest httpRequest = HttpRequest.newBuilder() .uri(URI.create("/api/gameRecords")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(new Gson().toJson(gameRecord))) .build(); try { HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); if (httpResponse.statusCode() == 200) { String message = "游戏结束,您的得分是:" + score; JOptionPane.showMessageDialog(null, message); } else { JOptionPane.showMessageDialog(null, "保存游戏记录失败"); } } catch (IOException | InterruptedException e) { JOptionPane.showMessageDialog(null, "保存游戏记录失败"); } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); playerPlane.draw(g); for (EnemyPlane enemyPlane : enemyPlanes) { enemyPlane.draw(g); } } private class GameKeyListener extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: playerPlane.setMoveLeft(true); break; case KeyEvent.VK_RIGHT: playerPlane.setMoveRight(true); break; case KeyEvent.VK_UP: playerPlane.setMoveUp(true); break; case KeyEvent.VK_DOWN: playerPlane.setMoveDown(true); break; case KeyEvent.VK_SPACE: playerPlane.fire(); break; } } @Override public void keyReleased(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: playerPlane.setMoveLeft(false); break; case KeyEvent.VK_RIGHT: playerPlane.setMoveRight(false); break; case KeyEvent.VK_UP: playerPlane.setMoveUp(false); break; case KeyEvent.VK_DOWN: playerPlane.setMoveDown(false); break; } } } } ``` 以上是一个简单的Java游戏飞机大战的实现思路和部分关键代码,供您参考。请注意,这只是一个简单的示例,实际项目中可能需要更多的功能和代码实现。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值