运行游戏如下:
碰到柱子就结束游戏
- package App;
-
- import main.GameFrame;
-
- public class GameApp {
- public static void main(String[] args) {//游戏的入口
- new GameFrame();
- }
- }
- package main;
-
- import util.Constant;
- import util.GameUtil;
-
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.util.Random;
-
- /**
- * 障碍物类
- */
- public class Barrier {
-
-
- //矩形参数
- private Rectangle rect;
-
- private boolean mob = true;
-
- //障碍物移动速度
- private int speed = 3;
- //障碍物需要的三个图片
- private static BufferedImage[] img;
-
- //障碍物的状态
- private boolean visible;
-
-
- static {
- final int COUNT = 3;
- //类加载的时候将三个图片初始化
- img = new BufferedImage[COUNT];
- for (int i = 0; i < COUNT; i++) {
- img[i] = GameUtil.loadBufferedImage(Constant.BARRIER_IMG_PATH[i]);
- }
- }
-
- //位置
- private int x, y;
- //宽度和高度
- private int width, height;
- //障碍物的类型
- private int type;
- public static final int TYPE_TOP_NORMAL = 0;
- public static final int TYPE_BOTTOM_NORMAL = 2;
- public static final int TYPE_HOVER_NORMAL = 4;
- public static final int TYPE_MOBILE = 6;
-
- //获得障碍物的宽度和高度
- public static final int BARRIRE_WIDTH = img[0].getWidth();
- public static final int BARRIRE_HEIGHT = img[0].getHeight();
- public static final int BARRIRE_HEAD_WIDTH = img[1].getWidth();
- public static final int BARRIRE_HEAD_HEIGHT = img[1].getHeight();
-
- public Barrier() {
-
- rect = new Rectangle();
-
- }
-
- public Barrier(int x, int y, int height, int type) {
- this.x = x;
- this.y = y;
- this.height = height;
- this.type = type;
- this.width = BARRIRE_WIDTH;
- }
-
- //根据不同的类型绘制障碍物
- public void draw(Graphics g) {
- switch (type) {
- case TYPE_TOP_NORMAL:
- drawTopMormal(g);
- break;
- case TYPE_BOTTOM_NORMAL:
- drawNomalTop(g);
- break;
- case TYPE_HOVER_NORMAL:
- drawHoverNormal(g);
- break;
- case TYPE_MOBILE:
- drawMobile(g);
- break;
- }
-
- }
-
- //绘制从上向下的障碍物
- private void drawTopMormal(Graphics g) {
- //求出所需要的障碍物的块数
- int count = (height - BARRIRE_HEAD_HEIGHT) / BARRIRE_HEIGHT + 1;
- //for循坏绘制障碍物
- for (int i = 0; i < count; i++) {
- g.drawImage(img[0], x, y + i * BARRIRE_HEIGHT, null);
- }
-
- //绘制头
- int y = height - BARRIRE_HEAD_HEIGHT;
- g.drawImage(img[2], x - (BARRIRE_HEAD_WIDTH - BARRIRE_WIDTH) / 2, y, null);
- x -= speed;
- if (x < 50) {
- visible = false;
- }
- rect(g);
-
-
- }
-
- //绘制从下向上的障碍物
- private void drawNomalTop(Graphics g) {
- //求出所需要的障碍物的块数
- int count = height / BARRIRE_HEIGHT + 1;
- //for循环绘制障碍物
- for (int i = 0; i < count; i++) {
- g.drawImage(img[0], x, Constant.FRAM_HEIGNT - i * BARRIRE_HEIGHT, null);
- }
- //绘制头
- int y = Constant.FRAM_HEIGNT - height;
- g.drawImage(img[1], x - (BARRIRE_HEAD_WIDTH - BARRIRE_WIDTH) / 2, y, null);
- x -= speed;
- if (x < -50) {
- visible = false;
- }
- rect(g);
- }
- //绘制中间的障碍物
- private void drawHoverNormal(Graphics g) {
- //求出所需要的障碍物的块数
- int count = (height-BARRIRE_HEAD_HEIGHT)/BARRIRE_HEIGHT;
- //绘制上头
- g.drawImage(img[1],x,y,null);
- //for循环绘制障碍物
- for (int i = 0; i < count; i++) {
- g.drawImage(img[0], x, y+BARRIRE_HEAD_HEIGHT+i*BARRIRE_HEIGHT, null);
- }
- rect(g);
-
- //绘制下头
- int y11 = y+height-BARRIRE_HEAD_HEIGHT;
- g.drawImage(img[2],x,y11,null);
- x -= speed;
- if (x < -50) {
- visible = false;
- }
- }
-
- //绘制移动的障碍物
- private void drawMobile(Graphics g) {
- //求出所需要的障碍物的块数
- int count = (height-BARRIRE_HEAD_HEIGHT)/BARRIRE_HEIGHT;
- //绘制上头
- g.drawImage(img[1],x,y,null);
- //for循环绘制障碍物
- for (int i = 0; i < count; i++) {
- g.drawImage(img[0], x, y+BARRIRE_HEAD_HEIGHT+i*BARRIRE_HEIGHT, null);
- }
- rect(g);
-
- //绘制下头
- int y11 = y+height-BARRIRE_HEAD_HEIGHT;
- g.drawImage(img[2],x,y11,null);
- x -= speed;
- if (x < -50) {
- visible = false;
- }
-
- if (mob) {
- y+=5;
- if (y >= 250) {
- mob=false;
- }
- }else if (!mob){
- y-=5;
- if (y <= 100) {
- mob=true;
- }
- }
- }
-
- /**
- * 绘制障碍物碰撞矩形
- *
- * @return
- */
- public void rect(Graphics g) {
- int x1 = this.x;
- int y1 = this.y;
- int w1 = img[0].getWidth();
- // g.setColor(Color.blue);
- // g.drawRect(x1, y1, w1, height);
- setRecyangle(x1, y1, w1, height);
- }
-
- /**
- * 障碍物的碰撞矩形参数
- *
- * @return
- */
- public void setRecyangle(int x, int y, int width, int height) {
- rect.x = x;
- rect.y = y;
- rect.width = width;
- rect.height = height;
- }
-
-
- //判断什么时候绘制下一组障碍物
- public boolean isInFrame() {
- return 600 - x > 150;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- public int getY() {
- return y;
- }
-
- public void setY(int y) {
- this.y = y;
- }
-
- public int getHeight() {
- return height;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public int getType() {
- return type;
- }
-
- public void setType(int type) {
- this.type = type;
- }
-
- public boolean isVisible() {
- return visible;
- }
-
- public void setVisible(boolean visible) {
- this.visible = visible;
- }
-
- public Rectangle getRect() {
- return rect;
- }
- }
- package main;
-
-
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * 为了避免反复的创建和销毁对象,使用对象池来提前创建好一些对象。
- * 使用的时候从池中获得,使用完毕后,归还
- */
- public class Barrierpool {
- //用于管理池中所有对象的容器
- private static List
pool = new ArrayList<>(); - //池中初始的对象个数
- public static final int initCount = 16;
- //对象池中最大个数
- public static final int maxCOunt = 20;
-
- static {
- //初始化池中的对象
- for (int i = 0; i < initCount; i++) {
- pool.add(new Barrier());
- }
- }
-
-
- /**
- * 从池中获取一个对象
- */
- public static Barrier getPool(){
- int size = pool.size();
- //如果池中有对象才可以拿
- if (size > 0) {
- //移除并返回对象
- System.out.println("拿走一个");
- return pool.remove(size-1);
- }else {
- //池中没有对象了 只能new
- System.out.println("新的对象");
- return new Barrier();
- }
- }
-
-
- /**
- * 将对象归还容器中
- */
- public static void setPool(Barrier barrier){
- if (pool.size() < maxCOunt) {
- pool.add(barrier);
- System.out.println("容器归还了");
- }
- }
-
-
- }
- package main;
-
-
- import static util.Constant.*;
- import util.GameUtil;
- import java.awt.*;
- import java.awt.image.BufferedImage;
-
- /**
- * 小鸟类
- */
- public class Bird {
-
- //小鸟矩形对象
- private Rectangle rect;
-
- //小鸟加速度
- private int acceleration;
-
- //小鸟的生命
- public boolean life = true;
-
- //存放小鸟图片
- private BufferedImage[] images;
- public static final int BIRD_IMG_COUNT = 3;
- //鸟的状态
- private int state;
- public static final int STATE_NORMAR = 0;//平着飞
- public static final int STATE_UP = 1;//向上飞
- public static final int STATE_DOWN = 2;//向下飞
-
- //小鸟的位置
- private int x=200,y=200;
-
-
- //小鸟移动方向 上下
- private boolean up=false,down=false;
-
- //小鸟移动速度
- private int speed=4;
-
-
- //构造方法中对资源初始化
- public Bird() {
- images = new BufferedImage[BIRD_IMG_COUNT];
- for (int i = 0; i < BIRD_IMG_COUNT; i++) {
- images[i] = GameUtil.loadBufferedImage(BIRD_IMG[i]);
- }
-
- int w = images[0].getWidth();
- int h = images[0].getHeight();
- rect = new Rectangle(w,h);
-
- }
-
- //绘制小鸟
- public void draw(Graphics g) {
-
- flyLogic();
-
- g.drawImage(images [state], x, y, null);
-
- //绘制小鸟的矩形
- g.drawRect(x,y,(int)rect.getWidth(), rect.height);
- rect.x=this.x;
- rect.y=this.y;
- }
-
-
-
- //控制小鸟移动方向
- public void flyLogic(){
- if (up){
- acceleration--;
- y+=acceleration;
- if (acceleration < -10) {
- acceleration=-10;
- }
- if (y<20){
- y=20;
- acceleration=0;
- }
- }
- if (!up){
- acceleration++;
- y+=acceleration;
- if (acceleration > 10) {
- acceleration=10;
- }
- if (y>475){
- y=475;
- acceleration=0;
- }
- }
-
- }
-
-
-
-
- public void fly(int fly){
- switch (fly){
- case 1:
- state=1;
- up=true;
- break;
- case 5:
- state=2;
- up=false;
- break;
- }
- }
-
- public Rectangle getRect() {
- return rect;
- }
-
- /**
- * 重新绘制小鸟的位置
- */
- public void restartDraw(){
- life=true;
- x=200;
- y=200;
- }
-
- }
- package main;
-
- import java.awt.*;
- import java.awt.image.BufferedImage;
-
- /**
- * 云彩类
- */
- public class Cloud {
- //云彩图片
- private BufferedImage img;
- //云彩速度
- private int speed;
- //云彩的位置
- private int x,y;
-
- public Cloud(){}
-
- public Cloud(BufferedImage img, int speed, int x, int y) {
- this.img = img;
- this.speed = speed;
- this.x = x;
- this.y = y;
- }
-
- public void draw(Graphics g){
- x-=speed;
- g.drawImage(img,x,y,null);
- }
- /**
- * 用于判断云彩是否飞出屏幕以外
- */
- public boolean isOutFrame(){
- if (x < -100) {
- return true;
- }
- return false;
- }
-
- }
- package main;
-
- import static util.Constant.*;
-
- import util.Constant;
- import util.GameUtil;
-
- import java.awt.*;
- import java.awt.image.BufferedImage;
-
- /**
- * 游戏背景类
- */
- public class GameBackGround {
- //背景需要的资源图片
- private BufferedImage bkimg;
-
- //构造器初始化资源
- public GameBackGround(){
- bkimg = GameUtil.loadBufferedImage(Constant.BK_IMG_OATH);
- }
-
- //绘制图片
- public void draw(Graphics g){
-
- //填充背景色
- g.setColor(BK_COLOR);
- g.fillRect(0,0,FRAM_WIDTH,FRAM_HEIGNT);
- g.setColor(Color.black);
-
-
- //得到图片的高度和宽度
- int height = bkimg.getHeight();
- int weight = bkimg.getWidth();
- //循环的次数
- int count = Constant.FRAM_WIDTH/weight+1;
- for (int i = 0; i < count; i++) {
- g.drawImage(bkimg,weight*i,Constant.FRAM_HEIGNT-height,null);
- }
- }
- }
- package main;
-
-
- import util.Constant;
-
- import java.awt.*;
- import java.io.*;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
-
-
- /**
- * 游戏中障碍物层
- */
- public class GameBarrierLayer {
-
- private GameTime gameTime;
-
- private int txt;
-
- private Random random = new Random();
-
- private List
barriers; -
- public GameBarrierLayer() {
- barriers = new ArrayList<>();
- gameTime = new GameTime();
- }
-
- //绘制障碍物
- public void draw(Graphics g, Bird bird) {
- for (int i = 0; i < barriers.size(); i++) {
- Barrier barrier = barriers.get(i);
-
- if (barrier.isVisible()) {
- barrier.draw(g);
- } else {
- Barrier remove = barriers.remove(i);
- Barrierpool.setPool(remove);
- i--;
- }
- }
- collideBird(bird);
- logic(g);
- }
-
- public void logic(Graphics g) {
- if (barriers.size() == 0) {
- ran();
- gameTime.begin();
- insert(600, 0, numberTop, 0);
- insert(600, 500 - numberDown, numberDown, 2);
- } else {
- long differ = gameTime.differ();
- g.setColor(Color.white);
- g.setFont(new Font("微软雅黑", 1, 20));
- g.drawString("坚持了:" + differ + "秒", 30, 50);
-
- //显示最高成绩
- txt = getTxt();
- if (differ <= txt){
- g.drawString("最高成绩:" + txt , 200, 50);
- }else {
- setTxt(String.valueOf(differ));
- g.drawString("最高成绩:" + getTxt() , 200, 50);
- }
-
- //判断最后一个障碍物是否完全进入屏幕内
- Barrier last = barriers.get(barriers.size() - 1);
- if (last.isInFrame()) {
- ran();
- if (number < 50){
- insert(600,32,440,4);
- }else if (number>450){
- insert(600,125,200,6);
- }else {
- insert(600, 0, numberTop, 0);
- insert(600, 500 - numberDown, numberDown, 2);
- }
-
- }
- }
- }
-
- //用于储存游戏数据
- File file = new File("C:\\game.txt");
-
- /**
- * 从文件获取数据
- * @return
- */
- public int getTxt() {
- BufferedReader in = null;
- try {
- in = new BufferedReader(new FileReader(file));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- int read = 0;
- try {
- read = Integer.parseInt(in.readLine());
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return read;
- }
-
- /**
- * 写入数据到文件
- * @param str
- */
- public void setTxt(String str) {
- FileWriter out = null;
- try {
- out = new FileWriter(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- out.write(str);
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
-
- /**
- * 用于从池中获取对象,并吧参数封装成barrier 存入barriers数组中
- */
- public void insert(int x, int y, int num, int type) {
- Barrier top = Barrierpool.getPool();
- top.setX(x);
- top.setY(y);
- top.setHeight(num);
- top.setType(type);
- top.setVisible(true);
- barriers.add(top);
- }
-
-
- //上方障碍物高度
- private int numberTop;
- //下方障碍物高度
- private int numberDown;
- private int number;
-
- //产生两个100-500之间的随机高度
- public void ran() {
- numberTop = random.nextInt(400) + 100;
- numberDown = random.nextInt(400) + 100;
- number = random.nextInt(500);
- //如果管道重合,则重新随机
- if (numberTop + numberDown > 450) {
- ran();
- }
- }
-
- /**
- * 判断障碍物和小鸟发生碰撞
- */
- public boolean collideBird(Bird bird) {
- for (int i = 0; i < barriers.size(); i++) {
- Barrier barrier = barriers.get(i);
- //判断矩形是否相交
- if (barrier.getRect().intersects(bird.getRect())) {
- System.out.println("装上啦");
- bird.life = false;
- }
- }
- return false;
- }
-
- /**
- * 用于清空障碍物的池子
- */
- public void restant(){
- barriers.clear();
- }
-
-
- }
- package main;
-
- import static util.Constant.*;
-
- import java.awt.*;
- import java.awt.event.*;
- import java.awt.image.BufferedImage;
-
- /**
- * 游戏的主窗口类,所有的关于游戏中绘制的内容都在此类中完成。
- */
- public class GameFrame extends Frame {
-
- //实例化gamebackGround类
- private GameBackGround gameBackGround;
-
- //实例化Bird类
- private Bird bird;
-
- //实例化GameBarrierLayer类
- private GameBarrierLayer gameBarrierLayer;
-
- //实例化GameFrontGround类
- private GameFrontGround gameFrontGround;
-
-
- //存放图片的图片
- private BufferedImage buffimg = new BufferedImage(FRAM_WIDTH,FRAM_HEIGNT,BufferedImage.TYPE_4BYTE_ABGR);
-
-
- //构造方法中初始化一些参数
- public GameFrame(){
- //窗口是否可见
- setVisible(true);
- //窗口的大小
- setSize(FRAM_WIDTH,FRAM_HEIGNT);
- //窗口的标题
- setTitle(FRAM_TITLE);
- //窗口的初始化位置
- setLocation(FRAM_X,FRAM_Y);
- //窗口的大小不可改变
- setResizable(false);
-
-
- //窗口的关闭事件
- addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- System.exit(0);//结束程序
- }
- });
-
-
- //初始化游戏对象
- initGamg();
-
- new run().start();
-
- //添加按键监听
- addKeyListener(new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent e) {
- add(e);
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
- minu(e);
- }
- });
-
-
-
- }
-
- //对游戏中的对象初始化
- public void initGamg(){
- gameBackGround = new GameBackGround();
- bird = new Bird();
- gameFrontGround = new GameFrontGround();
- gameBarrierLayer = new GameBarrierLayer();
- }
-
-
-
- class run extends Thread{
- @Override
- public void run() {
- while (true) {
- repaint();
- try {
- Thread.sleep(33);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
-
- /**
- * 所有的我们需要绘制的内容都在此方法中进行调用绘制
- */
- @Override
- public void update(Graphics g) {
- if(bird.life){
- //得到图片的画笔
- Graphics graphics = buffimg.getGraphics();
-
- gameBackGround.draw(graphics);
- bird.draw(graphics);
- gameFrontGround.draw(graphics);
- gameBarrierLayer.draw(graphics,bird);
-
- //一次性的将图片绘制到屏幕中
- g.drawImage(buffimg,0,0,null);
- }else {
- String over = "游戏结束";
- g.setColor(Color.red);
- g.setFont(new Font("微软雅黑",1,60));
- g.drawString(over,180,250);
-
- String reset = "Space Reset Game";
- g.drawString(reset,25,350);
- }
- }
-
-
- //按键
- public void add(KeyEvent e){
- switch (e.getKeyCode()){
- case KeyEvent.VK_UP:
- bird.fly(1);
- break;
- case KeyEvent.VK_SPACE:
- if (bird.life == false) {
- restart();
- }
- break;
- }
- }
-
-
-
- //抬键
- public void minu(KeyEvent e){
- switch (e.getKeyCode()){
- case KeyEvent.VK_UP:
- bird.fly(5);
- break;
- }
- }
-
- /**
- * 重置游戏
- */
- public void restart(){
- gameBarrierLayer.restant();
- bird.restartDraw();
- }
-
-
- }
- package main;
-
- import util.Constant;
- import util.GameUtil;
-
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
-
- /**
- * 游戏的前景类
- */
- public class GameFrontGround {
- //云彩的个数
- private static final int CLOUND_COUNT = 2;
- //存放云彩的容器
- private List
clouds; - //云彩的飞行速度
- private static final int CLOUNG_SPEED = 1;
- //使用到图片资源
- private BufferedImage[] img;
-
- //用于产生随机数
- private Random random;
-
- // 构造器初始化数据
- public GameFrontGround() {
- clouds = new ArrayList<>();
- img = new BufferedImage[CLOUND_COUNT];
-
- //容器中添加云彩的图片
- for (int i = 0; i < CLOUND_COUNT; i++) {
- img[i] = GameUtil.loadBufferedImage("img/cloud0" + i + ".png");
- }
- random = new Random();
- }
-
- //绘制云彩
- public void draw(Graphics g) {
- logic();
- for (int i = 0; i < clouds.size(); i++) {
- clouds.get(i).draw(g);
- }
- }
-
- /**
- * 用于云彩的个数控制
- */
- private void logic() {
- if ((int) (500 * Math.random()) < 5) {
- Cloud cloud = new Cloud(img[random.nextInt(CLOUND_COUNT)], CLOUNG_SPEED, 600, random.nextInt(150));
- clouds.add(cloud);
- }
- for (int i = 0; i < clouds.size(); i++) {
- Cloud cloud = clouds.get(i);
- if (cloud.isOutFrame()){
- clouds.remove(i);
- i--;
- System.out.println("移除了"+cloud);
- }
- }
-
- }
- }
- package main;
-
- /**
- * 游戏计时器
- */
- public class GameTime {
-
- //开始
- private long beginTime;
- //结束
- private long endTime;
- //时间差
- private long differ;
-
- public GameTime(){}
-
- public void begin(){
- beginTime = System.currentTimeMillis();
- }
- public long differ(){
- endTime = System.currentTimeMillis();
- return differ=(endTime-beginTime)/1000;
- }
-
- }
- package util;
-
- import java.awt.*;
-
- /**
- * @author
- * @create
- */
- public class Constant {
- //窗口的大小
- public static final int FRAM_WIDTH= 600;
- public static final int FRAM_HEIGNT= 500;
-
- //窗口标题
- public static final String FRAM_TITLE= "飞翔的小鸟";
-
- //窗口的初始化位置
- public static final int FRAM_X= 200;
- public static final int FRAM_Y= 200;
-
- //背景图片
- public static final String BK_IMG_OATH = "img/bird_bk.png";
-
- //背景色
- public static final Color BK_COLOR = new Color(0x4BC4CF);
-
- //小鸟图片资源
- public static final String[] BIRD_IMG={
- "img/bird_normal.png","img/bird_up.png","img/bird_down.png"
- };
-
- //障碍物图片资源
- public static final String[] BARRIER_IMG_PATH ={
- "img/barrier.png","img/barrier_up.png","img/barrier_down.png"};
- }
- package util;
-
- import javax.imageio.ImageIO;
- import java.awt.image.BufferedImage;
- import java.io.FileInputStream;
- import java.io.IOException;
-
- /**
- * 游戏工具类
- */
- public class GameUtil {
- /**
- *该方法传入一个图片路径 读取图片
- */
- public static BufferedImage loadBufferedImage(String ImgPath){
- try {
- return ImageIO.read(new FileInputStream(ImgPath));
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- }