飞机游戏代码(JAVA)

MyGameFrame类:

主要的调用类

package sc.wh.game;

import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import sc.wh.game.*;
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 Frame {
    
    
	// 调用工具类的getImage方法加载图片对象
	Image planeImg = GameUtil.getImage("images/plane.png");
	Image bg = GameUtil.getImage("images/bg.jpg");
	
	// 创建飞机,设置初始位置
	Plane plane = new Plane(planeImg,250,250);
	// 创建炮弹组
	Shell shells[] = new Shell[50];
	// 设置爆炸效果类的对象的引用
	Explode bao;
	// 游戏开始时间
	Date startTime = new Date();
	// 游戏结束时间
	Date endTime;
	// 游戏进行的时间
	int period;
	// 记录爆炸效果显示的图片
	int BaoCount = 0;
	
	// 在窗口画图方法,由repaint方法自动调用
	@Override
	public void paint(Graphics g) {
    
     // 会自动被调用,g相当于一支画笔
		Color c = g.getColor();
		// 画背景
		g.drawImage(bg,0,0,null);
		// 调用飞机类的画图方法并画飞机
		plane.drawSelf(g);
		// 画炮弹组中的炮弹
		for (int i=0;i<shells.length;i++) {
    
    
			// 调用炮弹对象的draw方法
			shells[i].draw(g);
			// 获取炮弹所在矩形位置并调用intersects判断两矩形是否相交
			boolean peng =  shells[i].getRect().intersects(plane.getRect());
			if(peng) {
    
    
				// 如果相交则设置飞机存活状态为false
				plane.live = false;
				// 如果bao对象没有初始化过则才初始化
				if(bao == null) {
    
    
					bao = new Explode(plane.x, plane.y);
					endTime = new Date();
					period = (int)(endTime.getTime() - startTime.getTime())/1000;
				}
				if(BaoCount <= 15) {
    
    
					// 调用爆炸效果显示类的画图方法,每次调用只画一张图
					bao.draw(g);
					BaoCount++;
				}
				
			}
			// 如果飞机未存活则显示游戏时间
			if(!plane.live) {
    
    
				// 创建字体对象
				Font f = new Font("宋体",Font.BOLD,50);
				// 设置字体
				g.setFont(f);
				// 设置字体颜色
				g.setColor(Color.RED);
				// 显示游戏结束时间
				g.drawString("游戏时间:" + period + "秒", 100, 250);
			}
		}
		g.setColor(c);
	}
	
	// 继承Thread线程类
	class PaintThread extends Thread{
    
    
		// 线程开始后会自动调用run方法
		@Override
		public void run() {
    
    
			while (true) {
    
    
				// 调用repaint窗口画图方法,此方法会自动调用paint方法
				repaint(); 
				try {
    
    
					// 控制一秒25次在窗口画图的方法
					Thread.sleep(40);
				} catch (InterruptedException e) {
    
    
					e.printStackTrace();
				}
			}
			
		}
	}
	// 创建键盘检测内部类,并继承键盘监听类
	class KeyMonitor extends KeyAdapter{
    
    

		// 检测键盘按下事件,调用飞机类对应的方法
		@Override
		public void keyPressed(KeyEvent e) {
    
    
			// KeyEvent键盘检测类
			plane.addDirection(e);
		}
		// 检测键盘释放事件,调用飞机类对应的方法
		@Override
		public void keyReleased(KeyEvent e) {
    
    
			plane.minusDirection(e);
		}
		
	}
	
	// 双缓冲解决闪烁
	private Image offScreenImage = null;
	public void update(Graphics g) {
    
    
	    if(offScreenImage == null)
	        offScreenImage = this.createImage(Constants.WIDTH,Constants.HEIGHT);//这是游戏窗口的宽度和高度
	     
	    Graphics gOff = offScreenImage.getGraphics();
	    paint(gOff);
	    g.drawImage(offScreenImage, 0, 0, null);
	}   
	
    public void launchFrame(){
    
    
        // 标题
        this.setTitle("game fly");
        // 窗口默认不可见
        this.setVisible(true);
        // 窗口大小
        this.setSize(Constants.WIDTH,Constants.HEIGHT);
        // 窗口距离左上角的坐标位置
        this.setLocation(300,300);
        //增加关闭窗口监听,这样用户点击右上角关闭图标,可以关闭游戏程序
        this.addWindowListener(new WindowAdapter() {
    
    
            @Override
            public void windowClosing(WindowEvent e){
    
    
                System.exit(0);
            }
        });
        
        // 创建在窗口中画图线程并调用
        new PaintThread().start();
        // 将KeyMonitor类的对象加入键盘监控检测,对应的事件会自动调用此类对应的方法
        addKeyListener(new KeyMonitor());
        // 创建炮弹,加入炮弹数组
        for(int i=0;i<shells.length;i++) {
    
    
        	shells[i] = new Shell();
        }
        
    }

    public static void main(String[] args) {
    
    
        MyGameFrame f = new MyGameFrame();
        // 调用画窗口方法
        f.launchFrame();
    }
}

工具类(用来获取图片对象):

package sc.wh.game;
 
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
 
public class GameUtil {
    
    
    // 工具类最好将构造器私有化。
    private GameUtil() {
    
    
     
    } 
 
    public static Image getImage(String path) {
    
    
        BufferedImage bi = null;
        try {
    
    
            URL u = GameUtil.class.getClassLoader().getResource(path);
            bi = ImageIO.read(u);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return bi;
    }
}

用来存储常量的类:

package sc.wh.game;

public class Constants {
    
    
	public static int WIDTH = 500;
	public static int HEIGHT = 500;
}

所有游戏对象的父类:

package sc.wh.game;

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

// 游戏父类
public class GameObject {
    
    
	Image img;  // 创建img对象
	double x,y; // 坐标
	int speed; // 速度
	int width,height; // 宽高
	// 画图方法
	public void drawSelf(Graphics g) {
    
    
		g.drawImage(img,(int)x,(int)y, null);
	}
	// 构造方法
	public GameObject(Image img, double x, double y, int speed, int width, int height) {
    
    
		super();
		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) {
    
    
		super();
		this.img = img;
		this.x = x;
		this.y = y;
	}
	public GameObject() {
    
    
		
	}
	// 根据物体所在位置和宽度高度,返回物体所在的矩形,便与后续的碰撞检测
	public Rectangle getRect() {
    
    
		return new Rectangle((int)x,(int)y,width,height);
	}
	
}

飞机类:

package sc.wh.game;

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

// 飞机类,继承自游戏类,拥有游戏类对应的方法和属性
public class Plane extends GameObject{
    
    
	// 当有键盘事件时,判断飞机移动的方向
	boolean left,right,up,down;
	// 飞机移动的速度
	int speed =;
	// 用于判断飞机是否存活
	boolean live = true;
	// 画飞机的方法,可根据键盘事件设置(left,right...)布尔值实时调整飞机位置
	public void drawSelf(Graphics g) {
    
    
		// 如果飞机存活,才调用画图方法
		if(live) {
    
    
			if(right) {
    
    
				x += speed;
			}
			if(left) {
    
    
				x -= speed;
			}
			if (up) {
    
    
				y -= speed;
			}
			if(down) {
    
    
				y += speed;
			}
			if (x<=0) {
    
    
				x = 0;
			}else if(x >= 460) {
    
    
				x = 460;
			}
			if(y <= 40) {
    
    
				y = 40;
			}else if(y >= 470) {
    
    
				y = 470;
			}
			// 根据位置画图
			g.drawImage(img,(int)x,(int)y, null);
		}
		
		
	}
	// 构造方法
	public Plane(Image img,double x, double y) {
    
    
		this.img = img;
		this.x = x;
		this.y = y;
		// 根据img对象的get..方法获取图片大小,用于矩形实现碰撞检测
		this.width = img.getWidth(null);
		this.height = img.getHeight(null);
	}
	// 键盘按下时,会调用此方法来设置移动的方向
	public void addDirection(KeyEvent e) {
    
    
		// getKeyCode可以获取按下键盘对应特定的值
		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) {
    
    
		// getKeyCode可以获取按下键盘对应特定的值
		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;
		}	
	}
}

炮弹类:

package sc.wh.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); // 设置颜色
		if(x <= 0|| x >= Constants.WIDTH-width-10) {
    
    
			degree = Math.PI - degree; // 当碰撞水平地图边界后,反转角度
		}
		if(y<=40 || y >= Constants.HEIGHT-height) {
    
    
			degree = -degree; // 当碰撞垂直地图后,反转角度
		}
		// 填充一个圆作为炮弹
		g.fillOval((int)x, (int)y, width, height);
		// 根据角度设置炮弹移动的位置
		x += speed*Math.cos(degree);
		y += speed*Math.sin(degree);
		g.setColor(c);
	}
	
}

显示爆炸效果的类:

package sc.wh.game;

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

public class Explode {
    
    
	// 记录爆炸位置
    double x,y;
    // 创建爆炸数组,static保证图片只加载一次
    static Image[] imgs = new Image[16];
    // 静态初始化块,初始化类的时候会自动调用
    static {
    
    
        for(int i=0;i<16;i++){
    
    
        	// 挨个将爆炸图片对象获取到,并加入数组
            imgs[i] = GameUtil.getImage("images/explode/e"+(i+1)+".gif");
            imgs[i].getWidth(null);
        }
    }
    // 用来记录当前加载的图片
    int count;
    // 画爆炸效果
    public void draw(Graphics g){
    
    
        if(count<=15){
    
    
        	// 轮播逐个画爆炸的图片
            g.drawImage(imgs[count], (int)x, (int)y, null);
            count++;
        }
    }
    
    // 构造方法设置爆炸位置
    public Explode(double x,double y){
    
    
        this.x = x;
        this.y = y;
    }
}

游戏效果图

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46456049/article/details/108648689
今日推荐