设计自己的小游戏-飞机大战奖励篇

在学习java基础知识后,根据网上飞机大战的内容和代码改变,设计出飞机大战的奖励篇小游戏,后期可将飞机大战和奖励篇等设计成一个完整游戏。

项目描述:
游戏开始,会出现若干蓝色空心圆形物体视为奖励道具会在界面中弹射,数量可以自行设定,控制飞机移动将奖励吃完,计算所用时间。
运行效果图:
在这里插入图片描述
游戏源码
游戏主窗口类:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;
 
/**
 * 游戏主窗口
 */
public class MyGameFrame extends JFrame {
 
    Image planeImg = GameUtil.getImage("images/plane.png");
    Image bg = GameUtil.getImage("images/bg.jpg");
 
    Plane p1 = new Plane(planeImg, 100, 100, 8);//飞机
 
    Bonus[] bonuses = new Bonus[10];//奖励道具
 
    Date start = new Date();//游戏开始的时间
    Date end;//游戏结束的时间:飞奖励吃完的那一刻
    long period = 0;//玩了多少秒
 
    @Override
    public void paint(Graphics g) {//g当做是一致画笔
        //画背景
        g.drawImage(bg,0,0,500,500,null);
 
        //画时间
        drawTime(g);
 
        //画飞机
        p1.drawMyself(g);
 
        //画奖励道具
        for (int i = 0; i<bonuses.length;i++){
            if(bonuses[i]!=null){
                bonuses[i].drawMyself(g);
 
                //碰撞检测。将所有的bonus和飞机进行检测,看有没有碰撞
                boolean peng = bonuses[i].getRec().intersects(p1.getRec());
                if (peng){
                    bonuses[i] = null;
                }
            }
        }
    }
 
    public void drawTime(Graphics g){//绘制时间的方法
        Color c = g.getColor();
        Font f = g.getFont();
 
        g.setColor(Color.green);
        if (!isNullOrEmptyArray(bonuses)){
            period = (System.currentTimeMillis()-start.getTime())/1000;
            g.drawString("游戏用时"+period+"秒",30,50);
        }else{
            if(end==null){
                end = new Date();
                period = (end.getTime()-start.getTime())/1000;
            }
 
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑", Font.BOLD, 30));
            g.drawString("游戏结束,最终所用时间:"+period+"秒", 45, 200);
        }
 
        g.setColor(c);
        g.setFont(f);
    }
 
    public static boolean isNullOrEmptyArray(Object[] array) {//判断奖励是否为空
        if(array == null) {
            return true;
        }
 
        if(array.length ==0) {
            return true;
        }
 
        boolean eachItemIsNull = true;
        for(Object item:array) {
            if(item != null) {
                eachItemIsNull = false;
            }
        }
        return eachItemIsNull;
    }
 
    //初始化窗口
    public void launchFrame(){
        this.setTitle("飞机大战-小夏沫");
        setVisible(true);//设置窗口是否可见
 
        setSize(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);//窗口大小
 
        setLocation(560,100);//窗口打开的位置
 
        //增加关闭窗口的动作
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);//正常退出程序
            }
        });
 
        new PaintThread().start();//启动窗画窗口的线程
        this.addKeyListener(new KeyMonitor());//启动键盘监听
 
        //初始化创建bonus对象
        for (int i =0;i<bonuses.length;i++){
            bonuses[i] = new Bonus();
        }
    }
 
    /**
     * 定义一个重画窗口的线程类
     * 定义成内部类是为了方便直接使用窗口类的相关方法
     */
    class PaintThread extends Thread{
        @Override
        public void run() {
            while(true){
                repaint();//内部类可以直接使用外部类的成员
 
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 
    //内部类,实现键盘的监听处理
    class KeyMonitor extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e) {
            p1.addDirection(e);
        }
 
        @Override
        public void keyReleased(KeyEvent e) {//        
            p1.minusDirection(e);
        }
    }
 
    private Image offScreenImage = null;
 
    public void update(Graphics g){
        if(offScreenImage==null){
            offScreenImage = this.createImage(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);//游戏窗口的宽度和高度
        }
 
        Graphics gOff = offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage, 0, 0, null);
    }
 
    public static void main(String[] args) {
        MyGameFrame gameFrame = new MyGameFrame();
        gameFrame.launchFrame();
    }
}

飞机类:

import java.awt.*;
import java.awt.event.KeyEvent;
 
public class Plane extends GameObject{
 
    boolean left, right, up, down;//飞机的方向控制
 
    @Override
    public void drawMyself(Graphics g) {
 
        super.drawMyself(g);
 
            //飞机飞行的算法,可以自行设定
//        x+=speed;
        if(left){
            x -= speed;
        }
        if(right){
            x += speed;
        }
        if(up){
            y -= speed;
        }
        if(down){
            y += speed;
        }
 
    }
 
    public void addDirection(KeyEvent e){
        switch(e.getKeyCode()){
            case KeyEvent.VK_LEFT:
                left = true;
                break;
            case KeyEvent.VK_RIGHT:
                right = true;
                break;
            case KeyEvent.VK_UP:
                up = true;
                break;
            case KeyEvent.VK_DOWN:
                down = true;
                break;
        }
    }
 
    public void minusDirection(KeyEvent e){
        switch (e.getKeyCode()){
            case KeyEvent.VK_LEFT:
                left = false;
                break;
            case KeyEvent.VK_RIGHT:
                right = false;
                break;
            case KeyEvent.VK_UP:
                up = false;
                break;
            case KeyEvent.VK_DOWN:
                down = false;
                break;
        }
    }
 
    public Plane(Image img, double x, double y, int speed) {
        super(img, x, y, speed);
    }
}

常数类:

public class Constant {
    //游戏窗口的宽度和高度
    public static final int GAME_WIDTH = 500;
    public static final int GAME_HEIGHT = 500;
 
}

奖励类:

import java.awt.*;
 
public class Bonus extends GameObject {
 
    double degree;//角度。炮弹沿着指定的角度飞行
 
    public Bonus(){
        x=200;
        y=300;
 
        degree = Math.random()*Math.PI*2;
 
        width = 10;
        height = 10;
 
        speed = 6;
    }
 
    @Override
    public void drawMyself(Graphics g) {
        Color c= g.getColor();//保存原来的颜色
 
        g.setColor(Color.CYAN);//设置画笔为青色
        g.drawOval((int)x,(int)y,width,height);
 
        g.setColor(c);//还原为原来的颜色
        //根据自己的算法指定移动的路径
        x += speed*Math.cos(degree);
        y += speed*Math.sin(degree);
 
        //碰到边界改变方向
        if(y>Constant.GAME_HEIGHT-this.height-9||y<35){
            degree = -degree;
        }
 
        if(x<10||x>Constant.GAME_WIDTH-this.width-9){
            degree = Math.PI-degree;
        }
    }
}

游戏根类:

import java.awt.*;
 
/**
 * 游戏物体的根类
 */
public class GameObject {
 
    Image img;          //图片
    double x,y;         //物体的坐标
    int speed;          //物体移动的速度
    int width,height;   //物体的宽度和高度
 
    public GameObject(Image img, double x, double y, int speed) {
        this.img = img;
        this.x = x;
        this.y = y;
        this.speed = speed;
 
        this.width = img.getWidth(null);
        this.height = img.getHeight(null);
    }
 
    public GameObject(){}
 
    public void drawMyself(Graphics g){
        g.drawImage(img, (int)x, (int)y, width, height, null);
    }
 
    //所有的物体都是矩形。当你获得对应的矩形的时候,我们就可以做一些相关的判断操作!
    public Rectangle getRec(){
        return new Rectangle((int)x, (int)y, width, height);
    }
}

工具类(加载图片):

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
 
/**
 * 游戏的工具类
 */
public class GameUtil {
 
    //构造器私有,防止别人创建本类的对象
    private GameUtil(){
    }
 
    public static Image getImage(String path){
        BufferedImage img = null;
        URL u = GameUtil.class.getClassLoader().getResource(path);
        try {
            img = ImageIO.read(u);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return img;
    }
}

eg:仅为练习代码,游戏过程中可能会出现bug,代码有待完善。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值