飞机小项目(java入门和对象练习)

  1. 继承Frame绘制类

  2. 初始化窗口
    设置标题、宽高、位置
    添加窗口监听器,当达到某个条件时,将窗口关闭

  3. 图形和文本绘制

    使用print()函数绘制图形和文本

    imageIO实现图片加载技术

  4. 多线程重画窗口

  5. 设置飞机坐标移动

  6. 面向对象思想设计游戏物体类、飞机类

  7. 加入键盘键位控制,启动键盘监听,关联飞机移动位置

  8. 炮弹设计

  9. 增加双闪烁解决方案

  10. 矩形边界碰撞检测

  11. 爆炸效果实现

  12. 飞机死亡和计时功能

附代码

package org.jinjin.game;

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Date;

/**
 * 飞机小游戏
 * 实现效果
 *     使用windows窗口实现,小飞机可以通过键盘键位控制,
 *     初始产生随机方向炮弹,当炮弹碰撞到边界时会自动回弹,
 *     当小飞机碰撞到炮弹时,小飞机爆炸,显示小飞机存活时间
 *  1.绘制窗口--完成
 *  2.将背景图片和小飞机图片加载到窗口中--完成
 *  3.使小飞机可以通过键位控制进行位置移动--完成
 *  4.炮弹设计以及边界回弹--完成
 *  5.碰撞后小飞机爆炸效果--完成
 *  6.碰撞后时间显示--完成
 *  7.新增游戏开始操作--完成
 */
public class MyGameFrame extends Frame {

    Image planeImg=GameImgUtil.getImage("images/plane.png");
    Image bgImg=GameImgUtil.getImage("images/bg.jpg");

    BackGround bg=new BackGround(bgImg,0,0);
    Plane plane = new Plane(planeImg,400,400);
    Shell[] shells = new Shell[50];
    Explode bao;

    Date startTime=new Date();
    Date endTime;
    int period;
    boolean isStart=false;

    //2.将背景图片和小飞机图片加载到窗口中
    boolean peng=false;
    @Override
    public void paint(Graphics g) {
        System.out.println("绘制一次窗口");
        //绘制图片背景
        bg.drawSelf(g);

        if(!isStart){
            Color c = g.getColor();
            g.setColor(Color.WHITE);
            g.setFont(new Font("宋体", Font.BOLD,40));
            g.drawString("按下enter键开始游戏",(int)Constant.WIDTH/3,(int)Constant.HEIGHT/2);
            g.setColor(c);
        }else{
            //绘制飞机
            plane.drawSelf(g);
            //绘制炸弹
            for (int i = 0; i < shells.length; i++) {
                shells[i].draw(g);
                //碰撞条件
                peng = shells[i].getRect().intersects(plane.getRect());
                if(peng){
                    shells=new Shell[0];
                    endTime=new Date();
                    period= (int)((endTime.getTime()-startTime.getTime())/1000);
                    break;
                }
            }
            if(peng){
                plane.live=false;
                if(bao==null){
                    bao=new Explode(plane.x,plane.y);
                }
                bao.draw(g);
                Color c = g.getColor();
                g.setColor(Color.RED);
                g.setFont(new Font("宋体", Font.BOLD,50));
                g.drawString("您存活了"+period+"秒",(int)Constant.WIDTH/3,(int)Constant.HEIGHT/2);
                g.setColor(c);
            }
        }
    }


    //1.绘制窗口以及窗口刷新
    public void launchFrame(){
        //绘制窗口要素
        this.setTitle("飞机小游戏");
        this.setVisible(true);
        this.setSize(Constant.WIDTH,Constant.HEIGHT);
        this.setLocation(300,50);
        //添加窗口监听
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                //手动点击窗口上的X,程序监听到窗口关闭,则关闭程序
                System.exit(0);
            }
        });
        //添加窗口自动刷新
        new PaintThread().start();
        //添加按键监听
        addKeyListener(new keyMonitor());
        //添加50个炮弹
        for (int i = 0; i < 50; i++) {
            shells[i]=new Shell();
        }
    }

    private Image offScreenImage = null;
    public void update(Graphics g) {
        if(offScreenImage == null)
            offScreenImage = this.createImage(Constant.WIDTH,Constant.HEIGHT);

        Graphics gOff = offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage, 0, 0, null);
    }

    class PaintThread extends Thread{
        @Override
        public void run() {
            while (true){
                repaint();
                try {
                    Thread.sleep(40);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class keyMonitor extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e) {
            plane.addDirection(e);
            if(e.getKeyCode()== KeyEvent.VK_ENTER&!isStart){
                isStart=true;
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            plane.minusDirection(e);
        }
    }

    public static void main(String[] args) {
        MyGameFrame myGameFrame = new MyGameFrame();
        myGameFrame.launchFrame();
    }

}
package org.jinjin.game;

import javax.imageio.ImageIO;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class GameImgUtil {
    private GameImgUtil(){}

    public static Image getImage(String filePath){
        BufferedImage read = null;
        try {

            URL resource = new File(filePath).toURL();
//            URL resource = GameImgUtil.class.getClassLoader().getResource(filePath);
            System.out.println("根据'"+filePath+"'当前获取到的图片路径为:"+resource.toString());
            read = ImageIO.read(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return read;
    }
}
package org.jinjin.game;

public class Constant {
    static int WIDTH=900;
    static int HEIGHT=900;
}
package org.jinjin.game;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;

public class GameObject {
    Image img;
    double x,y;
    int speed;
    int width;
    int height;

    public void drawSelf(Graphics g){
        g.drawImage(img,(int)x,(int)y,null);
    }
    public Rectangle getRect(){
        return new Rectangle((int)x,(int)y,width,height);
    }

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

    public GameObject(Image img, double x, double y) {
        this.img = img;
        this.x = x;
        this.y = y;
    }

    public GameObject() {
    }
}
package org.jinjin.game;

import java.awt.Image;

public class BackGround extends GameObject{
    public BackGround(Image img, double x, double y) {
        super(img, x, y);
    }
}
package org.jinjin.game;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;

public class Plane extends GameObject{
    boolean left,up,right,down;
    boolean live=true;
    public Plane(Image img, double x, double y) {
        this.img=img;
        this.x=x;
        this.y=y;
        this.speed = 5;
        this.width=img.getWidth(null);
        this.height=img.getHeight(null);
    }

    @Override
    public void drawSelf(Graphics g) {
        if(live){
            super.drawSelf(g);
            if(left&&x>0+width/2){
                x-=speed;
            }
            if(right&&x<Constant.WIDTH-width/2*3){
                x+=speed;
            }
            if(up&&y>32){
                y-=speed;
            }
            if(down&&y<Constant.HEIGHT-height/2*3){
                y+=speed;
            }
        }
    }

    public void addDirection(KeyEvent e) {
        switch (e.getKeyCode()){
            case KeyEvent.VK_LEFT:left=true;break;
            case KeyEvent.VK_UP:up=true;break;
            case KeyEvent.VK_RIGHT:right=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_UP:up=false;break;
            case KeyEvent.VK_RIGHT:right=false;break;
            case KeyEvent.VK_DOWN:down=false;break;
        }
    }
}
package org.jinjin.game;

import java.awt.Color;
import java.awt.Graphics;

public class Shell extends GameObject{
    double degree;

    public Shell(){
        x=200;
        y=200;
        width=10;
        height=10;
        speed=3;
        degree= Math.random()*Math.PI*2;
    }

    public void draw(Graphics g){
        Color c = g.getColor();
        g.setColor(Color.YELLOW);

        g.fillOval((int)x,(int)y,width,height);

        x+=speed*Math.cos(degree);
        y+=speed*Math.sin(degree);

        if(x<0||x>Constant.WIDTH-width){
            degree = Math.PI - degree;
        }

        if(y<30||y>Constant.HEIGHT-height){
            degree = -degree;
        }
        g.setColor(c);
    }
}
package org.jinjin.game;

import java.awt.Graphics;
import java.awt.Image;

public class Explode{
    double x,y;
    static Image[] imgs=new Image[16];
    static {
        for (int i = 0; i < 16; i++) {
            imgs[i] = GameImgUtil.getImage("images/explode/e"+(i+1)+".gif");
            imgs[i].getWidth(null);
        }
    }
    public Explode(double x,double y){
        this.x = x;
        this.y = y;
    }

    int count;
    public void draw(Graphics g){
        if(count<=15){
            g.drawImage(imgs[count], (int)x,(int)y,null);
            count++;
        }
    }
}

附游戏效果图
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雄行天下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值