Java程序设计-飞机大战

项目简介

团队选择难度为B等级的任务小游戏,一方面是因为其难度尚可,值得一试,另一方面也是因为两人对其的兴趣不小,对于项目的热情很高,同时也对于我们基础知识的巩固复习有好处。在几周的空余时间里,我和队员完成了这个项目,其中不足之处还请老师批评指正。

项目关键技术

java变量、java数据类型、判断语句、循环结构、数组、Java集合、简单窗口创建、图形图片绘制、双缓存技术、事件-鼠标和键盘事件、物体的碰撞检测。awt抽象窗口工具包、部分复杂算法、大部分注释、GUI界面、面向对象程序设计、线程等

开发环境:jdk11

开发工具:eclipse

项目需求分析

1.简单易懂的玩法,作为小游戏,能够激发玩家的兴趣

2.能够用鼠标进行流利地操作(灵活左右移动躲避敌机及子弹)

 

项目亮点: 1、充分发挥鼠标事件实现流利操作2.碰撞检测

a08ac4b73aef47bea05f8fb0cb713ddd.png

 

功能截图演示部分:

f9866fe7d99d44f4bbb1cf42cbbbcf65.png

db26a7a34fd34f55bacc227191891b4f.png

f9d2feb672114165b3f057892d935164.png

e1b4db1c8dcb4527ae00616c4ed47b2b.png

 

 

任务分配:

位置姓名任务分配
组长

1.负责团队博客创建及书写整理 、任务分配和团队答辩筹备,对于组员进行相关内容的教导

2.负责游戏基类的编写(子弹类,敌我战机类,使用鼠标控制战机移动)等代码的构建

 

组员

1、负责git仓库创建和游戏素材(背景图,子弹飞机的生成)搜寻并添加创意,并对于博客进行补充,和相关疑难问题的解决

2、负责游戏设置规则类(使用空格游戏暂停,通关条件)和工具类的编写以及游戏相关内容的补充,同时对于整体代码bug漏洞进行检查

 

 

项目git地址:https://gitee.com/south-of-the-south-bank/planewar

 

git提交记录:f5e081f7ab7f4836b5e115efcc9329c6.png

 58b397b7588a4c048427c2843575bf30.png

 代码静态扫描

f1c4ed3801834b6597efffa6f1b75752.jpeg

 代码内容基本符合规范

 

 

代码部分:

GameUI

package main;


import obj.*;
import utils.GameUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class GameWin extends JFrame {

	private static final long serialVersionUID = 7429332630858909252L;
	//游戏状态 0未开始 1游戏中 2暂停 3.通关失败 4.通关成功
	//定义默认状态
    public static int state = 0;
    //游戏得分
    public static int score = 0;
    //双缓存的图片
    Image offScreenImage = null;
    //窗口的宽度
    int width = 600;
    //窗口的高度
    int height = 600;
    //游戏的重绘次数
    int count = 1;
    //敌机出现的数量
    int enemyCount = 0;
    //背景图对象
    BgObj bgObj = new BgObj(GameUtils.bgImg,0,-2000,2);
    //我方飞机对象
    public PlaneObj planeObj = new PlaneObj(GameUtils.planeImg,290,550,20,30,0,this);
    //敌方boss对象
    public BossObj  bossObj = null;
    //启动方法
    public void launch(){
        //设置窗口是否可见
        this.setVisible(true);
        //设置窗口大小
        this.setSize(width,height);
        //设置窗口位置
        this.setLocationRelativeTo(null);
        //设置窗口标题
        this.setTitle("飞机大战 by张、盘");

        GameUtils.gameObjList.add(bgObj);
        GameUtils.gameObjList.add(planeObj);

        //添加鼠标点击事件
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == 1 && state == 0){
                	//游戏开始
                    state = 1;
                }
            }
        });

        //添加用于暂停的键盘监听事件
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
            	//点击空格键
                if (e.getKeyCode() == 32){
                    switch (state){
                        case 1:
                            state = 2;
                            break;
                        case 2:
                            state = 1;
                            break;
                            default:
                    }
                }
            }
        });

        //背景图的不断绘制
        while (true){
            if (state == 1){
                createObj();
                repaint();
            }
            try {
            	//每间隔25毫秒调用一次方法
                Thread.sleep(25);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics g) {
    	//初始化
        if (offScreenImage == null){
            offScreenImage = createImage(width,height);
        }
        //获取offScreenImage的画笔对象
        Graphics gImage = offScreenImage.getGraphics();
        //填充区域
        gImage.fillRect(0,0,width,height);
        if (state == 0){
            //未开始
        	//用画笔g绘制图片:背景、boss、爆炸特效
            gImage.drawImage(GameUtils.bgImg,0,0,null);
            gImage.drawImage(GameUtils.bossImg,220,120,null);
            gImage.drawImage(GameUtils.explodeImg,270,350,null);
            //开始界面
            GameUtils.drawWord(gImage,"点击开始游戏",Color.red,40,180,300);
        }
        if (state == 1){
            GameUtils.gameObjList.addAll(GameUtils.explodeObjList);
            //运行中,遍历
            for (int i = 0; i < GameUtils.gameObjList.size(); i++) {
                GameUtils.gameObjList.get(i).paintSelf(gImage);
            }
            //下一次绘制之前删除的元素
            GameUtils.gameObjList.removeAll(GameUtils.removeList);
        }
        if (state == 3){
            //失败
            gImage.drawImage(GameUtils.explodeImg,planeObj.getX()-35,planeObj.getY()-50,null);
            GameUtils.drawWord(gImage,"你失败了!",Color.red,50,180,300);
        }
        if (state == 4){
            //通关
            gImage.drawImage(GameUtils.explodeImg,bossObj.getX() + 30,bossObj.getY(),null);
            GameUtils.drawWord(gImage,"恭喜通关!",Color.green,50,190,300);
        }
        //绘制计分板
        GameUtils.drawWord(gImage,score+" 分",Color.green,40,30,100);
        g.drawImage(offScreenImage,0,0,null);
        count++;
        //打印gameObjList的长度
        System.out.println(GameUtils.gameObjList.size());
    }

    void createObj() {
        /*我方子弹
    	控制子弹生成速度
    	每调用15次paint方法生成一颗子弹*/
        if (count % 15 == 0){
            GameUtils.shellObjList.add(new ShellObj(GameUtils.shellImg, planeObj.getX() + 3, planeObj.getY() - 16, 14, 29, 5, this));
            GameUtils.gameObjList.add(GameUtils.shellObjList.get(GameUtils.shellObjList.size() - 1));
        }
        //创建敌机
        if (count % 15 == 0){
            GameUtils.enemyObjList.add(new EnemyObj(GameUtils.enemyImg,(int)(Math.random()*12)*50,0,49,36,5,this));
            GameUtils.gameObjList.add(GameUtils.enemyObjList.get(GameUtils.enemyObjList.size() -1));
            enemyCount++;
        }
        //敌机子弹
        if (count % 15 == 0 && bossObj != null){
            GameUtils.bulletObjList.add(new BulletObj(GameUtils.bulletImg,bossObj.getX()+76,bossObj.getY()+85,15,25,5,this));
            GameUtils.gameObjList.add(GameUtils.bulletObjList.get(GameUtils.bulletObjList.size() - 1));
        }
        //控制boss出现条件
        if (enemyCount > 10 && bossObj == null){
            bossObj = new BossObj(GameUtils.bossImg,250,35,155,100,5,this);
            GameUtils.gameObjList.add(bossObj);
        }
    }
    public static void main(String[] args) {
        GameWin gameWin = new GameWin();
        gameWin.launch();
    }



}

飞行物父类

package obj;

import main.GameWin;

import java.awt.*;

public class GameObj {
	//物体基本属性的定义:图片、坐标、宽高、移速、窗口的引用
    Image img;//定义Imag类型的静态数组
    int x;
    int y;
    int width;
    int height;
    double speed;
    GameWin frame;

    public Image getImg() {
        return img;
    }

    public void setImg(Image img) {
        this.img = img;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public GameWin getFrame() {
        return frame;
    }

    public void setFrame(GameWin frame) {
        this.frame = frame;
    }

    public GameObj() {
    }

    public GameObj(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public GameObj(Image img, int x, int y, double speed) {
        this.img = img;
        this.x = x;
        this.y = y;
        this.speed = speed;
    }

    public GameObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        this.img = img;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.speed = speed;
        this.frame = frame;
    }
    //绘制自身的方法
    public void paintSelf(Graphics gImage){
        gImage.drawImage(img,x,y,null);
    }
    //获取自身矩形,用于碰撞检测
    public Rectangle getRec(){
        return new Rectangle(x,y,width,height);
    }
}

己方战机

package obj;

import main.GameWin;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class PlaneObj extends GameObj {
    @Override
    public Image getImg() {
        return super.getImg();
    }

    public PlaneObj() {
        super();
    }

    public PlaneObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
        //鼠标滚动事件
        this.frame.addMouseMotionListener(new MouseAdapter() {
            @Override
            //飞机的横纵坐标等于鼠标光标的横纵坐标减去飞机宽高的一半
            public void mouseMoved(MouseEvent e) {
                PlaneObj.super.x = e.getX() - 11;
                PlaneObj.super.y = e.getY() - 16;
            }
        });
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        //我方飞机与敌方boss的碰撞检测
        if (this.frame.bossObj != null && this.getRec().intersects(this.frame.bossObj.getRec())){
            GameWin.state = 3;
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

敌机

package obj;

import main.GameWin;
import utils.GameUtils;

import java.awt.*;

public class ShellObj extends GameObj {
    @Override
    public Image getImg() {
        return super.getImg();
    }

    public ShellObj() {
        super();
    }

    public ShellObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        //实现子弹的移动
        y -= speed;
        //我方子弹的越界消失;条件 y < 0 ;改变后的坐标 (-100,100)
        if (y < 0){
            this.x = -100;
            this.y = 100;
            GameUtils.removeList.add(this);
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

敌机

package obj;

import main.GameWin;
import utils.GameUtils;

import java.awt.*;

public class EnemyObj extends GameObj {

    public EnemyObj() {
        super();
    }

    public EnemyObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        //敌机坐标
        y += speed;
        //敌我飞机碰撞检测
        if (this.getRec().intersects(this.frame.planeObj.getRec())){
        	//游戏失败
            GameWin.state = 3;
        }
        //敌机的越界消失;判断条件 y > 600 ;改变后的坐标(-200,-200)
        if (y > 600){
            this.x = -200;
            this.y = 200;
            GameUtils.removeList.add(this);
        }
        //敌机消失前移动到(-200,-200)  我方子弹(-100,100)
        //将this与每一个shellobj进行碰撞检测
        for (ShellObj shellObj: GameUtils.shellObjList) {
            if (this.getRec().intersects(shellObj.getRec())){
            	//创造爆炸效果
                ExplodeObj explodeObj = new ExplodeObj(x,y);
                GameUtils.explodeObjList.add(explodeObj);
                GameUtils.removeList.add(explodeObj);
                //改变碰撞敌机的坐标
               shellObj.setX(-100);
               shellObj.setY(100);
               this.x = -200;
               this.y = 200;
               GameUtils.removeList.add(shellObj);
               GameUtils.removeList.add(this);
               GameWin.score++;
            }
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

子弹类

package obj;

import main.GameWin;
import utils.GameUtils;

import java.awt.*;

public class ShellObj extends GameObj {
    @Override
    public Image getImg() {
        return super.getImg();
    }

    public ShellObj() {
        super();
    }

    public ShellObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        //实现子弹的移动
        y -= speed;
        //我方子弹的越界消失;条件 y < 0 ;改变后的坐标 (-100,100)
        if (y < 0){
            this.x = -100;
            this.y = 100;
            GameUtils.removeList.add(this);
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}
package obj;

import main.GameWin;
import utils.GameUtils;

import java.awt.*;

public class BulletObj extends GameObj {
    public BulletObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        //子弹速度
        y += speed;
        //敌方子弹与我方飞机的碰撞检测
        if (this.getRec().intersects(this.frame.planeObj.getRec())){
            GameWin.state = 3;
        }
        //敌方子弹的越界消失;条件 y > 600 ;改变后的坐标(-300,300)
        if (y > 600){
            this.x = -300;
            this.y = 300;
            GameUtils.removeList.add(this);
        }
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

背景图循环

package obj;

import java.awt.*;

public class BgObj extends GameObj {
    public BgObj() {
        super();
    }

    public BgObj(Image img, int x, int y, double speed) {
        super(img, x, y, speed);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        y += speed;
        //背景图的循环
        if (y >= 0){
            y = -2000;
        }
    }
}

BOOS类

package obj;

import main.GameWin;
import utils.GameUtils;

import java.awt.*;

public class BossObj extends GameObj {

    int life = 10;

    public BossObj(Image img, int x, int y, int width, int height, double speed, GameWin frame) {
        super(img, x, y, width, height, speed, frame);
    }

    @Override
    public void paintSelf(Graphics gImage) {
        super.paintSelf(gImage);
        //对于boss移动距离的限定
        if (x > 550 || x < -50){
            speed = -speed;
        }
        //实现boss的移动
        x += speed;
        //boss与己方子弹的碰撞检测
        for (ShellObj shellObj : GameUtils.shellObjList){
            if (this.getRec().intersects(shellObj.getRec())){
            	//删除碰撞后的子弹
                shellObj.setX(-100);
                shellObj.setY(100);
                GameUtils.removeList.add(shellObj);
                life--;
            }
            if (life <= 0){
            	//通关
                GameWin.state = 4;
            }
        }
        //血条白色背景
        gImage.setColor(Color.white);
        gImage.fillRect(20,40,100,10);
        //绘制血条
        gImage.setColor(Color.red);
        gImage.fillRect(20,40,life * 100 / 10,10);
    }

    @Override
    public Rectangle getRec() {
        return super.getRec();
    }
}

工具类

package utils;


import obj.*;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class GameUtils {
    //背景图片
    public static Image bgImg = Toolkit.getDefaultToolkit().getImage("imgs/bg.jpg");
    //boss图片
    public static Image bossImg = Toolkit.getDefaultToolkit().getImage("imgs/boss.png");
    //爆炸图片
    public static Image explodeImg = Toolkit.getDefaultToolkit().getImage("imgs/explode/e6.gif");
    //我方战机图片
    public static Image planeImg = Toolkit.getDefaultToolkit().getImage("imgs/plane.png");
    //我方子弹图片
    public static Image shellImg = Toolkit.getDefaultToolkit().getImage("imgs/shell.png");
    //敌方子弹图片
    public static Image bulletImg = Toolkit.getDefaultToolkit().getImage("imgs/bullet.png");
    //敌机图片
    public static Image enemyImg = Toolkit.getDefaultToolkit().getImage("imgs/enemy.png");

    //所有游戏物体的集合
    public static List<GameObj> gameObjList = new ArrayList<>();
    //要删除元素的集合
    public static List<GameObj> removeList = new ArrayList<>();
    //我方子弹的集合
    public static List<ShellObj> shellObjList = new ArrayList<>();
    //敌方子弹的集合
    public static List<BulletObj> bulletObjList = new ArrayList<>();
    //敌机的集合
    public static List<EnemyObj> enemyObjList = new ArrayList<>();
    //爆炸的集合
    public static List<ExplodeObj> explodeObjList = new ArrayList<>();

    //绘制字符串的工具类
    public static void drawWord(Graphics gImage,String str,Color color,int size,int x,int y){
        gImage.setColor(color);
        gImage.setFont(new Font("黑体",Font.BOLD,size));
        gImage.drawString(str,x,y);
    }
}

爆炸类

import java.awt.*;

public class ExplodeObj extends GameObj {

    static Image[] pic = new Image[16];
    //限制爆炸效果
    int explodeCount = 0;
    //将imgs中图片添加到静态数组
    static {
        for (int i = 0; i < pic.length; i++) {
            pic[i] = Toolkit.getDefaultToolkit().getImage("imgs/explode/e"+(i+1)+".gif");
        }
    }

    public ExplodeObj(int x, int y) {
        super(x, y);
    }

    @Override
    public void paintSelf(Graphics gImage) {
    	//限制爆炸效果出现的次数
        if (explodeCount < 16){
            super.img = pic[explodeCount];
            super.paintSelf(gImage);
            explodeCount++;
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值