Java练习——小游戏 模拟雷电

使用工具:Eclipse

游戏效果:

目录 结构:

结构介绍:

GameFrame:主程序入口

GameUtil:工具类,用来导入图片

GameObject:游戏物体的父类(物体图片、物体速度、物体宽高、坐标xy、碰撞)

Constant:常量

Plane:飞机类

Stone:石头类(游戏生成的陨石)

Bullet:子弹类(点击空格键就可以发射子弹)

Boom:爆炸类(飞机死亡后的一个爆炸效果)

Live:生命类(左下角显示的爱心)

按顺序贴出代码

GameFrame

package cn.claire.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;

@SuppressWarnings("serial")
public class GameFrame extends Frame {

	Image backgroundImg1 = GameUtil.getIamge("images/background.jpg");// 游戏背景
	Image backgroundImg2 = GameUtil.getIamge("images/background.jpg");
	int bgY = 0;// 背景图的纵坐标

	Image planeImg = GameUtil.getIamge("images/plane.png");
	Plane plane = new Plane(planeImg, 240, 600);

	Image[] stoneImgs = { GameUtil.getIamge("images/stone0.png"), GameUtil.getIamge("images/stone1.png"),
			GameUtil.getIamge("images/stone2.png") };
	Stone[] stones = new Stone[15];// 障碍物--石头

	Image livesImg = GameUtil.getIamge("images/live.png");
	int lives = Constant.PLANE_LIVES;// 飞机的生命数
	Live planeLive;// 飞机生命

	Image bulletImg = GameUtil.getIamge("images/bullet.png");
	Bullet bullet;

	Boom boom;// 爆炸对象

	// 时间
	Date startTime = new Date();
	Date endTime;
	int period;// 游戏持续的时间

	int score = 0;// 得分

	/* 绘制窗口 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);

		// 保存默认的画笔与字体
		Color cOrigin = g.getColor();
		Font fOrigin = g.getFont();

		// 背景图滚动
		{
			g.drawImage(backgroundImg1, 0, bgY, null);
			g.drawImage(backgroundImg1, 0, bgY - 800, null);
			bgY += Constant.BACKGROUND_SPEED;
			if (bgY == 800) {
				bgY = 0;
			}
		}
		if (plane != null) {
			plane.drawSelf(g);// 画飞机
		}

		// 画石头
		for (int i = 0; i < stones.length; i++) {

			if (plane != null) {
				// 检测飞机与石头的碰撞
				boolean crushed = stones[i].getRect().intersects(plane.getRect());
				if (crushed) {
					lives--;
					stones[i].img = stoneImgs[(int) (Math.random() * 3)];// 石头重画
					stones[i].x = Math.random() * 400 + 40;
					stones[i].y = 30;
					boom = new Boom(plane.x - 10, plane.y);// 爆炸对象
					if (0 == lives) {
						System.out.println("飞机死亡");
						plane.live = false;
						plane = null;
					}
					crushed = false;
					if (score >= 1) {
						score -= 1;// 如果得分超过1分,则减分
					}
				}
			}

			// 检测子弹是否打中石头
			if (bullet != null) {
				boolean hitted = stones[i].getRect().intersects(bullet.getRect());
				if (hitted) {
					boom = new Boom(stones[i].x, stones[i].y);// 爆炸对象
					stones[i].img = stoneImgs[(int) (Math.random() * 3)];// 石头重画
					stones[i].x = Math.random() * 400 + 40;
					stones[i].y = 30;
					hitted = false;
					bullet = null;// 子弹没了
					score += 3;// 得分增加3分
				}
			}

			stones[i].draw(g);

		}

		if (plane != null) {// 得分
			g.setColor(Color.YELLOW);
			g.setFont(new Font("宋体", Font.BOLD, 20));
			g.drawString("得分: " + score + "分", 380, 780);
		} else {
			g.setColor(Color.RED);
			g.setFont(new Font("宋体", Font.BOLD, 40));
			g.drawString("游戏结束", 150, 400);
			g.drawString("总得分:" + score + "分", 150, 450);
		}

		if (boom != null) {// 画爆炸对象
			boom.draw(g);
		}

		// 生命增加
		if (((int) (((new Date()).getTime() - startTime.getTime())) / 1000) % 10 == 0 && planeLive == null) {
			planeLive = new Live(livesImg);
		}
		if (planeLive != null) {
			planeLive.draw(g);
			if (plane != null) {
				boolean getLive = planeLive.getRect().intersects(plane.getRect());
				if (getLive && planeLive != null) {
					planeLive = null;
					lives++;// 飞机加一条命
					if (lives >= 3) {
						lives = 3;
					}
				}
			}

		}

		// 飞机生命数显示
		for (int i = 0; i < lives; i++) {
			g.drawImage(livesImg, 10 + 50 * i, 750, null);
		}

		// 画子弹:在飞机存在的情况下
		if (plane != null && bullet != null) {
			bullet.draw(g);
			if (bullet.y < 10) {// 飞到上空的时候,子弹消失
				bullet = null;
			}
		}

		// 归为初始的画笔与字体
		g.setColor(cOrigin);
		g.setFont(fOrigin);
	}

	/* 反复重画窗口 */
	class PaintThread extends Thread {
		@Override
		public void run() {
			super.run();
			while (true) {
				repaint();// 重画
				try {
					Thread.sleep(40);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/* 初始化窗口 */
	public void launchFranme() {
		this.setTitle("雷电");
		this.setVisible(true);
		this.setSize(Constant.SCREEN_WIDTH, Constant.SCREEN_HEIGHT);
		this.setLocation(500, 20);

		// 关闭窗口
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				super.windowClosing(e);
				System.exit(0);
			}
		});

		for (int i = 0; i < stones.length; i++) {
			stones[i] = new Stone(stoneImgs[(int) (Math.random() * 3)]);
		}

		new PaintThread().start();// 启动重画窗口的线程
		addKeyListener(new KeyMonitor());// 启动键盘监听
	}

	/* 键盘监听 */
	class KeyMonitor extends KeyAdapter {
		@Override
		public void keyPressed(KeyEvent e) {
			super.keyPressed(e);
			if (plane != null) {
				plane.addDirection(e);
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
			super.keyReleased(e);
			if (plane != null) {
				plane.minusDirection(e);
				if (e.getKeyCode() == KeyEvent.VK_SPACE && bullet == null) {// 抬起空格并且没有子弹,则生成子弹
					bullet = new Bullet(bulletImg, (double) plane.x + 10, (double) plane.y);
				}
			}

		}
	}

	/* 双缓冲解决闪烁 */
	private Image offScreenImage = null;

	public void update(Graphics g) {
		if (offScreenImage == null) {
			offScreenImage = this.createImage(Constant.SCREEN_WIDTH, Constant.SCREEN_HEIGHT);
		}
		Graphics gOff = offScreenImage.getGraphics();
		paint(gOff);
		g.drawImage(offScreenImage, 0, 0, null);
	}

	/* 程序入口 */
	public static void main(String[] args) {
		GameFrame game = new GameFrame();
		game.launchFranme();
	}
}

GameUtil

package cn.claire.game;

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

import javax.imageio.ImageIO;

public class GameUtil {
	private GameUtil() {
	}

	/**
	 * 返回指定文件的图片对象
	 * 
	 * @param path
	 * @return
	 */
	public static Image getIamge(String path) {
		BufferedImage bi = null;
		try {
			URL u = GameUtil.class.getClassLoader().getResource(path);
			bi = ImageIO.read(u);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return (BufferedImage) bi;
	}
}

GameObject

package cn.claire.game;

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

/**
 * 游戏物体的父类
 * 
 * @author Lenovo
 *
 */
public class GameObject {
	Image img;
	int speed;// 物体速度
	int width, height;// 宽高
	double x, y;// 坐标

	// 在画布中画出该物体
	public void drawSelf(Graphics g) {
		g.drawImage(img, (int) x, (int) y, null);
	}

	/**
	 * 返回物体所在的矩形便于后续的碰撞检测
	 * 
	 * @return
	 */
	public Rectangle getRect() {
		return new Rectangle((int) x, (int) y, width, height);
	}

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

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

	public GameObject() {

	}
}

Constant

package cn.claire.game;

public class Constant {
	public static final int SCREEN_WIDTH = 500;// 屏幕宽
	public static final int SCREEN_HEIGHT = 800;// 屏幕高
	public static final int BACKGROUND_SPEED = 5;// 背景滚动速度
	public static final int PLANE_SPEED = 10;// 飞机的速度
	public static final int STONE_SPEED = 5;// 陨石飞行速度
	public static final int PLANE_LIVES = 3;// 飞机生命条数
	public static final int BULLET_SPEED = 15;// 子弹飞行速度
}

Plane

package cn.claire.game;

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

/**
 * 飞机类
 * 
 * @author Lenovo
 *
 */
public class Plane extends GameObject {
	int speed = Constant.PLANE_SPEED;// 飞机速度
	boolean left, up, right, down;// 飞机方向
	boolean live = true;// 飞机存活

	/* 按下键,改变方向 */
	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;
		default:
			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;
		default:
			break;
		}
	}

	@Override
	public void drawSelf(Graphics g) {
		if (live) {
			g.drawImage(img, (int) x, (int) y, null);
			if (left && x > 0) {
				x -= speed;
			}
			if (right && x < Constant.SCREEN_WIDTH - img.getWidth(null)) {
				x += speed;
			}
			if (up && y > 30) {
				y -= speed;
			}
			if (down && y < Constant.SCREEN_HEIGHT - img.getHeight(null)) {
				y += speed;
			}
		}
	}

	// 构造器
	public Plane(Image img, double x, double y) {
		this.img = img;
		this.x = x;
		this.y = y;
		this.speed = Constant.PLANE_SPEED;
		this.width = img.getWidth(null);
		this.height = img.getHeight(null);
	}
}

Stone

package cn.claire.game;

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

/**
 * 障碍物
 * 
 * @author Lenovo
 *
 */
public class Stone extends GameObject {
	double degree;// 飞行角度
	boolean live = true;// 是否存在

	public Stone(Image img) {
		x = Math.random() * 400 + 40;
		y = 30;
		this.img = img;
		width = img.getWidth(null);
		height = img.getHeight(null);
		speed = Constant.STONE_SPEED;// 陨石飞行速度
		degree = Math.random() * Math.PI * 2;
	}

	public void draw(Graphics g) {
		if (live) {
			g.drawImage(img, (int) x, (int) y, null);
			x += speed * Math.cos(degree);
			y += speed * Math.sin(degree);

			if (x < 10 || x > Constant.SCREEN_WIDTH - width) {
				degree = Math.PI - degree;
			}
			if (y < 30 || y > Constant.SCREEN_HEIGHT - height) {
				degree = -degree;
			}
		}
	}
}

Bullet

package cn.claire.game;

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

public class Bullet extends GameObject {
	public Bullet(Image img, double x, double y) {
		this.img = img;
		this.x = x;
		this.y = y;
		width = img.getWidth(null);
		height = img.getHeight(null);
		speed = Constant.BULLET_SPEED;// 子弹飞行速度
	}

	public void draw(Graphics g) {
		g.drawImage(img, (int) x, (int) y, null);
		y -= speed;
	}

}

Boom

package cn.claire.game;

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

public class Boom extends GameObject {
	double x, y;
	static Image[] imgs = new Image[16];

	static {
		for (int i = 0; i < imgs.length; i++) {
			imgs[i] = GameUtil.getIamge("images/e" + (i + 1) + ".png");
		}
	}

	int count;

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

	public Boom(double x, double y) {
		this.x = x;
		this.y = y;
	}

}

Live

package cn.claire.game;

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

public class Live extends GameObject {
	double degree;// 飞行角度
	boolean live = true;// 是否存在

	public Live(Image img) {
		x = Math.random() * 400 + 40;
		y = 30;
		this.img = img;
		width = img.getWidth(null);
		height = img.getHeight(null);
		speed = Constant.STONE_SPEED + 10;// 血条飞行速度
		degree = Math.random() * Math.PI * 2;
	}

	public void draw(Graphics g) {
		if (live) {
			g.drawImage(img, (int) x, (int) y, null);
			x += speed * Math.cos(degree);
			y += speed * Math.sin(degree);

			if (x < 10 || x > Constant.SCREEN_WIDTH - width) {
				degree = Math.PI - degree;
			}
			if (y < 30 || y > Constant.SCREEN_HEIGHT - height) {
				degree = -degree;
			}
		}
	}
}

贴一下图片素材(基本都是网上找的,然后自己PS处理的,有喜欢别的可以自行更换)

 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值