如下:
碰到柱子就结束游戏
App
GameApp类
-
p
ackage App; import main.GameFrame; public class GameApp { public static void main(String[] args) {//游戏的入口 new GameFrame(); } }
main
Barrier 类
-
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; } }
Barrierpool 类
-
package main; import java.util.ArrayList; import java.util.List; /** * 为了避免反复的创建和销毁对象,使用对象池来提前创建好一些对象。 * 使用的时候从池中获得,使用完毕后,归还 */ public class Barrierpool { //用于管理池中所有对象的容器 private static List<Barrier> 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("容器归还了"); } } }
Bird 类
-
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; } }
Cloud 类
-
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; } }
GameBackGround 类
-
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); } } }
GameBarrierLayer 类
-
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<Barrier> 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(); } }
GameFrame 类
-
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(); } }
GameFrontGround 类
-
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<Cloud> 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); } } } }
GameTime 类
-
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; } }
untl
Constant 类
-
p
ackage 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"};
GameUtil 类
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;
}
}