java实现窗口飞机冒险小游戏(基础版)

主窗口类:

package 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.sql.Date;

import javax.swing.JFrame;

public class MyGameFram extends JFrame{
	Image planeImg = GameUtil.getImage("images/plan.jpg");
	Image bg = GameUtil.getImage("images/bg.jpg");
	Image ex = GameUtil.getImage("images/explode.jpg");
	
	Plane plane = new Plane(planeImg, 250, 250);
	Shell[] shells = new Shell[50];
	
	Date starTime = new Date(System.currentTimeMillis());
	Date endTime;
	long period = 0; //游戏持续的时间
	
	public void paint(Graphics g){//自动调用,g相当于一画笔
		g.drawImage(bg, 0, 0, null);
		plane.drawSelf(g); //画飞机
		//画50个炮弹
		for(int i=0; i<shells.length; i++){
			shells[i].draw(g);  
			//每画一个炮弹时,就判断这个炮弹是否与飞机相碰了
			boolean peng = shells[i].getRect().intersects(plane.getRect());
			if(peng){//相撞了
				plane.live = false;
				g.drawImage(ex, (int)plane.x, (int)plane.y, null);//画爆炸图片
				
				endTime = new Date(System.currentTimeMillis());
				period = (endTime.getTime() - starTime.getTime())/1000;
			}
			
			if(!plane.live){
				g.setColor(Color.red);
				Font f = new Font("宋体",Font.BOLD,30);
				g.setFont(f);
				g.drawString("存活时间:" + period + "秒", (int)plane.x, (int)plane.y);
				for(int i1=0; i1<2000000000; i1++){
					
				}
				System.exit(0);
			}
		}
	}
	
	/*
	 * 内部类
	 * 用于重复画窗口
	 */
	class PaintTread extends Thread{
		@Override
		public void run() { 
			while(true){
				repaint();  //重画
				try{
					Thread.sleep(40);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
		}
	}
	
	class KeyMonitor extends KeyAdapter{
		//按下键
		public void keyPressed(KeyEvent e) {
			//飞机对键盘输入的方向进行改变
			plane.addDirection(e);
		}
		
		//释放键
		public void keyReleased(KeyEvent e) {
			//飞机取消键盘释放方向键对应的方向
			plane.minDirection(e);
		}
	}
	
	/*
	 * 初始化窗口
	 */
	public void launchFrame(){
		this.setTitle("会程作品");
		this.setVisible(true);//设置窗口可见
		this.setSize(Constant.GAME_HEIGHT,Constant.GAME_WIDTH);
		this.setLocation(300,100);
		//添加窗口监听器,以便关闭窗口时结束程序
		this.addWindowListener(new WindowAdapter(){
			public void windowClosed(WindowEvent e){
				System.exit(0);//结束程序
			}
		});
		new PaintTread().start();//启动重画窗口的线程
		addKeyListener(new KeyMonitor());//给窗口增加键盘监听器
		
		//初始化50个炮弹
		for(int i=0; i<shells.length; i++){
			shells[i] = new Shell();
		}
	}
	
	
	public static void main(String[] args){
		MyGameFram f = new MyGameFram();
		f.launchFrame();
	}
	
	private Image offScreenImage = null;
	
	/*
	 * 利用双缓冲解决屏幕闪动问题,
	 * 如果继承的是JFram类,虽然闪动不明显,但是仍然有闪动
	 */
	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);
	}
}

常量类:

package Game;
/*
 * 常量类
 */
public class Constant {
	public static final int GAME_WIDTH = 500;
	public static final int GAME_HEIGHT = 500;
}

所有物体的父类:

package 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, height;
	
	
	public void drawSelf(Graphics g){
		g.drawImage(img, (int)x, (int)y, null);
	}


	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 Game;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.IIOException;
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) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bi;
	}
}

飞机类

package Game;

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

/*
 * 飞机类
 */
public class Plane  extends GameObject{
	
	boolean live = true;
	boolean left, up, right, down;//方向属性,用于控制方向
	
	public void drawSelf(Graphics g){
		
		if(!live){
			System.out.println("飞机与炮弹发生碰撞了");
		}
		g.drawImage(img, (int)x, (int)y, null);
		if(left){
			x -= speed;
		}
		if(right){
			x += speed;
		}
		if(up){
			y -= speed;
		}
		if(down){
			y += speed;
		}
	}
	
	public  Plane(Image img, int x, int y){
		this.img = img;
		this.x = x;
		this.y = y;
		this.speed = 6; //设置速度 
		this.width = img.getWidth(null);
		this.height = img.getHeight(null);
	}
	
	//根据键盘的输入设置方向
	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 minDirection(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 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;
		//random()返回的是弧度,要换算成度数
		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.GAME_WIDTH - width){//防止超出窗口边界
			degree = Math.PI - degree;//根据三角函数计算
		}
		
		if(y<30||y>Constant.GAME_HEIGHT - height){//防止超出窗口边界
			degree = - degree;
		}
		
		g.setColor(c);//恢复画笔原来的颜色
	}
}

运行界面:

在这里插入图片描述

死亡界面:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/HC199854/article/details/106003344