您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java怎么實現大魚吃小魚游戲”,在日常操作中,相信很多人在Java怎么實現大魚吃小魚游戲問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java怎么實現大魚吃小魚游戲”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
創建一個游戲窗口類 GameWin,創建一個 launch() 啟動方法,在其中設置窗口相關屬性:
import javax.swing.*; public class GameWin extends JFrame { int width = 1440; int height = 900; //創建一個啟動方法,設置窗口信息 public void launch() { this.setVisible(true); //設置窗口可見 this.setSize(width, height); //設置窗口大小 this.setLocationRelativeTo(null); //設置窗口居中 this.setResizable(false); //設置窗口大小不可改變 this.setTitle("大魚吃小魚"); //設置窗口標題 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //設置窗口按鈕 } }
創建一個游戲窗口測試類 GameWinDemo,進行窗口對象的創建和啟動方法的調用:
public class GameWinDemo { public static void main(String[] args) { //創建一個游戲窗口對象 GameWin gameWin = new GameWin(); //啟動窗口 gameWin.launch(); } }
將下載的背景圖片的文件夾復制到項目文件夾中:
創建一個工具類 GameUtils,在其中添加背景圖片:
import java.awt.*; public class GameUtils { public static Image bgimg = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\sea.jpg"); }
在 GameWin 類中添加 paint 方法,在其中繪制背景圖片:
@Override public void paint(Graphics g) { //用畫筆繪制背景圖片 g.drawImage(GameUtils.bgimg, 0, 0, null); }
如果發現背景圖片加載不出來,先檢查一下路徑有沒有寫錯,相對路徑不行的話就試試絕對路徑;有時候加載背景圖片會較慢,可以試著將運行出來的窗口最小化后再恢復
定義默認游戲狀態,同時在 paint 方法中對游戲狀態進行判斷進而顯示對應的游戲界面:
import javax.swing.*; import java.awt.*; public class GameWin extends JFrame { int width = 1440; int height = 900; //定義游戲默認狀態 static int state = 0; //創建一個啟動方法,設置窗口信息 public void launch() { this.setVisible(true); //設置窗口可見 this.setSize(width, height); //設置窗口大小 this.setLocationRelativeTo(null); //設置窗口居中 this.setResizable(false); //設置窗口大小不可改變 this.setTitle("大魚吃小魚"); //設置窗口標題 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //設置窗口按鈕 } @Override public void paint(Graphics g) { //用畫筆繪制背景圖片 g.drawImage(GameUtils.bgimg, 0, 0, null); //游戲狀態:0未開始,1游戲中,2游戲失敗,3游戲勝利,4游戲暫停,5重新開始 switch (state) { case 0: g.drawImage(GameUtils.bgimg, 0, 0, null); //為啟動頁面添加文字 g.setColor(Color.pink); g.setFont(new Font("仿宋", Font.BOLD, 60)); g.drawString("請點擊開始游戲", 600, 500); break; case 1: break; case 2: break; case 3: break; case 4: break; default: break; } } }
在啟動方法中添加鼠標監聽器,當點擊啟動頁面時游戲開始
//創建一個啟動方法,設置窗口信息 public void launch() { this.setVisible(true); //設置窗口可見 this.setSize(width, height); //設置窗口大小 this.setLocationRelativeTo(null); //設置窗口居中 this.setResizable(false); //設置窗口大小不可改變 this.setTitle("大魚吃小魚"); //設置窗口標題 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //設置窗口按鈕 //添加鼠標監聽事件 this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == 1 && state == 0) { state = 1; repaint(); } } }); }
新建一個背景圖的實體類 Bg,在 GameWin 類里創建其對象,并在 case 1 中調用繪制背景圖的方法
import java.awt.*; public class Bg { void paintSelf(Graphics g) { g.drawImage(GameUtils.bgimg, 0, 0, null); } }
由于游戲中需要不斷繪制背景圖片,所以我們在啟動方法中添加一個 while 循環,在其中每隔 40 毫秒重繪背景圖
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GameWin extends JFrame { int width = 1440; int height = 900; //定義游戲默認狀態 static int state = 0; //獲取背景圖類的對象 Bg bg = new Bg(); //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { this.setVisible(true); //設置窗口可見 this.setSize(width, height); //設置窗口大小 this.setLocationRelativeTo(null); //設置窗口居中 this.setResizable(false); //設置窗口大小不可改變 this.setTitle("大魚吃小魚"); //設置窗口標題 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //設置窗口按鈕 //添加鼠標監聽事件 this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == 1 && state == 0) { state = 1; repaint(); } } }); //背景圖片重復使用,需要重復調用repaint方法 while(true) { repaint(); Thread.sleep(40); } } @Override public void paint(Graphics g) { //用畫筆繪制背景圖片 g.drawImage(GameUtils.bgimg, 0, 0, null); switch (state) { case 0: g.drawImage(GameUtils.bgimg, 0, 0, null); //為啟動頁面添加文字 g.setColor(Color.pink); g.setFont(new Font("仿宋", Font.BOLD, 60)); g.drawString("請點擊開始游戲", 500, 500); break; case 1: bg.paintSelf(g); break; case 2: break; case 3: break; case 4: break; default: break; } } }
如果此時你的屏幕出現閃爍的情況,可以用下面的方法解決
整體思路為:
重新創建一個空的圖片,將所有的組件先繪制到空的圖片上,然后把繪制好的圖片一次性地繪制到主窗口上
創建一個空圖片對象,在 paint 方法中將所有組件繪制到空圖片上,再一次性繪制到主窗口上
public class GameWin extends JFrame { int width = 1440; int height = 900; //定義游戲默認狀態 static int state = 0; //獲取背景圖類的對象 Bg bg = new Bg(); //創建一個空圖片對象 Image offScreenImage; //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { this.setVisible(true); //設置窗口可見 this.setSize(width, height); //設置窗口大小 this.setLocationRelativeTo(null); //設置窗口居中 this.setResizable(false); //設置窗口大小不可改變 this.setTitle("大魚吃小魚"); //設置窗口標題 this.setDefaultCloseOperation(EXIT_ON_CLOSE); //設置窗口按鈕 //添加鼠標監聽事件 this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == 1 && state == 0) { state = 1; repaint(); } } }); //背景圖片重復使用,需要重復調用repaint方法 while (true) { repaint(); Thread.sleep(40); } } @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 switch (state) { case 0: //把組件重新繪制到主窗口中 gImage.drawImage(GameUtils.bgimg, 0, 0, null); //為啟動頁面添加文字 gImage.setColor(Color.pink); gImage.setFont(new Font("仿宋", Font.BOLD, 60)); gImage.drawString("請點擊開始游戲", 500, 500); break; case 1: bg.paintSelf(gImage); break; case 2: break; case 3: break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } }
新建敵方魚的父類 Enamy,編寫左敵方魚類 Enamy_1_L 繼承父類
import java.awt.*; public class Enamy { //定義圖片 Image img; //定義物體坐標 int x; int y; int width; int height; //移動速度 int speed; //方向 int dir = 1; //敵方魚的類型、分值 int type; int count; //繪制自身方法 public void paintSelf(Graphics g) { g.drawImage(img, x, y, width, height, null); } //獲取自身矩形用于碰撞檢測 public Rectangle getRec() { return new Rectangle(x, y, width, height); } } //左敵方魚類 class Enamy_1_L extends Enamy { Enamy_1_L() { this.x = -45; this.y = (int) (Math.random() * 700 + 100); this.width = 45; this.height = 69; this.speed = 10; this.count = 1; this.img = GameUtils.enamy_l_img; } }
在 GameUtils 類中添加左敵方魚類的圖片
public class GameUtils { //背景圖 public static Image bgimg = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\sea.jpg"); //敵方魚類 public static Image enamy_l_img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish2_r.gif"); }
在 GameWin 類中創建左敵方魚類對象并在 case 1 的情況下繪制左敵方魚類
public class GameWin extends JFrame { //...... //敵方魚類 Enamy enamy = new Enamy_1_L(); //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { //...... } @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 switch (state) { case 0: //把組件重新繪制到主窗口中 gImage.drawImage(GameUtils.bgimg, 0, 0, null); //為啟動頁面添加文字 gImage.setColor(Color.pink); gImage.setFont(new Font("仿宋", Font.BOLD, 60)); gImage.drawString("請點擊開始游戲", 500, 500); break; case 1: bg.paintSelf(gImage); enamy.paintSelf(gImage); enamy.x += enamy.speed; break; case 2: break; case 3: break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } }
在工具類中創建一個所有敵方魚物體的集合
public class GameUtils { //敵方魚類集合 public static List<Enamy> EnamyList = new ArrayList<>(); //...... }
在窗口類中添加一個方法,用于批量添加敵方魚類
public class GameWin extends JFrame { //...... //敵方魚類 Enamy enamy; //計數器,用來記錄游戲的重繪次數,也是魚生成的數量 int time = 0; //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { //...... }); //背景圖片重復使用,需要重復調用repaint方法 while (true) { repaint(); time++; Thread.sleep(40); } } @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 switch (state) { case 0: //...... case 1: bg.paintSelf(gImage); logic(); //不斷添加敵方魚類 //遍歷敵方魚類集合,繪制敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } break; case 2: break; case 3: break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } //批量添加魚類 void logic() { //每重繪10次生成一條敵方魚類 if (time % 10 == 0) { enamy = new Enamy_1_L(); GameUtils.EnamyList.add(enamy); } //移動方向 for (Enamy enamy : GameUtils.EnamyList) { enamy.x = enamy.x + enamy.dir * enamy.speed; } } }
在工具類中添加我方魚類的圖片
public class GameUtils { //...... //我方魚類 public static Image myFishImg_L = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\myFish\\myfish_left.gif"); public static Image myFishImg_R = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\myFish\\myfish_right.gif"); }
創建我方魚類
import java.awt.*; public class MyFish { //圖片 Image img = GameUtils.myFishImg_L; //坐標 int x = 700; int y = 500; int width = 50; int height = 50; //移動速度 int speed = 20; //等級 int level = 1; //繪制自身的方法 public void paintSelf(Graphics g) { g.drawImage(img, x, y, width, height, null); } //獲取自身矩形的方法 public Rectangle getRec() { return new Rectangle(x, y, width, height); } }
在窗口類中獲取我方魚的對象
//我方魚類 MyFish myFish = new MyFish();
在工具類中添加方向判定,用來控制我方魚的方向
public class GameUtils { //方向 static boolean UP = false; static boolean DOWN = false; static boolean LEFT = false; static boolean RIGHT = false; //...... }
在我方魚類添加一個方法,實現對鍵盤的控制
public class MyFish { //...... //繪制自身的方法 public void paintSelf(Graphics g) { //調用方法 logic(); g.drawImage(img, x, y, width, height, null); } //...... void logic() { if (GameUtils.UP) { y = y - speed; } if (GameUtils.DOWN) { y = y + speed; } if (GameUtils.LEFT) { x = x - speed; img = GameUtils.myFishImg_L; } if (GameUtils.RIGHT) { x = x + speed; img = GameUtils.myFishImg_R; } } }
在窗口類的 paint 方法的 case 1 中,添加我方魚類所創造的方法
import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class GameWin extends JFrame { //...... //我方魚類 MyFish myFish = new MyFish(); //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { //...... }); //鍵盤移動 this.addKeyListener(new KeyAdapter() { @Override//按壓 public void keyPressed(KeyEvent e) { //上下左右四個鍵的ASCII值為 上 ↑:38下 ↓: 40左 ←: 37右 →: 39 if (e.getKeyCode() == 38) { GameUtils.UP = true; } if (e.getKeyCode() == 40) { GameUtils.DOWN = true; } if (e.getKeyCode() == 37) { GameUtils.LEFT = true; } if (e.getKeyCode() == 39) { GameUtils.RIGHT = true; } } @Override//抬起 public void keyReleased(KeyEvent e) { if (e.getKeyCode() == 38) { GameUtils.UP = false; } if (e.getKeyCode() == 40) { GameUtils.DOWN = false; } if (e.getKeyCode() == 37) { GameUtils.LEFT = false; } if (e.getKeyCode() == 39) { GameUtils.RIGHT = false; } } }); //...... } @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 switch (state) { case 0: //...... break; case 1: bg.paintSelf(gImage); myFish.paintSelf(gImage); logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } break; case 2: break; case 3: break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } //批量添加魚類 void logic() { //...... } }
在游戲中所有物體被視為矩形,兩個物體是否碰撞,即檢測兩個物體的所在矩形是否有重疊部分
具體檢測,就是讓我方魚與敵方魚的矩形進行一一檢測,在窗口類的 logic() 方法中實現
//批量添加魚類 void logic() { //每重繪10次生成一條敵方魚類 if (time % 10 == 0) { enamy = new Enamy_1_L(); GameUtils.EnamyList.add(enamy); } //移動方向 for (Enamy enamy : GameUtils.EnamyList) { enamy.x = enamy.x + enamy.dir * enamy.speed; //我方魚與敵方魚的碰撞檢測 if (myFish.getRec().intersects(enamy.getRec())) { enamy.x = -200; enamy.y = -200; } } }
在工具類中定義分數
//分數 static int count = 0;
在窗口類中實現我方魚吃掉敵方魚增加分數,同時在頁面上打印分數
public class GameWin extends JFrame { //...... @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 switch (state) { case 0: //...... case 1: bg.paintSelf(gImage); //*******打印所得積分******** gImage.setColor(Color.ORANGE); gImage.setFont(new Font("仿宋", Font.BOLD, 50)); gImage.drawString("積分:" + GameUtils.count, 200, 120); myFish.paintSelf(gImage); logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } break; case 2: break; case 3: break; case 4: break; default: break; } //...... //批量添加魚類 void logic() { //...... //移動方向 for (Enamy enamy : GameUtils.EnamyList) { enamy.x = enamy.x + enamy.dir * enamy.speed; //我方魚與敵方魚的碰撞檢測 if (myFish.getRec().intersects(enamy.getRec())) { enamy.x = -200; enamy.y = -200; //********得分******** GameUtils.count += enamy.count; } } } }
在我方魚類中實現吃掉敵方魚后,我方魚體積增加
public class MyFish { //...... //繪制自身的方法 public void paintSelf(Graphics g) { logic(); g.drawImage(img, x, y, width + GameUtils.count, height + GameUtils.count, null); } //獲取自身矩形的方法 public Rectangle getRec() { return new Rectangle(x, y, width + GameUtils.count, height + GameUtils.count); } //...... }
根據積分來實現關卡的設置,如果達到目標積分則過關,并增加我方魚的等級
在工具類中定義關卡等級
//關卡等級 static int level = 0;
在窗口類的 logic() 方法中設置關卡
public class GameWin extends JFrame { //...... @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 switch (state) { case 0: //...... break; case 1: //...... break; case 2: break; case 3: //玩家勝利 bg.paintSelf(gImage); myFish.paintSelf(gImage); gImage.setColor(Color.ORANGE); gImage.setFont(new Font("仿宋", Font.BOLD, 80)); gImage.drawString("積分: " + GameUtils.count, 200, 120); gImage.drawString("勝利", 400, 500); break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } //批量添加魚類 void logic() { //關卡難度 if (GameUtils.count < 5) { GameUtils.level = 0; myFish.level = 1; } else if (GameUtils.count <= 15) { GameUtils.level = 1; } else if (GameUtils.count <= 50) { GameUtils.level = 2; myFish.level = 2; } else if (GameUtils.count <= 150) { GameUtils.level = 3; myFish.level = 3; } else if (GameUtils.count <= 300) { GameUtils.level = 4; myFish.level = 3; } else { //分數大于300,玩家勝利 state = 3; } //...... } }
實現游戲界面積分、難度、關卡的可視化編寫
在工具類中定義繪制文字的方法
//繪制文字的方法 public static void drawWord(Graphics g, String str, Color color, int size, int x, int y) { g.setColor(color); g.setFont(new Font("仿宋", Font.BOLD, size)); g.drawString(str, x, y); }
在背景類中讓積分、難度、我方魚等級可視化
public class Bg { void paintSelf(Graphics g, int fishLevel) { g.drawImage(GameUtils.bgimg, 0, 0, null); switch (GameWin.state) { case 0: GameUtils.drawWord(g, "請點擊開始游戲", Color.RED, 80, 500, 500); break; case 1: GameUtils.drawWord(g, "積分:" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "難度:" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等級:" + fishLevel, Color.ORANGE, 50, 1000, 120); break; case 2: break; case 3: GameUtils.drawWord(g, "積分:" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "難度:" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等級:" + fishLevel, Color.ORANGE, 50, 1000, 120); GameUtils.drawWord(g, "勝利", Color.RED, 80, 700, 500); break; default: break; } } }
對窗口類的 paint 方法進行優化
@Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 bg.paintSelf(gImage, myFish.level); //*********************** //游戲狀態:0未開始,1游戲中,2游戲失敗,3游戲勝利,4游戲暫停,5重新開始 switch (state) { case 0: break; case 1: myFish.paintSelf(gImage); logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } break; case 2: break; case 3: //玩家勝利 myFish.paintSelf(gImage); break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); }
首先實現右側敵方小魚的生成,在工具類中添加右側敵方小魚的圖
//敵方魚類 public static Image enamy_l_img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish2_r.gif"); public static Image enamy_r_img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish2_l.gif");
在敵方魚類中創建敵方小魚右類繼承敵方小魚左類
//右敵方魚類 class Enamy_1_R extends Enamy_1_L { Enamy_1_R() { this.x = 1400; dir = -1; this.img = GameUtils.enamy_r_img; } }
在窗口類中定義隨機數,使左右敵方小魚隨機出現
public class GameWin extends JFrame { //...... //定義一個隨機數,以此讓左右魚的數量隨機 double random; //...... random = Math.random(); //每重繪10次生成一條敵方魚類 if (time % 10 == 0) { if (random > 0.5) { enamy = new Enamy_1_L(); } else { enamy = new Enamy_1_R(); } GameUtils.EnamyList.add(enamy); } //...... }
接下來是其他敵方魚類的生成,其原理與敵方小魚的生成原理一致
在窗口類添加敵方魚圖
//敵方魚類 public static Image enamy_l_img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish2_r.gif"); public static Image enamy_r_img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish2_l.gif"); public static Image enamy_l_2img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish3_r.png"); public static Image enamy_r_2img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish3_l.png"); public static Image enamy_l_3img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish4_r.png"); public static Image enamy_r_3img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\fish4_l.png");
創建剩下的敵方魚類并寫入參數
class Enamy_2_L extends Enamy { Enamy_2_L() { this.x = -100; this.y = (int) (Math.random() * 700 + 100); this.width = 100; this.height = 100; this.speed = 5; this.count = 2; this.type = 2; this.img = GameUtils.enamy_l_2img; } } class Enamy_2_R extends Enamy_2_L { Enamy_2_R() { this.x = 1400; dir = -1; this.img = GameUtils.enamy_r_2img; } } class Enamy_3_L extends Enamy { Enamy_3_L() { this.x = -300; this.y = (int) (Math.random() * 700 + 100); this.width = 300; this.height = 150; this.speed = 15; this.count = 5; this.type = 3; this.img = GameUtils.enamy_l_3img; } //由于第3種魚的體積過大,我們需要將其修改一下 public Rectangle getRec() { return new Rectangle(x + 40, y + 30, width - 80, height - 60); } } class Enamy_3_R extends Enamy_3_L { Enamy_3_R() { this.x = 1400; dir = -1; this.img = GameUtils.enamy_r_3img; } }
在窗口類種添加敵方魚的生成,添加我方魚和敵方魚的等級比較來判斷游戲是否失敗,同時游戲失敗界面只剩下敵方魚類
public class GameWin extends JFrame { //...... @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 bg.paintSelf(gImage, myFish.level); //游戲狀態:0未開始,1游戲中,2游戲失敗,3游戲勝利,4游戲暫停,5重新開始 switch (state) { case 0: break; case 1: myFish.paintSelf(gImage); logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } break; case 2: //*********游戲失敗界面********* logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } break; case 3: //玩家勝利 myFish.paintSelf(gImage); break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } //批量添加魚類 void logic() { //...... random = Math.random(); //********根據游戲等級生成魚類******** switch (GameUtils.level) { case 4: case 3: case 2: if (time % 30 == 0) { if (random > 0.5) { enamy = new Enamy_3_L(); } else { enamy = new Enamy_3_R(); } GameUtils.EnamyList.add(enamy); } case 1: if (time % 20 == 0) { if (random > 0.5) { enamy = new Enamy_2_L(); } else { enamy = new Enamy_2_R(); } GameUtils.EnamyList.add(enamy); } case 0: //每重繪10次生成一條敵方魚類 if (time % 10 == 0) { if (random > 0.5) { enamy = new Enamy_1_L(); } else { enamy = new Enamy_1_R(); } GameUtils.EnamyList.add(enamy); } break; default: break; } //移動方向 for (Enamy enamy : GameUtils.EnamyList) { enamy.x = enamy.x + enamy.dir * enamy.speed; //我方魚與敵方魚的碰撞檢測 if (myFish.getRec().intersects(enamy.getRec())) { //********如果我方魚的等級大于等于敵方魚******* if (myFish.level >= enamy.type) { enamy.x = -200; enamy.y = -200; //得分 GameUtils.count += enamy.count; } else { state = 2; } } } } }
背景類優化:
public class Bg { void paintSelf(Graphics g, int fishLevel) { g.drawImage(GameUtils.bgimg, 0, 0, null); switch (GameWin.state) { case 0 -> GameUtils.drawWord(g, "請點擊開始游戲", Color.RED, 80, 500, 500); case 1 -> { GameUtils.drawWord(g, "積分:" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "難度:" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等級:" + fishLevel, Color.ORANGE, 50, 1000, 120); } case 2 -> { GameUtils.drawWord(g, "積分:" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "難度:" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等級:" + fishLevel, Color.ORANGE, 50, 1000, 120); GameUtils.drawWord(g, "失敗", Color.RED, 80, 600, 500); } case 3 -> { GameUtils.drawWord(g, "積分:" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "難度:" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等級:" + fishLevel, Color.ORANGE, 50, 1000, 120); GameUtils.drawWord(g, "勝利", Color.RED, 80, 700, 500); } default -> { } } } }
在工具類中添加敵方 boss 魚
public static Image boss_img = Toolkit.getDefaultToolkit().createImage("D:\\IDEA\\idea_Demo\\FishGame\\images\\enemyFish\\boss.gif");
創建敵方 boss 魚類繼承父類
class Enamy_Boss extends Enamy { Enamy_Boss() { this.x = -1000; this.y = (int) (Math.random()*700 + 100); this.width = 340; this.height = 340; this.speed = 100; this.count = 0; this.type = 10; this.img = GameUtils.boss_img; } }
在窗口類中獲取敵方 boss 魚類,在游戲等級為 4 的代碼塊中,添加 boss 生成的條件,同時對 boss 和我方魚類及其他魚類碰撞的情況做出處理
public class GameWin extends JFrame { //...... //敵方boss類 Enamy boss; //是否生成boss boolean isboss = false; //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { //...... } @Override public void paint(Graphics g) { //懶加載模式初始化對象 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); //獲取圖片對應的畫筆對象 bg.paintSelf(gImage, myFish.level); //游戲狀態:0未開始,1游戲中,2游戲失敗,3游戲勝利,4游戲暫停,5重新開始 switch (state) { case 0: break; case 1: myFish.paintSelf(gImage); logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } //********boss魚的生成******** if (isboss) { boss.x += boss.dir * boss.speed; boss.paintSelf(gImage); if (boss.x < 0) { gImage.setColor(Color.RED); gImage.fillRect(boss.x, boss.y, 2400, boss.height / 30); } } break; case 2: logic(); //不斷添加敵方魚類 for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } //********添加敵方boss******** if (isboss) { boss.paintSelf(gImage); } break; case 3: //玩家勝利 myFish.paintSelf(gImage); break; case 4: break; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } //批量添加魚類 void logic() { //關卡難度 if (GameUtils.count < 5) { GameUtils.level = 0; myFish.level = 1; } else if (GameUtils.count <= 15) { GameUtils.level = 1; } else if (GameUtils.count <= 50) { GameUtils.level = 2; myFish.level = 2; } else if (GameUtils.count <= 150) { GameUtils.level = 3; myFish.level = 3; } else if (GameUtils.count <= 300) { GameUtils.level = 4; myFish.level = 3; } else { //分數大于300,玩家勝利 state = 3; } random = Math.random(); switch (GameUtils.level) { case 4: //********判斷是否生成boss******** if (time % 60 == 0) { if (random > 0) { boss = new Enamy_Boss(); isboss = true; } } case 3: case 2: //...... case 1: //...... case 0: //...... default: break; } //移動方向 for (Enamy enamy : GameUtils.EnamyList) { enamy.x = enamy.x + enamy.dir * enamy.speed; //********boss魚的碰撞處理******** if (isboss) { if (boss.getRec().intersects(enamy.getRec())) { enamy.x = -200; enamy.y = -200; } if (boss.getRec().intersects(myFish.getRec())) { state = 2; } } //...... } } }
首先實現暫停功能,如果游戲狀態為 4,則游戲暫停,我們使用空格鍵來實現游戲暫停功能
在 launch 方法中添加鍵盤的監聽事件
public class GameWin extends JFrame { //...... //創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { //...... //鍵盤移動 this.addKeyListener(new KeyAdapter() { @Override//按壓 public void keyPressed(KeyEvent e) { //上下左右四個鍵的ASCII值為 上 ↑:38下 ↓: 40左 ←: 37右 →: 39 if (e.getKeyCode() == 38) { GameUtils.UP = true; } if (e.getKeyCode() == 40) { GameUtils.DOWN = true; } if (e.getKeyCode() == 37) { GameUtils.LEFT = true; } if (e.getKeyCode() == 39) { GameUtils.RIGHT = true; } //********空格鍵******** if (e.getKeyCode() == 32) { //如果游戲狀態為運行中,則暫停,反之 switch (state) { case 1: state = 4; GameUtils.drawWord(getGraphics(), "游戲暫停!!!", Color.RED, 50, 600, 400); break; case 4: state = 1; break; } } } @Override//抬起 public void keyReleased(KeyEvent e) { if (e.getKeyCode() == 38) { GameUtils.UP = false; } if (e.getKeyCode() == 40) { GameUtils.DOWN = false; } if (e.getKeyCode() == 37) { GameUtils.LEFT = false; } if (e.getKeyCode() == 39) { GameUtils.RIGHT = false; } } }); //背景圖片重復使用,需要重復調用repaint方法 while (true) { repaint(); time++; Thread.sleep(40); } } @Override public void paint(Graphics g) { //...... case 4: //******** return; default: break; } //將繪制好的圖片一次性繪制到主窗口中 g.drawImage(offScreenImage, 0, 0, null); } //批量添加魚類 ...... }
接下來是重新開始功能,在窗口類中創建一個新的方法,將游戲狀態恢復到初始,然后定義在游戲狀態為結束或勝利的情況下,點擊鼠標左鍵進入重新開始界面
//重新開始 void reGame() { GameUtils.EnamyList.clear(); time =0; myFish.level = 0; GameUtils.count = 0; myFish.x = 700; myFish.y = 500; myFish.width = 50; myFish.height = 50; boss = null; isboss = false; }
//創建一個啟動窗口,設置窗口信息 public void launch() throws InterruptedException { //...... //添加鼠標監聽事件 this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == 1 && state == 0) { state = 1; repaint(); } //重新開始 if (e.getButton() == 1 && (state == 2 || state == 3)) { reGame(); state = 1; } } }); //鍵盤移動 //...... }
到此,關于“Java怎么實現大魚吃小魚游戲”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。