600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > java实现飞机大战小游戏(源码+注释)

java实现飞机大战小游戏(源码+注释)

时间:2021-04-01 22:47:39

相关推荐

java实现飞机大战小游戏(源码+注释)

整体的思路和博主其他博文java实现贪吃蛇小游戏(源码+注释)和java实现2048小游戏(源码+注释)是一样的,都是利用Frame创建窗体,利用Panel添加组件,提前规划好布局,调用鼠标和键盘监听,引用图片元素。

此处的思路在于不断的刷新敌机集合和子弹集合来实现动态效果。

文章目录

一.工程文件二.Main.java三.GameFrame.java四.GamePanel.java五.FlyObject.java六.Hero.java七.Ep.java八.Fire.java九.App.java十.效果演示

一.工程文件

二.Main.java

主函数,实现类

package ui;//主函数实现public class Main {public static void main(String[] args) {//创建窗体GameFrame frame = new GameFrame();//创建面板GamePanel panel = new GamePanel(frame);//调用开始游戏的方法启动游戏panel.action();//将面板加入到窗体中frame.add(panel);//设置窗体可见frame.setVisible(true);}}

三.GameFrame.java

窗体类,绘制窗体

package ui;import javax.swing.*;//创建窗体public class GameFrame extends JFrame {//构造方法,初始化窗体属性public GameFrame(){//设置标题,来源于JFramesetTitle("飞机大战");//设置大小setSize(512,768);//设置居中setLocationRelativeTo(null);//设置窗体可见//setVisible(true);//不允许玩家修改界面大小setResizable(false);//设置默认的关闭选项setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}

四.GamePanel.java

画布类,用于勾勒元素

package ui;import javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.image.BufferedImage;import java.util.ArrayList;import java.util.List;import java.util.Random;//自定义游戏面板(创建画布)public class GamePanel extends JPanel {//定义背景图BufferedImage bg;//构造游戏机Hero hero = new Hero();//敌机集合List<Ep> eps = new ArrayList<Ep>();//弹药集合List<Fire> fs = new ArrayList<Fire>();//定义分数int score;//设置游戏开关Boolean gameover=false;//设置火力int power = 1;//动作函数,描绘场景内飞行物的运动状态public void action(){//创建线程(基本模板)new Thread(){public void run(){//无线循环创建while (true){//判断如果游戏没有失败,则执行以下操作if(!gameover){//敌机进场epEnter();//调用敌机移动方法epMove();//发射子弹shoot();//子弹移动fireMove();//判断子弹是否击中敌机shootEp();//检测敌机是否撞到游戏机hit();}//每执行一次,线程休眠一会儿try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//重绘界面repaint();}}}.start();//让线程开始运行}//每执行20次,释放一个敌机,创建计数器计数int index = 0;protected void epEnter(){index++;//创建敌机if(index>=20){//创建敌机Ep e = new Ep();//加入集合eps.add(e);//重置计数器index = 0;}}//让敌机移动protected void epMove(){//遍历敌机集合,依次移动for (int i = 0; i < eps.size(); i++) {//获取集合中敌机Ep e = eps.get(i);//调用敌机类中的移动方法e.move();}}//每执行20次,创建一颗子弹,创建计数器计数int findex = 0;protected void shoot(){findex++;if(findex>=20){//根据火力判断子弹行数//一排子弹if(power==1){//创建子弹Fire fire1 = new Fire(hero.x+45,hero.y,1);//将子弹存入子弹集合中fs.add(fire1);}//两排子弹else if(power==2){//创建子弹Fire fire1 = new Fire(hero.x+15,hero.y,0);//将子弹存入子弹集合中fs.add(fire1);//创建子弹Fire fire2 = new Fire(hero.x+75,hero.y,2);//将子弹存入子弹集合中fs.add(fire2);}//三排子弹else{//创建子弹Fire fire1 = new Fire(hero.x+15,hero.y,0);//将子弹存入子弹集合中fs.add(fire1);//创建子弹Fire fire2 = new Fire(hero.x+75,hero.y,2);//将子弹存入子弹集合中fs.add(fire2);//创建子弹Fire fire3 = new Fire(hero.x+45,hero.y-10,1);//将子弹存入子弹集合中fs.add(fire3);}//使计数器归0findex = 0;}}//让子弹移动protected void fireMove(){//遍历子弹集合for (int i = 0; i < fs.size(); i++) {//获取每一颗子弹位置Fire f = fs.get(i);//依次移动每一颗子弹f.move();}}//判断子弹是否击中敌机protected void shootEp(){//遍历所有子弹for (int i = 0; i < fs.size(); i++) {//获取每一颗子弹Fire f = fs.get(i);//判断一颗子弹是否击中敌机bang(f);}}//判断一颗子弹是否击中敌机protected void bang(Fire f){for (int i = 0; i < eps.size(); i++) {//取出每一张敌机Ep e = eps.get(i);//判断这个子弹是否击中敌机if(e.shootBy(f)&&e.type!=15){//判断游戏机机是否击中道具机if(e.type==12){//火力增加power++;//如果火力值大于三,增加血量if(power>3){//恢复血量if(hero.hp<3){hero.hp++;}//使游戏机血量不超过3power = 3;}}//如果敌机被子弹击中//敌机消失eps.remove(e);//删除子弹fs.remove(f);//增加分数score += 10;}}}//检测敌机是否撞到主机protected void hit() {for (int i = 0; i < eps.size(); i++) {//获取每一个敌机Ep e = eps.get(i);//调用敌机的方法判断if(e.shootBy(hero)){//删除敌机eps.remove(e);//主机血量减少hero.hp--;//火力恢复初始值power = 1;//分数增加score += 10;//当主机血量减少到0时游戏结束if(hero.hp==0){gameover = true;}}}}//构造函数public GamePanel(GameFrame frame){//设置背景bg = App.getImg("/img/bg2.jpg");//创建鼠标监听和鼠标适配器MouseAdapter adapter = new MouseAdapter() {//点击鼠标时会执行的代码@Overridepublic void mouseClicked(MouseEvent e) {//游戏结束时候,点击屏幕时重新开始游戏if(gameover){//重新初始化主机hero = new Hero();//重置游戏开关gameover = false;//分数清0score = 0;//清空敌机集合eps.clear();//随机背景图Random random = new Random();int index = random.nextInt(5)+1;bg = App.getImg("/img/bg"+index+".jpg");//重新绘制repaint();}}//确定需要监听的事件,此处监听鼠标移动事件@Overridepublic void mouseMoved(MouseEvent e) {//让游戏机的横纵坐标等于鼠标的移动坐标//获取鼠标的横纵坐标int mx = e.getX();int my = e.getY();//传递坐标if(!gameover){//使鼠标坐标正好位于图片中央hero.moveToMouse(mx-114/2,my-93/2);}//重新绘制界面repaint();}};//将适配器加入到监听器中addMouseListener(adapter);addMouseMotionListener(adapter);//使用键盘监听,创建键盘适配器KeyListener kd = new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {}//当键盘被按下是触发@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();//上键if(keyCode == KeyEvent.VK_UP){hero.y-=10;}//下键else if(keyCode == KeyEvent.VK_DOWN){hero.y+=10;}//左键else if(keyCode == KeyEvent.VK_LEFT){hero.x-=10;}//右键else if(keyCode == KeyEvent.VK_RIGHT){hero.x+=10;}repaint();}@Overridepublic void keyReleased(KeyEvent e) {}};//将适配器加入窗体的监听器中frame.addKeyListener(kd);}//画图方法@Overridepublic void paint(Graphics g) {//调用父类中的一些渲染方法super.paint(g);//画背景g.drawImage(bg,0,0,null);//画敌机for (int i = 0; i < eps.size(); i++) {Ep ep = eps.get(i);g.drawImage(ep.img,ep.x,ep.y,null);}//画子弹for (int i = 0; i < fs.size(); i++) {Fire fire = fs.get(i);g.drawImage(fire.img,fire.x,fire.y,fire.w,fire.h,null);}//画分数g.setColor(Color.white);//设置字体型号,设置加粗,设置字体大小g.setFont(new Font("\u6977\u4F53",Font.BOLD,30));//显示分数g.drawString("分数:"+score,10,30);//画游戏机g.drawImage(hero.img,hero.x,hero.y,null);//画游戏机血量for (int i = 0; i < hero.hp; i++) {g.drawImage(hero.img,380+i*35,5,30,30,null);}//画游戏结束if(gameover){//设置字体颜色为红色g.setColor(Color.red);//设置字体型号,设置加粗,设置字体大小g.setFont(new Font("楷体",Font.BOLD,35));//显示字体g.drawString("GAMEOVER",170,300);//设置字体颜色为绿色g.setColor(Color.green);//设置字体型号,设置加粗,设置字体大小g.setFont(new Font("楷体",Font.BOLD,29));//显示字体g.drawString("yh提醒你点击屏幕任意位置重新开始",10,350);}//重新绘制界面repaint();}}

五.FlyObject.java

飞行物类,设定飞行物特性

package ui;import java.awt.image.BufferedImage;//飞行物具有共同特点,故抽离成父类public class FlyObject {//均采用照片素材BufferedImage img;//位置的横坐标int x;//位置的纵坐标int y;//图片元素的宽度int w;//图片元素的高度int h;}

六.Hero.java

主机类,设定游戏时候操控的飞机属性

package ui;import java.awt.image.BufferedImage;//游戏机public class Hero extends FlyObject{//设置游戏机血量int hp;//构造函数public Hero(){//获取游戏机元素img = App.getImg("/img/hero.png");//确认初始位置x = 200;y = 500;//获取游戏机图片元素的宽和高w = img.getWidth();h = img.getHeight();//设置初始血量为3hp = 3;}//根据传入参数移动相应位置public void moveToMouse(int mx,int my){x = mx;y = my;}}

七.Ep.java

敌机类

package ui;import javax.swing.*;import java.awt.image.BufferedImage;import java.util.ArrayList;import java.util.List;import java.util.Random;//敌机类public class Ep extends FlyObject{//设置敌机速度int sp;//设置敌机类型,不同的敌机类型有不同的属性int type;//构造函数public Ep(){//引入随机数随机调用敌机Random random = new Random();//调用[1,15]范围内的敌机int index = random.nextInt(15)+1;//保存敌机类型type = index;//如果序号小于10,则补充前导0,实质符合图片命名规律String path = "/img/ep" + (index<10?"0":"")+index+".png";//根据路径调用方法类函数获取图片io流img = App.getImg(path);//确定敌机位置//获取敌机照片元素宽度参数w = img.getWidth();//边界长减去照片宽度,防止照片越界x = random.nextInt(512-w);y = 0;//设置速度sp = 17-index;}//设置敌机移动方法public void move() {//如果敌机类型为5,则向左方倾斜移动if(type==5){x -= 5;y += sp;}//如果敌机类型为5,则向右方倾斜移动else if(type==6){x += 5;y += sp;}//如果是其他类型,则正常向下移动else {y+=sp;}}//判断敌机是否被子弹击中public boolean shootBy(Fire f) {//获取图片元素属性,确定相应的坐标算法,判断是否满足条件,满足则被击中Boolean hit = x <= f.x+f.w &&x>f.x-w&&y<=f.y+f.h&&y>f.y-h;return hit;}//判断敌机是否被玩家机击中public boolean shootBy(Hero f) {//获取图片元素属性,确定相应的坐标算法,判断是否满足条件,满足则被击中Boolean hit = x <= f.x+f.w &&x>f.x-w&&y<=f.y+f.h&&y>f.y-h;return hit;}}

八.Fire.java

子弹类

package ui;public class Fire extends FlyObject{//子弹当前移动方向,0为左上角飞,1垂直飞,2右上角飞int dir;//构造方法,初始化子弹public Fire(int hx,int hy,int dir){//获取子弹的图片img = App.getImg("/img/fire.png");//确定图片的大小,此处把子弹大小缩小了4倍w = img.getWidth()/4;h = img.getHeight()/4;//根据构造函数传进来的参数设置子弹的位置以及子弹的方向x = hx;y = hy;this.dir=dir;}//子弹的移动方法public void move() {//左上角飞if(dir==0){x -= 1;y -= 10;}//垂直上飞else if(dir == 1){y -= 10;}//右上角飞else if(dir == 2){x += 1;y -= 10;}}}

九.App.java

方法类

package ui;import javax.imageio.ImageIO;import javax.swing.*;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.InputStream;//处理图片的工具类//此处我定义了两种获取图片的方法,可以对照参考public class App {//static可以公用所有对象都共用该方法,并且可以不依赖对象实现public static BufferedImage getImg(String path){//用try方法捕获异常try {//io流,输送数据的管道BufferedImage img = ImageIO.read(App.class.getResource(path));return img;}//异常处理,打印异常catch (IOException e) {e.printStackTrace();}//没找到则返回空return null;}//此处与贪吃蛇小游戏的调用方法是一样的public static ImageIcon getImg2(String path){InputStream is;//从主类文件所在的路径寻找相应路径的图片is = App.class.getClassLoader().getResourceAsStream(path);//用try方法捕获异常try {return new ImageIcon(ImageIO.read(is));}//异常处理,打印异常catch (IOException e) {e.printStackTrace();}//没找到则返回空return null;}}

十.效果演示

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。