Java實(shí)現(xiàn)經(jīng)典游戲Flappy Bird的示例代碼
前言
《布谷鳥(niǎo)闖關(guān)-簡(jiǎn)單版》是一個(gè)基于java的布谷鳥(niǎo)闖關(guān)游戲,摁上鍵控制鳥(niǎo)的位置穿過(guò)管道間的縫隙,需要做碰撞檢測(cè),監(jiān)聽(tīng)鍵盤(pán)事件,背景圖片的切換,障礙物管道產(chǎn)生時(shí)y軸上需要隨機(jī)位置。
主要設(shè)計(jì)
- 設(shè)計(jì)游戲界面,用swing實(shí)現(xiàn)
- 設(shè)計(jì)背景
- 設(shè)計(jì)移動(dòng)墻
- 設(shè)計(jì)布谷鳥(niǎo)
- 設(shè)計(jì)障礙物
- 設(shè)計(jì)背景音樂(lè)和音效
- 由幾個(gè)關(guān)鍵的布爾類型變量start,crash,over是產(chǎn)生鍵鍵盤(pán)事件時(shí)用來(lái)控制界面顯示的彈框的
- 操作:空格鍵開(kāi)始游戲,enter鍵取消"game over"彈框,摁空格鍵繼續(xù),上鍵(up)是對(duì)鳥(niǎo)的控制
- 工具類ImageMgr專用于讀取圖片
功能截圖
游戲開(kāi)始:
控制布谷鳥(niǎo)
飛過(guò)障礙物
撞到障礙物,游戲結(jié)束
代碼實(shí)現(xiàn)
游戲啟動(dòng)類
public class Main { public static void main(String[] args) { Cuckoo frame = new Cuckoo(); while (true){ try { Thread.sleep(100); if(!frame.crash){ frame.repaint(); } } catch (InterruptedException e) { e.printStackTrace(); } } } }
核心類
/** * 1.窗口 * 2.背景 * 3.移動(dòng)墻 * 4.布谷鳥(niǎo) * 5.障礙物 * 6.背景音樂(lè) * 7.音效 * 8.歡迎界面 * 9.game over */ public class Cuckoo extends Frame { private int step; private int score; private int height; private int moveLeft; private int pipeMove; boolean crash = false; private boolean over = false; private boolean start = false; private static int bird_y = 270; private static final int L_X = 800; private static final int L_Y = 200; private static final int SPEED = 2; private static final int BIRD_X = 100; private static final int GAME_X_Y_0 = 0; private static final int GAME_WIDTH = 288; private static final int GAME_HEIGHT = 512; private static final int PIPE_WIDTH = ImageMgr.pipe.getWidth(); private static final int PIPE_HEIGHT = ImageMgr.pipe.getHeight(); private static final int READY_WIDTH = ImageMgr.ready.getWidth(); private static final int READY_HEIGHT = ImageMgr.ready.getHeight(); private static final int START_WIDTH = ImageMgr.start.getWidth(); private static final int BIRD_WIDTH = ImageMgr.bird[0].getWidth(); private static final int BIRD_HEIGHT = ImageMgr.bird[0].getWidth(); private static final int GROUND_HEIGHT = ImageMgr.ground.getHeight(); private static final int GAME_OVER_WIDTH = ImageMgr.gameOver.getWidth(); private static final int GAME_OVER_HEIGHT = ImageMgr.gameOver.getHeight(); private static final int BACKGROUND_HEIGHT = ImageMgr.background.getHeight(); private static Image offScreenImage; private static Rectangle pipeRectangle1; private static Rectangle pipeRectangle2; private static Rectangle birdRectangle; Cuckoo(){ setVisible(true); setResizable(false); //setTitle("cuckoo"); setBounds(L_X, L_Y,GAME_WIDTH,GAME_HEIGHT); addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()){ case KeyEvent.VK_SPACE : start = true;break; case KeyEvent.VK_ENTER : reopen();break; } } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { bird_y -= 20; } } }); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } @Override public void update(Graphics g) { if(offScreenImage == null){ offScreenImage = this.createImage(GAME_WIDTH,GAME_HEIGHT); } Graphics gOffScreen = offScreenImage.getGraphics(); Color c = gOffScreen.getColor(); gOffScreen.setColor(Color.BLACK); gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT); gOffScreen.setColor(c); paint(gOffScreen); g.drawImage(offScreenImage,0,0,null); } @Override public void paint(Graphics g) { background(g); ground(g); start(g); if(start){ bird(g); pipe(g); colliedWith(); gameOver(g); score(g); } } //如果碰撞后,可以嗯enter鍵重開(kāi) private void reopen(){ if(crash){ score = 0; over = false; crash = false; start = false; moveLeft = 0; pipeMove = 0; //bird_y = 270;//繼上次死的位置開(kāi)始 } } private void score(Graphics g){ Font font = new Font("微軟雅黑",Font.BOLD,18); g.setFont(font); Color c = g.getColor(); g.setColor(Color.lightGray); g.drawString("score " + score,20,70); g.setColor(c); } private void background(Graphics g){ g.drawImage(ImageMgr.background, GAME_X_Y_0 - moveLeft,GAME_X_Y_0, GAME_WIDTH - moveLeft,GAME_HEIGHT, GAME_X_Y_0, GAME_X_Y_0, GAME_WIDTH, GAME_HEIGHT, null); g.drawImage(ImageMgr.background, GAME_WIDTH-1 - moveLeft,GAME_X_Y_0, GAME_WIDTH*2 - moveLeft, GAME_HEIGHT, GAME_X_Y_0, GAME_X_Y_0, GAME_WIDTH, GAME_HEIGHT, null); moveLeft += SPEED; //游戲啟動(dòng)計(jì)分 if(start && moveLeft % 100 == 0){ score += 1; } if(moveLeft >= GAME_WIDTH){ moveLeft = 0; } } private void ground(Graphics g){ g.drawImage(ImageMgr.ground,0,BACKGROUND_HEIGHT - GROUND_HEIGHT,null); } private void bird(Graphics g){ Color c = g.getColor(); g.setColor(Color.BLUE); g.drawRect(BIRD_X, bird_y,BIRD_WIDTH,BIRD_HEIGHT); g.setColor(c); g.drawImage(ImageMgr.bird[step++], BIRD_X, bird_y,null); if(step >= ImageMgr.bird.length){ step = 0; } if(start){ bird_y += 4; } birdRectangle = new Rectangle(BIRD_X,bird_y,BIRD_WIDTH,BIRD_HEIGHT); } private void pipe(Graphics g){ drawPipe(g); pipeMove += SPEED; if(pipeMove >= GAME_WIDTH + PIPE_WIDTH){ pipeMove = 0; Random ran = new Random(); height = ran.nextInt(10)*20; drawPipe(g); } } private void drawPipe(Graphics g){ g.setColor(Color.RED); // g.drawRect(GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,PIPE_WIDTH,PIPE_HEIGHT); // g.drawRect(GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,PIPE_WIDTH,PIPE_HEIGHT); g.drawImage(ImageMgr.pipe,GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,null); g.drawImage(ImageMgr.pipe,GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,null); pipeRectangle1 = new Rectangle(GAME_WIDTH - pipeMove,GAME_HEIGHT/5*3 - height,PIPE_WIDTH,PIPE_HEIGHT); pipeRectangle2 = new Rectangle(GAME_WIDTH - pipeMove,-GAME_HEIGHT/5*4 - height,PIPE_WIDTH,PIPE_HEIGHT); } private void gameOver(Graphics g){ if(over){ g.drawImage(ImageMgr.gameOver,GAME_WIDTH/2 - GAME_OVER_WIDTH/2, GAME_HEIGHT/2 - GAME_OVER_HEIGHT,null); } } private void start(Graphics g){ if(!start){ g.drawImage(ImageMgr.ready,GAME_WIDTH/2 - READY_WIDTH/2, GAME_HEIGHT/2 - READY_HEIGHT,null); g.drawImage(ImageMgr.start,GAME_WIDTH/2 - START_WIDTH/2, GAME_HEIGHT/2,null); } } private void colliedWith(){ if(birdRectangle.intersects(pipeRectangle1) || birdRectangle.intersects(pipeRectangle2)){ crash = true; over = true; //gameOver(g); } } }
工具類
public class ImageMgr { static BufferedImage background,ground,pipe,gameOver,start,ready; static BufferedImage[] bird = new BufferedImage[3]; private static final ImageMgr INSTANCE = new ImageMgr(); //nothing private ImageMgr(){ initImage(); }; private void initImage(){ try { background = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/bg_light.png"))); ground = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/ground.png"))); pipe = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/pipe.png"))); gameOver = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/gameover.png"))); start = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/start.png"))); ready = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/ready.png"))); for(int i = 0;i < 3;i++){ bird[i] = ImageIO.read(Objects.requireNonNull(Cuckoo.class.getClassLoader().getResourceAsStream("images/blueBird_" + (i+1) + ".png"))); } } catch (IOException ex) { ex.printStackTrace(); } } public static ImageMgr getInstance(){ return INSTANCE; } }
總結(jié)
通過(guò)此次的《布谷鳥(niǎo)闖關(guān)-簡(jiǎn)單版》實(shí)現(xiàn),讓我對(duì)JAVA的相關(guān)知識(shí)有了進(jìn)一步的了解,對(duì)java這門(mén)語(yǔ)言也有了比以前更深刻的認(rèn)識(shí)。
java的一些基本語(yǔ)法,比如數(shù)據(jù)類型、運(yùn)算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷?,?duì)于這一個(gè)概念,終于悟到了一些。
以上就是Java實(shí)現(xiàn)經(jīng)典游戲Flappy Bird的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java Flappy Bird游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring?Boot攔截器和監(jiān)聽(tīng)器實(shí)現(xiàn)對(duì)請(qǐng)求和響應(yīng)處理實(shí)戰(zhàn)
這篇文章主要介紹了Spring?Boot攔截器和監(jiān)聽(tīng)器實(shí)現(xiàn)對(duì)請(qǐng)求和響應(yīng)處理實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06Java文件上傳與文件下載實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java文件上傳與文件下載實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Java文件上傳與文件下載相關(guān)操作原理、實(shí)現(xiàn)方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-02-02Java高并發(fā)之CyclicBarrier的用法詳解
CyclicBarrier 是 Java 中的一種同步工具,它可以讓多個(gè)線程在一個(gè)屏障點(diǎn)處等待,直到所有線程都到達(dá)該點(diǎn)后,才能繼續(xù)執(zhí)行。本文就來(lái)和大家聊聊它的用法,需要的可以參考一下2023-03-03WIN7系統(tǒng)JavaEE(java)環(huán)境配置教程(一)
這篇文章主要介紹了WIN7系統(tǒng)JavaEE(java+tomcat7+Eclipse)環(huán)境配置教程,本文重點(diǎn)在于java配置,感興趣的小伙伴們可以參考一下2016-06-06詳解使用IntelliJ IDEA新建Java Web后端resfulAPI模板
這篇文章主要介紹了詳解使用IntelliJ IDEA新建Java Web后端resfulAPI模板,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08SpringData Repository Bean方法定義規(guī)范代碼實(shí)例
這篇文章主要介紹了SpringData Repository Bean方法定義規(guī)范代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08