JAVA實現flappy bird游戲

圖片素材

實現代碼

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.IOException;public class BackGroundView extends JPanel {BufferedImage bgImage; //背景圖片BufferedImage groundImg;//地面圖片BufferedImage imgStart;//開始游戲圖片BufferedImage imgEnd;//GameOVer圖片public int bg_width;//背景圖片寬度public int bg_height;//背景圖片高度public int ground_width;//地面圖片寬度public int ground_height;//地面圖片高度public int ground_x,ground_y;//地面繪制起始坐標public int speed = 0;//管道和地面移動的速度public int state = 0;//游戲狀態,0表示未開始,1表示正在玩,2表示GameOverpublic static final int MOVE_SPEED1 = 50;// 地面及柱子移動初始速度,當積分累加,速度會遞增public static final int jframeWidth = 432;//窗口寬度(bg.png寬度)public static final int jframeHeight = 644;//窗口高度(bg.png高度)public static final String PATH_PIC = "\\pictures\\";public static final String PATH_BG = PATH_PIC + "bg.png";//背景圖片路徑public static final String PATH_GROUND = PATH_PIC + "ground.png";public static final String PATH_IMGSTART = PATH_PIC + "start.png";public static final String PATH_IMGEND = PATH_PIC + "gameover.png";public static final int FONT_SIZE = 30;//得分字體大小public static final int SCORE_X = 20;public static final int SCORE_Y = 40;public int score;public JFrame jframeMain;public GameBoard gameBoard;public Bird bird;public Pipe pipe1,pipe2;public BackGroundView(){initFrame();//初始化窗口}public void initFrame(){jframeMain = new JFrame("Flappy Bird");jframeMain.setSize(jframeWidth, jframeHeight);jframeMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jframeMain.setLocationRelativeTo(null);//居中顯示jframeMain.setResizable(false);//窗口Size固定gameBoard = new GameBoard();//初始化內部類GameBoardjframeMain.add(gameBoard);Thread moveAll = new Thread(gameBoard);moveAll.start();}//游戲面板class GameBoard extends JPanel implements Runnable{public GameBoard(){initGame();//初始化游戲}public void initGame(){//原則:先加載后繪制try{//1、加載背景圖片bgImage = ImageIO.read(this.getClass().getResource(PATH_BG));//根據當前路徑加載圖片進內存//獲取圖片寬度與高度bg_width = bgImage.getWidth();bg_height = bgImage.getHeight();System.out.println("bg_width:" + bg_width + ",bg_height:" + bg_height);//2、加載地面圖片,注意大的圖片要先加載,否則會遮住之前加載的groundImg = ImageIO.read(this.getClass().getResource(PATH_GROUND));ground_width = groundImg.getWidth();ground_height = groundImg.getHeight();ground_x = 0;ground_y = bg_height - ground_height;System.out.println("ground_width:" + ground_width + ",ground_height:" + ground_height);System.out.println("ground_x:" + ground_x + ",ground_y:" + ground_y);//3、加載開始和結束圖片imgStart = ImageIO.read(this.getClass().getResource(PATH_IMGSTART));imgEnd = ImageIO.read(this.getClass().getResource(PATH_IMGEND));//4、加載小鳥圖片,并在繪制中繪制小鳥,在run中讓小鳥飛動bird = new Bird();//5、加載管道圖片,一個窗口中最多顯示兩個管道pipe1 = new Pipe(bg_width, bg_height, ground_height);pipe1.x = bg_width;//第一根管道位置pipe2 = new Pipe(bg_width, bg_height, ground_height);pipe2.x = bg_width + Pipe.PIPE_DISTANCE;//第二跟管道位置}catch (IOException e){ }//3、讓地面移動speed = MOVE_SPEED1;//速度初始化}@Overridepublic void run() {action();//處理鍵盤事件//移動while(true){try{if (state == 0) {groundMove();//地面移動,初始化窗口未開始游戲地面和小鳥就要動bird.fly();//小鳥飛動}else if (state == 1){groundMove();//地面移動,初始化窗口未開始游戲地面和小鳥就要動bird.fly();//小鳥飛動bird.down();//僅游戲開始時下降pipe1.move();//讓兩根管子動起來pipe2.move();//小鳥撞到地面,天空,柱子都GameOverif (bird.hitPipe(pipe1) || bird.hitPipe(pipe2) || bird.hitGround(bg_height, ground_height) || bird.hitSky()){state = 2;}else {if (bird.addScore(pipe1) || bird.addScore(pipe2)){//每次通過一個得分加10分,速度也增加score += 10;speed += 2;}}}else if (state == 2){}Thread.sleep(1000 / speed);//speed越大線程休眠時間越少,執行次數越多,速度就越快this.repaint();//刷新,會自動重新調用paint()方法}catch (InterruptedException e){ }}}public void groundMove(){ground_x--;//地面左移,可以實現小鳥右移if (ground_x == bg_width - ground_width + 9){//9為修正值,自己調的,保證移動更流暢ground_x = 0;}}public void action(){//設置監聽事件this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);switch(state){case 0://游戲未開始點擊,就切換為開始游戲state = 1;bird.x = Bird.BIRD_FLY_X;bird.y = Bird.BIRD_FLY_Y;break;case 1://游戲開始bird.up();//游戲中點擊就是上升break;case 2://切換到未開始狀態,得分清零,小鳥與管道位置重置state = 0;score = 0;bird.x = Bird.BIRD_X;bird.y = Bird.BIRD_Y;pipe1.x = bg_width;pipe2.x = bg_width + Pipe.PIPE_DISTANCE;break;default:break;}}});}@Overridepublic void paint(Graphics g) {super.paint(g);//System.out.println("paint方法被調用時間:" + getCurrentTime());g.drawImage(bgImage,0,0,null);//繪制背景if (state == 0){//游戲未開始g.drawImage(imgStart,0,0,null);g.drawImage(bird.img, bird.x, bird.y, null);}else if (state == 1){//游戲開始g.drawImage(bird.img, bird.x, bird.y, null);//點擊開始后,初始坐標也同時變g.drawImage(pipe1.img, pipe1.x, pipe1.y, null);g.drawImage(pipe2.img, pipe2.x, pipe2.y, null);}else if (state == 2){//游戲結束g.drawImage(imgEnd,0,0,null);}g.drawImage(groundImg , ground_x, ground_y, null);//繪制地面//繪制分數Graphics2D gg = (Graphics2D) g;Font scoreFont = new Font("微軟雅黑", Font.BOLD, FONT_SIZE);//得分字體//下面兩句是抗鋸齒模式,消除文字鋸齒,字體更清晰順滑gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);gg.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);gg.setFont(scoreFont);gg.setColor(Color.WHITE);gg.drawString("" + score, SCORE_X, SCORE_Y);}//當前時間public String getCurrentTime() {Date day = new Date();SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");return df.format(day);}}public void showView(){jframeMain.setVisible(true);}
}
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;//小鳥類
public class Bird {public static final int BIRD_PIC_COUNT = 8;//小鳥圖片個數,8張圖片輪播形成飛行時的樣子public static final int BIRD_X = 190;//初始化小鳥坐標(游戲未開始小鳥位置)public static final int BIRD_Y = 220;public static final int BIRD_FLY_X = 120;//開始游戲后小鳥初始坐標public static final int BIRD_FLY_Y = 240;public static final int BIRD_UP_SPEED = 6;public static int index = 0;//當前小鳥圖片序號public int x,y;//小鳥坐標public int width;//小鳥寬度public int height;//小鳥高度public double g = 9.8;//重力加速度public double t = 0.05;//自然下降時間public double v,h;//下降速度與下降距離BufferedImage img;BufferedImage[] imgs = new BufferedImage[BIRD_PIC_COUNT];public Bird(){try{for (int i = 0; i < 8; i++) {imgs[i] = ImageIO.read(this.getClass().getResource(BackGroundView.PATH_PIC + i + ".png"));}img = imgs[0];//獲取小鳥寬高width = img.getWidth();height = img.getHeight();//初始化小鳥位置x = BIRD_X;y = BIRD_Y;}catch (IOException e){ }}// 小鳥飛翔的圖片切換public void fly() {index++;// 小鳥圖形切換的頻率,index/x,x越大,翅膀切換頻率越慢,index到48完成一次輪播img = imgs[index / 6 % BIRD_PIC_COUNT];//除以6是調整速度if (index == 6 * BIRD_PIC_COUNT) {index = 0;}}//上升public void up(){v = BIRD_UP_SPEED;//上升,鼠標點擊小鳥上升20}//下降public void down() {v = v - g*t;// Vt=Vo-gth = v - g*t*t/2;// h=Vot-gt2/2y = y - (int)h;}// 碰撞檢測// 是否碰撞地面public boolean hitGround(int bg_height, int ground_height) {if (y + height >= (bg_height - ground_height)) {return true;}return false;}// 碰撞到舞臺頂部public boolean hitSky() {if (y <= 0) {return true;}return false;}// 碰到柱子時的檢測public boolean hitPipe(Pipe p) {// x方向小鳥和柱子碰撞的條件if ((x + width) >= p.x && x <= p.x + p.width) {if (y <= p.y + (p.height - Pipe.PIPE_GAP) / 2|| y >= p.y + (p.height + Pipe.PIPE_GAP) / 2 - height) {return true;}}return false;}// 增加積分,通過管道后調用該方法public boolean addScore(Pipe p) {if (x == p.x + p.width) {return true;}return false;}
}
public class Main {public static void main(String[] args) {new BackGroundView().showView();}
}
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;public class Pipe {public static int PIPE_GAP = 144;//中間可通過的缺口大小public static int PIPE_DISTANCE = 244;//管道之間的間距BufferedImage img;//管道圖片public int x,y;//坐標public int width,height;//柱子寬高private int max, min;//保證管道完全能顯示在屏幕上,所以要設置max與minRandom random = new Random();//管道隨機出現public int bg_width;public Pipe(int bg_width, int bg_height, int ground_height){this.bg_width = bg_width;try{img = ImageIO.read(this.getClass().getResource(BackGroundView.PATH_PIC + "pipe.png"));width = img.getWidth();height = img.getHeight();System.out.println("Pipe_width = " + width + ",Pipe_height = " + height);//width=74,height=1200x = bg_width;//管道在不在初始背景出現,在背景"右邊"max = (height - PIPE_GAP) / 2;//圖片有上下兩管道,這個max表示一個管道的高度min = (height - PIPE_GAP) / 2 - (bg_height - PIPE_GAP - ground_height);//管道出現的最小長度y = -(min + random.nextInt(max - min));//管道隨機出現的坐標}catch (IOException e){ }}//游戲開始,柱子就要向左移動public void move(){x--;//若柱子走出最左邊窗口,管道就重新初始化if (x == -width){x = bg_width;y = -(min + random.nextInt(max - min));//管道隨機出現的坐標}}}

?游戲界面與實現效果

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/163717.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/163717.shtml
英文地址,請注明出處:http://en.pswp.cn/news/163717.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

飛翔的小鳥游戲

GameApp類 package 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.Buf…

gitea倉庫鏡像同步至gitlab

1、參考文檔&#xff1a;倉庫鏡像 | Gitea Documentation 2、錯誤一&#xff1a;賬號密碼錯誤問題 解決方法&#xff1a; 出現以上錯誤為第三步用戶名&#xff08;Oauth2應用名稱&#xff09;或者密碼&#xff08;Gitlab個人訪問令牌&#xff09;錯誤。 1&#xff09;如下圖1…

【UE4虛幻】UTexture2D紋理裁剪函數

參數說明&#xff1a; 源2D紋理圖片&#xff1a;UTexture2D* SourceTexture 裁剪區域的左上角&#xff1a;const FVector2D TopLeft 裁剪區域的右下角&#xff1a;const FVector2D BottomRight 返回值是裁剪之后的紋理圖片 UTexture2D* APointProjection::CropPicture(UTextur…

洗地機哪個牌子好用?洗地機選購攻略

傳統的清潔方式都是掃把拖把的結合&#xff0c;既繁瑣也勞累&#xff0c;每次清潔完后還得累的腰酸背痛的&#xff0c;像廚房這種地方甚至會不容易清潔干凈&#xff0c;總感覺地板灰蒙蒙的。洗地機的誕生就很好的解決了這些問題&#xff0c;不用一遍遍的重復掃地拖地擦地&#…

1410. HTML 實體解析器 --力扣 --JAVA

題目 「HTML 實體解析器」 是一種特殊的解析器&#xff0c;它將 HTML 代碼作為輸入&#xff0c;并用字符本身替換掉所有這些特殊的字符實體。 HTML 里這些特殊字符和它們對應的字符實體包括&#xff1a; 雙引號&#xff1a;字符實體為 &quot; &#xff0c;對應的字符是 &qu…

JOSEF約瑟 過電流繼電器 JL15-300/11 觸點形式一開一閉 板前接線

系列型號 JL15-1.5/11電流繼電器JL15-2.5/11電流繼電器 JL15-5/11電流繼電器JL15-10/11電流繼電器 JL15-15/11電流繼電器JL15-20/11電流繼電器 JL15-30/11電流繼電器JL15-40/11電流繼電器 JL15-60/11電流繼電器JL15-80/11電流繼電器 JL15-100/11電流繼電器JL15-150/11電流繼電…

linux的系統

10.4 I2C 系統的重要結構體 參考資料&#xff1a; ? Linux 驅動程序:&#xff08;某版本的 Linux&#xff0c;比如 Linux-4.9.88&#xff09;/drivers/i2c ? I2CTools: https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/ 284 / 577 10.4.1 重要結構體 使用一句…

母嬰團隊半年破億秘訣揭秘,合規經營成就輝煌

這支母嬰產品銷售團隊在短短半年內實現了過億的銷售額&#xff0c;這是一個令人矚目的成就。他們既不依賴線下門店&#xff0c;也不是傳統的電商平臺&#xff0c;那么他們是如何做到這一點的呢&#xff1f; 這個團隊從16年10月開始經營母嬰產品&#xff0c;如今已經過去了6年時…

生成式AI:SEO的末日?

由于在搜索結果中引入生成式AI (GAI)&#xff0c;以 SEO 為主導的內容的未來成為最近的熱門話題&#xff0c;這是有充分理由的。 對于出版商和網站所有者&#xff08;從現在開始我們將他們稱為內容創建者&#xff09;的影響可能是毀滅性的。 如下圖所示&#xff0c;谷歌新的搜…

成為AI產品經理——模型構建過程(上)

目錄 一、背景 1.對內 2.對外 二、模型構建過程 1.模型設計 2.特征工程 ① 數據清洗 ② 特征提取 數值型數據 標簽/描述類數據特征 非結構化數據&#xff08;處理文本特征&#xff09; 網絡關系型數據 ③ 特征選擇 ④ 訓練集/測試集 一、背景 雖然產品經理不…

Linux應用開發基礎知識——I2C應用編程(十二)

前言&#xff1a; I2C&#xff08;Inter-Integrated Circuit BUS&#xff09;是集成電路總線&#xff0c;是目前應用最廣泛的總線之一&#xff0c;最初由PHILIPS&#xff08;現為NXP&#xff09;設計。它使用多主從架構&#xff0c;主要用于連接低速周邊設備。I2C總線在硬件物理…

WorkPlus即時通訊,打通上下游產業鏈,構建企業生態圈

如今&#xff0c;隨著信息技術的迅速發展&#xff0c;智慧水務、智慧醫療、智慧城市、智慧教育、智慧政務等領域正蓬勃發展。在這個智慧時代&#xff0c;企業需要一個具備開放性和擴展性的平臺級產品&#xff0c;以滿足多樣化的業務需求。WorkPlus作為一款全新的移動底座產品&a…

String 真的不可變嗎?

為什么 String 類不可變 final修飾符&#xff1a; String類被聲明為final&#xff0c;這意味著它不能被繼承。因此&#xff0c;無法創建String的子類來修改其行為。私有字符數組&#xff08;char[]&#xff09;&#xff1a; String類內部使用私有的字符數組來存儲字符串的內容…

Excel文件比較不再繁瑣,xlCompare助您快速找出差異

概要 在現代職場中&#xff0c;Excel 已成為工作中不可或缺的利器。 在日常操作中&#xff0c;我們會遇到需要對兩個或多個 Excel 文件進行比較的情況&#xff0c;此時&#xff0c;一款高效的 Excel 文件比較工具就顯得尤為重要。 本文將為您介紹一款功能強大、優勢明顯的 Exc…

創新建筑形式:氣膜體育館助力校園體育設施革新

體育場館在校園中扮演著重要的角色&#xff0c;是學生們進行體育鍛煉、比賽和各類體育活動的場所。傳統的室內體育館建設往往需要大量資金和漫長的建設周期&#xff0c;但隨著氣膜體育館的嶄露頭角&#xff0c;校園體育設施的面貌正迎來一場革新。 快速搭建&#xff0c;靈活性極…

電機應用開發-直流有刷電機電流環控制實現

目錄 直流有刷電機電流環控制實現 硬件設計 直流電機電流環控制-位置式PID實現 編程要點 配置ADC可讀取電流值 配置基本定時器6產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算 配置定時器1輸出PWM控制電機 ADC數據處理 編寫位置式PID算法 直流電機電流環控…

3、領導跟你談話,講到你的團隊里面的好友,公司會進行觀察裁員,你會去傳話么?

作為一個團隊成員&#xff0c;我會認真聽取領導的意見&#xff0c;并尊重公司的決定。然而&#xff0c;作為一個好友&#xff0c;我也會考慮他們的利益&#xff0c;我會與他們溝通&#xff0c;提醒他們注意自己的表現和工作&#xff0c;努力提高業績和工作質量&#xff0c;以確…

5個免費在線工具推薦

NSDT 三維場景建模工具GLTF/GLB在線編輯器Three.js AI自動紋理化開發包YOLO 虛幻合成數據生成器3D模型在線轉換 1、NSDT 三維場景建模 訪問地址&#xff1a;NSDT 編輯器 2、GLTF/GLB在線編輯器 訪問地址&#xff1a;GLTF 編輯器 3、Three.js AI自動紋理化開發包 圖一為原始模…

Linux下安裝兩個版本python

1 python下載&#xff1a; 官網地址&#xff1a;Download Python | Python.org 第一&#xff1a;點擊下載如下圖&#xff1a; 第二&#xff1a;找到對應的python版本源碼包&#xff1a; 點擊右鍵復制下載地址&#xff0c;如下圖 例如我的是&#xff1a;https://www.python.org/…

【鴻蒙應用ArkTS開發系列】- 云開發入門實戰二 實現省市地區聯動地址選擇器組件(上)

目錄 概述 云數據庫開發 一、創建云數據庫的對象類型。 二、預置數據&#xff08;為對象類型添加數據條目&#xff09;。 三、部署云數據庫 云函數實現業務邏輯 一、創建云函數 二、云函數目錄講解 三、創建resources目錄 四、獲取云端憑據 五、導出之前創建的元數據…