国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Java實(shí)戰之飛翔的小鳥(niǎo)小游戲

發(fā)布時(shí)間:2021-07-06 11:12 來(lái)源:腳本之家 閱讀:0 作者:qq_42236679 欄目: 開(kāi)發(fā)技術(shù)

目錄

                                  前言

                                  一個(gè)簡(jiǎn)單的單機小游戲:flypybird ,用來(lái)鞏固java基礎。

                                  涉及主要知識點(diǎn):JFrame 、 JPanel 、 繼承、 鍵盤(pán)/鼠標監聽(tīng) 、 多線(xiàn)程 、 工具類(lèi)設計

                                   提示:這是大致的實(shí)現過(guò)程,實(shí)際實(shí)現過(guò)程有一定的修改,具體以源碼為準。

                                  一、大體思路

                                  1、首先要有一個(gè)框架,作為主程序入口,這里使用 JFrame  類(lèi)。

                                  2、然后需要有一個(gè)畫(huà)布,用來(lái)把游戲場(chǎng)景畫(huà)上去,然后在上面添加鍵盤(pán)/鼠標監聽(tīng)來(lái)控制,這里使用的是 JPenal 類(lèi)。

                                  3、需要創(chuàng )建幾個(gè)類(lèi):小鳥(niǎo)、地面、障礙物柱子、一個(gè)獲取圖片的工具類(lèi)

                                  4、然后逐步添加到畫(huà)布中,實(shí)現對應的功能

                                  二、具體步驟

                                  2.1 創(chuàng )建窗體類(lèi)

                                  相當于窗戶(hù)的框架,有了框架才能裝玻璃。然后也是主程序執行的入口

                                  2.1.1 具體代碼

                                  public class MainFrame extends JFrame {
                                   
                                      /* 圖標 */
                                      BufferedImage Icon;
                                   
                                      /*
                                       * 構造器用來(lái)初始化框架*/
                                      public MainFrame() throws IOException {
                                          /* 設置圖標 */
                                          Icon = ImageUtil.getImage("bird1_1.png");
                                          setIconImage(Icon);
                                          /* 設置關(guān)閉 */
                                          setDefaultCloseOperation(EXIT_ON_CLOSE);
                                          /* 設置標題 */
                                          setTitle("飛翔的小鳥(niǎo)");
                                          /* 設置尺寸*/
                                          setSize(298, 550);
                                          /* 設置大小不可變 */
                                          setResizable(false);
                                          /* 設置窗體居中 */
                                          setLocationRelativeTo(null);
                                      }
                                   
                                   
                                      /*
                                       * 主程序
                                       * */
                                      public static void main(String[] args) throws IOException {
                                          
                                          MainFrame mainFrame = new MainFrame();
                                          mainFrame.setVisible(true);
                                   
                                      }
                                  }
                                  

                                  2.1.2 效果展示

                                  2.1.3 小結

                                  大體框架做好,考慮到后面還需要使用比較多的圖片,因此接下來(lái)先建一個(gè)工具類(lèi),用來(lái)獲取圖片資源。

                                  三、創(chuàng )建一個(gè)獲取圖片的工具類(lèi)

                                  3.1 具體代碼

                                  /*
                                   * 工具類(lèi),用來(lái)獲取圖片
                                   * */
                                  public class ImageUtil {
                                      public static BufferedImage getImage(String name) throws IOException {
                                         
                                          return ImageIO.read(new BufferedInputStream(new FileInputStream("birdGame/flyBird/" + name)));
                                      }
                                  }
                                  

                                  3.2 小結

                                  圖片獲取方式改為用工具類(lèi)獲取,只需要輸入圖片名+格式。后期方便減少重復代碼的書(shū)寫(xiě)。

                                  四、創(chuàng )建畫(huà)布

                                  使用 Jpanel 類(lèi),創(chuàng )建畫(huà)布(相當于玻璃) ,就能在上面畫(huà)游戲的畫(huà)面了。后期還需要在上面添加鼠標/鍵盤(pán)監聽(tīng)。

                                  4.1 具體代碼

                                  public class GameJPenal extends JPanel {
                                      /*
                                       * 各種參數應該設置在這
                                       * */
                                      BufferedImage bg; 
                                      
                                      /*
                                       * 構造方法用來(lái)完成數據的初始化
                                       * */
                                      public GameJPenal() throws IOException {
                                          bg = ImageUtil.getImage("bg_day.png"); 
                                      }
                                      
                                      /*
                                       * 開(kāi)始游戲的方法
                                       * */
                                      public void start() {
                                          gameStart = true;
                                          Thread myThread = new Thread(new MyThread());
                                          myThread.start();
                                      }
                                   
                                   
                                      //繪制的方法
                                      @Override
                                      public void paint(Graphics g) { 
                                          g.drawImage(bg, 0, 0, 288, 512, null);     //背景
                                         
                                      }
                                  }
                                  

                                  4.2 效果展示

                                  先在main方法中創(chuàng )建對象,把畫(huà)布添加到框架里面,注意要重新在最后設置可見(jiàn),否者看不到背景

                                  /*
                                       * 主程序
                                       * */
                                      public static void main(String[] args) throws IOException {
                                   
                                          MainFrame mainFrame = new MainFrame();
                                   
                                          GameJPenal gameJPenal = new GameJPenal();
                                   
                                          mainFrame.add(gameJPenal);  /* 畫(huà)布添加到框架上 */
                                   
                                          mainFrame.setVisible(true);
                                   
                                          gameJPenal.requestFocus(); /* 請求屏幕焦點(diǎn) ,否則無(wú)法實(shí)現鍵盤(pán)監聽(tīng) */
                                   
                                      }
                                  

                                  接下來(lái)就可以運行,效果如下

                                  4.3 小結

                                  這里需要注意一個(gè)點(diǎn)就是請求屏幕焦點(diǎn):后期如果要做鍵盤(pán)監聽(tīng)的話(huà)必須有焦點(diǎn),否則無(wú)法實(shí)現鍵盤(pán)控制

                                  五、把地面畫(huà)上去

                                  5.1 代碼

                                  public class Ground {
                                      BufferedImage land;
                                      /*  x,y 是地面在畫(huà)布上的坐標 */ 
                                      private int x;
                                      private int y;
                                      private final int SPEED = 4;  //控制地面移動(dòng)的速度
                                   
                                      public Ground() throws IOException {
                                          land = ImageUtil.getImage("land.png");
                                          x = 0;
                                          y = 512 - land.getHeight();
                                      }
                                   
                                      /*
                                       * 地面移動(dòng)的效果
                                       * */
                                      public void move() {
                                          if (x == (288 - land.getWidth())) {
                                              x = 0;
                                          }
                                          x-=SPEED;
                                      }
                                   
                                      /*
                                      * get方法
                                      * */
                                      public int getX() {
                                          return x;
                                      }
                                   
                                      public int getY() {
                                          return y;
                                      }
                                  }
                                  

                                  接下來(lái)就是把地面的圖片用畫(huà)筆畫(huà)上去

                                   
                                  g.drawImage(land.landImg, land.x, land.y, land.w, land.h, null);

                                  六、創(chuàng )建一個(gè)新線(xiàn)程讓畫(huà)面動(dòng)起來(lái)

                                  先把變量添加到 GamePanel 類(lèi)

                                  Land land;    //地面
                                      Thread newThread;  //線(xiàn)程
                                      boolean gameStart; // 游戲狀態(tài)變量,準備狀態(tài)為 false ,游戲開(kāi)始為 true
                                      boolean gameOver;  //狀態(tài)變量, 游戲開(kāi)始為false ,游戲結束為true
                                  

                                  在GamePanel 構造器里面初始化變量,創(chuàng )建一個(gè)新線(xiàn)程,用死循環(huán)不斷調用地面移動(dòng)的方法,然后重畫(huà)畫(huà)面,實(shí)現移動(dòng)的效果

                                  這里還加了倆個(gè)游戲的狀態(tài)變量,主要是為了方便實(shí)現游戲的準備畫(huà)面和游戲結束后可以重新開(kāi)始游戲:

                                  boolean gameStart;  //游戲準備狀態(tài)
                                  boolean gameOver;   //游戲結束狀態(tài)
                                  /*
                                       * 新開(kāi)一個(gè)線(xiàn)程
                                       * */
                                      class MyThread implements Runnable {
                                          @Override
                                          public void run() {
                                              while (true) {
                                                  ground.move();
                                                  c0.move();
                                                  c1.move();
                                                  bird.fly();
                                                  bird.move();
                                                  isGameOver();
                                                  repaint();
                                                  if (gameOver) {
                                                      return;
                                                  }
                                                  try {
                                                      Thread.sleep(20);
                                                  } catch (InterruptedException e) {
                                                      e.printStackTrace();
                                                  }
                                              }
                                          }
                                      }
                                  

                                  小結:

                                  這時(shí)候畫(huà)面已經(jīng)能動(dòng)起來(lái)了,接下來(lái)就是把其它的對象創(chuàng )建出來(lái)添加進(jìn)去:鳥(niǎo) 、 障礙物(柱子)

                                  七、創(chuàng )建柱子類(lèi)

                                   和創(chuàng )建地面類(lèi)似,需要有他的坐標點(diǎn)和高度,同時(shí)為了畫(huà)面柱子的連續性,需要倆組不同的柱子,

                                  /*
                                   * 柱子類(lèi)
                                   * */
                                  public class Column {
                                   
                                      private final int SPEED = 2;
                                      int w1;
                                      int h1;
                                      int x1;
                                      int y1;
                                      BufferedImage img1;
                                   
                                      int w2;
                                      int h2;
                                      int x2;
                                      int y2;
                                      BufferedImage img2;
                                   
                                      /*
                                       * 構造方法
                                       * 初始化對象*/
                                      public Column(int i) throws IOException {
                                   
                                          img1 = ImageUtil.getImage("pipe_down.png");
                                          w1 = img1.getWidth() / 2;
                                          h1 = img1.getHeight();
                                          x1 = 288 + i * 150;
                                          y1 = -100 - i * 20;
                                   
                                          img2 = ImageUtil.getImage("pipe_up.png");
                                          w2 = img2.getWidth() / 2;
                                          h2 = img2.getHeight();
                                          x2 = 288 + i * 150;
                                          y2 = h2 - i * 25 -20;
                                      }
                                   
                                      /*柱子移動(dòng)的方法
                                       * */
                                      public void move() {
                                   
                                          if (x1 == -w1) {
                                              x1 = 288;
                                          }
                                          if (x2 == -w2) {
                                              x2 = 288;
                                          }
                                          x1 -= SPEED;
                                          x2 -= SPEED;
                                      }
                                  }
                                  

                                  八、實(shí)現柱子在畫(huà)布上的移動(dòng)

                                  和地面的初始化一樣,在畫(huà)布上添加成員變量,進(jìn)行初始化,接下來(lái)用畫(huà)筆在畫(huà)布上畫(huà)出來(lái),在線(xiàn)程里面的死循環(huán)調用它移動(dòng)的方法,實(shí)現柱子的移動(dòng)

                                  小結:

                                  接下來(lái)就是把小鳥(niǎo)添加到畫(huà)布上來(lái)

                                  九、創(chuàng )建小鳥(niǎo)類(lèi)

                                  小鳥(niǎo)的x軸位置其實(shí)是固定的,因此小鳥(niǎo)只需要能在y軸移動(dòng)就行,這一部分可以通過(guò)鼠標活著(zhù)鍵盤(pán)監聽(tīng)來(lái)控制

                                  小鳥(niǎo)有一個(gè)扇翅膀的動(dòng)作,通過(guò)把圖片存在一個(gè)集合里面,通過(guò)循環(huán),每次畫(huà)一個(gè)圖片,就能實(shí)現扇翅膀的效果

                                  難點(diǎn):小鳥(niǎo)的上下移動(dòng)的方法的設計

                                  這里通過(guò)設計一個(gè)類(lèi)似拋物線(xiàn)的動(dòng)作,每次按下鍵盤(pán)Up,就改變它的上拋的初速度,讓小鳥(niǎo)往上飛,經(jīng)過(guò)時(shí)間 t 開(kāi)始做落體運動(dòng)

                                  public class Bird {
                                      private double v0;  /* 小鳥(niǎo)運動(dòng)的初速度 */
                                      double t;  /* 往上運動(dòng)的時(shí)間 */
                                      int s;   /* 往上運動(dòng)的路程 */
                                      int x;
                                      int y;
                                      int g;   /* 重力 */
                                      BufferedImage img;
                                      ArrayList<BufferedImage> list;  /* 裝三張不同動(dòng)作的圖片 */
                                   
                                      public Bird() throws IOException {
                                          g = 3;
                                          v0 = 5;
                                          t = 0.3;
                                          img = ImageUtil.getImage("bird1_1.png");
                                          x = 100;
                                          y = 200;
                                          list = new ArrayList<>();
                                          list.add(ImageUtil.getImage("bird1_0.png"));
                                          list.add(ImageUtil.getImage("bird1_1.png"));
                                          list.add(ImageUtil.getImage("bird1_2.png"));
                                      }
                                   
                                      /*
                                       * 鳥(niǎo)飛的動(dòng)作,通過(guò)改變每次畫(huà)不同動(dòng)作的圖片來(lái)實(shí)現
                                       * */
                                      int i = 0;
                                      public void fly() {
                                          if (i >= 3) {
                                              i = 0;
                                          }
                                          img = list.get(i);
                                          i++;
                                      }
                                      /*
                                       * 鳥(niǎo)的上拋移動(dòng)
                                       * */
                                      public void moveUP() {
                                          v0 = 10;
                                      }
                                      /*
                                       * 鳥(niǎo)的落體運動(dòng)*/
                                      public void move() {
                                          s= (int) (v0*t);
                                          y -= s;
                                          double v2 = v0 - g * t;
                                          v0 = v2;
                                      }
                                  }
                                  

                                  十、小鳥(niǎo)添加到畫(huà)布

                                  和柱子一樣,不做贅述

                                  效果如下:

                                  十一、實(shí)現鍵盤(pán)監聽(tīng)

                                  注意:實(shí)現加鍵盤(pán)監聽(tīng)需要畫(huà)布獲得焦點(diǎn)

                                  方法1:main 方法中設置

                                  gameJPenal.requestFocus();

                                  方法2:直接在GamePanel 類(lèi)設置

                                  setFocusable(true);

                                  主要代碼:

                                  this.addKeyListener(new KeyAdapter() {
                                              @Override
                                              public void keyPressed(KeyEvent e) {
                                                  if (gameOver) {
                                                      if (e.getKeyCode() == KeyEvent.VK_UP) {
                                                          gameOver = false;
                                                          gameStart = false;
                                                          try {
                                                              ground = new Ground();
                                                              c0 = new Column(0);
                                                              c1 = new Column(1);
                                                              bird = new Bird();
                                                            
                                                          } catch (IOException ioException) {
                                                              ioException.printStackTrace();
                                                          }
                                                      }
                                        
                                   
                                                  } else if (gameStart) {
                                                      if (e.getKeyCode() == KeyEvent.VK_UP) {
                                                          bird.moveUP();
                                                      }
                                                  } else {
                                                      start();
                                                  }
                                              }
                                          });
                                  

                                  十二、判斷游戲結束的方法

                                  判斷游戲結束其實(shí)比較簡(jiǎn)單,通過(guò)檢測小鳥(niǎo)的x, y 坐標以及小鳥(niǎo)圖片的寬度與柱子的x , y 坐標加上柱子的寬度做一個(gè)碰撞檢測

                                  /*
                                       * 判定游戲是否結束的方法
                                       * */
                                      public void isGameOver() {
                                          //先判斷是否落地
                                          if (bird.y <= 0 || bird.y >= 512 - ground.land.getHeight() - bird.img.getHeight()) {
                                              gameOver = true;
                                          }
                                          //判斷是否撞柱子
                                          int bh = bird.img.getHeight();
                                          int bw = bird.img.getWidth();
                                          //c0.img1, c0.x1, c0.y1, c0.w1, c0.h1, null
                                          if (c0.x1 <= bird.x + bw && c0.x1 + c0.w1 >= bird.x && c0.y1 + c0.h1 >= bird.y) {
                                              gameOver = true;
                                          }
                                          if (c1.x1 <= bird.x + bw && c1.x1 + c1.w1 >= bird.x && c1.y1 + c1.h1 >= bird.y) {
                                              gameOver = true;
                                          }
                                          if (c0.x2 <= bird.x + bw && c0.x2 + c0.w2 >= bird.x && c0.y2 <= bird.y + bh) {
                                              gameOver = true;
                                          }
                                          if (c1.x2 <= bird.x + bw && c1.x2 + c1.w2 >= bird.x && c1.y2 <= bird.y + bh) {
                                              gameOver = true;
                                          }
                                      }
                                  
                                  if (gameStart == false) {
                                              g.drawImage(imageStart, 50, 200, null);
                                          }
                                          if (gameOver == true) {
                                              g.drawImage(imageGameOver, 50, 200, null);
                                  

                                  十三、游戲結束后回到準備狀態(tài)

                                  這里其實(shí)就是狀態(tài)重置,寫(xiě)在在鍵盤(pán)監聽(tīng)事件里面,邏輯就是游戲結束,只要按了Up鍵,游戲就重置為準備狀態(tài)。同時(shí),在游戲 paint 方法中加一個(gè)判斷,不同的狀態(tài)對應不同的圖片

                                  if (gameOver) {
                                                      if (e.getKeyCode() == KeyEvent.VK_UP) {
                                                          gameOver = false;
                                                          gameStart = false;
                                                          try {
                                                              ground = new Ground();
                                                              c0 = new Column(0);
                                                              c1 = new Column(1);
                                                              bird = new Bird();
                                                              score = 0;
                                                          } catch (IOException ioException) {
                                                              ioException.printStackTrace();
                                                          }
                                                      }
                                                      repaint();
                                  

                                  十四、統計分數

                                  分數統計原理:小鳥(niǎo)的x坐標和柱子的( x+w)相等,分數就+1

                                  if (bird.x == c0.x1 + c0.w1 || bird.x == c1.x1 + c1.w1) {
                                                      score++;
                                                  }

                                  總結

                                  游戲結構并不復雜,只需要逐步實(shí)現每個(gè)功能即可。然后用到的主要是一些比較基礎的知識,對于鞏固基礎知識還是有一定幫助的。

                                  第一次寫(xiě)博客,可能不夠精簡(jiǎn),可讀性不強。下次加油  。

                                  到此這篇關(guān)于Java實(shí)戰之飛翔的小鳥(niǎo)小游戲的文章就介紹到這了,更多相關(guān)java飛翔的小鳥(niǎo)內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

                                  免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

                                  永久免费AV无码网站性色AV| 亚洲中文字幕无码天然素人在线| 试看免费120秒| 中文字幕无码精品亚洲资源网久久| 久久久久久无码AV成人影院| 国产熟女露脸大叫高潮|