創建三個包,存放代碼。把圖片放進文件中
APP包(運行)
GameApp類
package APP;
import mian.GameFrame;public class GameApp {public static void main(String[] args) {new GameFrame();}
}
mian包(主內容)
Barrier 類(障礙物)
package mian;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;import util.Constant;
import util.GameUtil;/** 障礙物類*/
public class Barrier {private Rectangle rect;//小鳥矩形對象//private boolean mob=true;private int speed=3;//障礙物移動速度private static BufferedImage[] imgs;//障礙物需要的三個圖片//障礙物的狀態private boolean visible;static {final int COUNT=3;//類加載的時候將三個圖片化imgs=new BufferedImage[COUNT];for(int i=0;i<COUNT;i++) {imgs[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_MOBLIE=6;//獲得障礙物的寬帶和高度public static final int BARRIRE_WIDTH=imgs[0].getWidth();public static final int BARRIRE_HEIGHT=imgs[0].getHeight();public static final int BARRIRE_HEAD_WIDTH=imgs[1].getWidth();public static final int BARRIRE_HEAD_HEIGHT=imgs[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:drawMormalTop(g);break;case TYPE_HOVER_NORMAL:drawHoverNormal(g);break;case TYPE_MOBLIE: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(imgs[0],x,y+i*BARRIRE_HEIGHT, null);}//繪制頭int y=height-BARRIRE_HEAD_HEIGHT;g.drawImage(imgs[2],x-(BARRIRE_HEAD_WIDTH-BARRIRE_WIDTH)/2,y, null);x-=speed;if(x<-50) {visible=false;}rect(g);}//繪制從下到上的障礙物private void drawMormalTop(Graphics g) {//求出所需要的障礙物的塊數int count=height/BARRIRE_HEIGHT+1;//for循環繪制障礙物for(int i=0;i<count;i++) {g.drawImage(imgs[0],x,Constant.FRAM_HEIGHT-i*BARRIRE_HEIGHT, null);} //繪制頭int y=Constant.FRAM_HEIGHT-height;g.drawImage(imgs[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(imgs[1],x,y,null);//for循環繪制障礙物for(int i=0;i<count;i++) {g.drawImage(imgs[0],x,y+BARRIRE_HEAD_HEIGHT+i*BARRIRE_HEIGHT, null);} rect(g);//繪制下頭int y11=y+height-BARRIRE_HEAD_HEIGHT;g.drawImage(imgs[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(imgs[1],x,y,null);//for循環繪制障礙物for(int i=0;i<count;i++) {g.drawImage(imgs[0],x,y+BARRIRE_HEAD_HEIGHT+i*BARRIRE_HEIGHT, null);} rect(g);//繪制下頭int y11=y+height-BARRIRE_HEAD_HEIGHT;g.drawImage(imgs[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;}}} /** 繪制障礙物矩形*/public void rect(Graphics g) {int x1=this.x;int y1=this.y;int w1=imgs[0].getWidth();
// g.drawRect(x1, y1, w1,height);setRectyangle(x1,y1,w1,height);}/** 障礙物矩形參數*/public void setRectyangle(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 mian;
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 {//如果池中沒有對象,只能newSystem.out.println("新的對象");return new Barrier();}}/** 將對象歸還容器中*/public static void setPool(Barrier barrier) {if(pool.size()<maxCount) {pool.add(barrier);System.out.println("容器歸還了");}}}
Bird(鳥)
package mian;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import static util.Constant.*;
import util.GameUtil;/** 小鳥類*/
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 mian;
import java.awt.Graphics;
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 mian;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;import util.Constant;
import util.GameUtil;/** 游戲背景類*/
public class GameBackground {private BufferedImage bkimg;//背景需要的資源圖片//構造器初始化資源public GameBackground() {bkimg=GameUtil.loadBufferedImage(Constant.BK_CATH_OATH);}//繪制圖片public void draw(Graphics g) {//填充背景顏色g.setColor(Constant.BK_COLOR);g.fillRect(0, 0, Constant.FRAM_WIDTH,Constant.FRAM_HEIGHT);g.setColor(Color.black);//得到圖片的高寬和寬高int height=bkimg.getHeight();int width=bkimg.getWidth();//循環的次數int count=Constant.FRAM_WIDTH/width+1;for(int i=0;i<count;i++) {g.drawImage(bkimg,width*i,Constant.FRAM_HEIGHT-height, null);}}
}
GameBarrierLayer(游戲中障礙物層)?
package mian;import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
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) throws NumberFormatException, IOException {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) throws NumberFormatException, IOException {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("D:\\飛翔的小鳥.txt");/** 用于得到文件中的數據*/public int getTxt() throws NumberFormatException, IOException {BufferedReader in=new BufferedReader(new FileReader(file));int read=Integer.parseInt(in.readLine());in.close();return read;}/** 用于儲存數據*/public void setTxt(String str) throws IOException {FileWriter fileWriter=new FileWriter(file);fileWriter.write(str);fileWriter.close();}/** 用來從池中獲取對象,并把參數封裝成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 mian;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;import static util.Constant.*;
import util.Constant;public class GameFrame extends Frame{//實例化GrameBackground類private GameBackground gameBackground;//實例化Bird類private Bird bird;//實例化GameBarrierLayerprivate GameBarrierLayer gameBarrierLayer;//實例化GameFrontground類private GameFrontground gameFrontground;//存放圖片的圖片private BufferedImage buffimg=new BufferedImage(FRAM_WIDTH,FRAM_HEIGHT,BufferedImage.TYPE_4BYTE_ABGR);//構造方法中初始化一些參數public GameFrame() {setVisible(true);//窗口是否可見setSize(FRAM_WIDTH,FRAM_HEIGHT);//窗體的大小setTitle(FRAM_Ttile);//窗體的標題setLocation(FRAM_x,FRAM_y);//窗體的初始位置setResizable(false);//窗體的大小不可改變//窗口的關閉事件addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);//結束程序}});//初始化游戲對象initGame();new run().start();//添加案件監聽器addKeyListener(new KeyAdapter (){public void keyPressed(KeyEvent e) {//super.keyPressed(e);add(e);}public void keyReleased(KeyEvent e) {//super.keyReleased(e);minu(e);}});}//對游戲中的對象初始化public void initGame() {gameBackground=new GameBackground();bird=new Bird();gameFrontground=new GameFrontground();gameBarrierLayer=new GameBarrierLayer();}class run extends Thread{public void run() {while(true) {repaint();try {Thread.sleep(33); }catch(InterruptedException e) {e.printStackTrace();}}}}/** 所有的我們需要繪制的內容都在此方法中進行調用繪制*/@Overridepublic void update(Graphics g) {if(bird.life) {//得到圖片的畫筆Graphics graphics=buffimg.getGraphics();gameBackground.draw(graphics);bird.draw(graphics);gameFrontground.draw(graphics);try {gameBarrierLayer.draw(graphics,bird);} catch (NumberFormatException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//一次性的將圖片繪制到屏幕中g.drawImage(buffimg,0,0,null);}else {String over="游戲結束";g.setColor(Color.red);g.setFont(new Font("微軟雅黑",1,60));g.drawString(over,300,250);String reset="Spce 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();}}
GameTime(計時)
package mian;
/** 計時類*/
public class GameTime {private long begingTime;//開始private long endTime;//結束private long differ;//時間差public GameTime() {}public void begin() {begingTime=System.currentTimeMillis();}public long differ() {endTime=System.currentTimeMillis();return differ=(endTime-begingTime)/1000;}
}
util(窗體)
Constant?
package util;import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;import javax.imageio.ImageIO;public class GameUtil {public static BufferedImage loadBufferedImage(String imgpath) {try {return ImageIO.read(new FileInputStream(imgpath));}catch(IOException e){e.printStackTrace();}return null;}}