Java Swing 實現300行捕魚達人遊戲
阿新 • • 發佈:2020-11-23
package org.wf.game.fish; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO;import javax.swing.JFrame; import javax.swing.JPanel; public class FishGame { public static void main(String[] args) { //遊戲畫框 JFrame jf = new JFrame("瘋狂捕魚"); jf.setSize(800, 480); jf.setLocationRelativeTo(null); jf.setResizable(false); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setAlwaysOnTop(true); //載入魚池 Pool pool = new Pool(); jf.add(pool); //顯示框架 jf.setVisible(true); pool.action(); } } //魚池類 class Pool extends JPanel { private static final long serialVersionUID = 1L; BufferedImage bgImage; //背景圖片 Fish[] fishs = new Fish[20]; //所有的魚 Net net = new Net(); //漁網 boolean isExit; //滑鼠是否在遊戲介面 int score, bullet = 50; //遊戲得分,子彈數 public Pool() { super(); File bg = new File("images/bg.jpg"); try { bgImage = ImageIO.read(bg); } catch (IOException e) { e.printStackTrace(); } //0-8,9-17對應1-9號魚 for (int i = 0; i < fishs.length / 2 - 1; i++) { fishs[i] = new Fish(i + 1); fishs[i + 9] = new Fish(i + 1); } fishs[18] = new Fish(10); fishs[19] = new Fish(11); } //畫遊戲元素 @Override public void paint(Graphics g) { g.drawImage(bgImage, 0, 0, null); //畫背景 for (Fish fish : fishs) { g.drawImage(fish.fishImage, fish.fish_x, fish.fish_y, null); //畫魚 } if (!isExit) { g.drawImage(net.netImage, net.netX, net.netY, null); //畫網 } //畫遊戲說明文字 g.setColor(Color.GREEN); g.setFont(new Font("楷體", Font.ITALIC, 20)); g.drawString("瘋狂捕魚V1.0 By~Synchronized", 10, 25); g.drawString("子彈數:" + bullet + " 得分:" + score, 350, 25); g.drawString("右鍵切換漁網 VIP:" + (net.power % 7 + 1), 590, 25); if (bullet <= 0) { g.setColor(Color.RED); g.setFont(new Font("楷體", Font.BOLD, 100)); g.drawString("Game Over", 150, 250); bullet = 0; isExit = true; net.power = -1; } } //遊戲啟動方法 public void action() { for (Fish fish : fishs) { fish.start(); } //滑鼠監聽器 MouseAdapter adapter = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int event = e.getModifiers(); if (event == 4) { net.change(); //切換網大小 super.mousePressed(e); } else if (event == 16) { //減子彈 if (bullet - (net.power % 7 + 1) <= 0) { bullet = 0; } else { bullet -= (net.power % 7 + 1); } //捕魚 for (Fish fish : fishs) { if (!fish.catched) { catchFish(fish); } } } } @Override public void mouseMoved(MouseEvent e) { net.moveTo(e.getX(), e.getY()); super.mouseMoved(e); } @Override public void mouseEntered(MouseEvent e) { isExit = false; super.mouseEntered(e); } @Override public void mouseExited(MouseEvent e) { isExit = true; super.mouseExited(e); } }; this.addMouseListener(adapter); this.addMouseMotionListener(adapter); while (true) { repaint(); } } //封裝捕魚的方法 public void catchFish(Fish fish) { fish.catched = net.catchFish(fish); if (fish.catched) { score += 2 * fish.k; bullet += 2 * fish.k; } } } //魚類 class Fish extends Thread { int fish_x, fish_y; //魚的座標 BufferedImage fishImage; //魚的圖片 BufferedImage[] fishImages = new BufferedImage[10]; //魚動作的圖片 BufferedImage[] catchImages; //魚的被捕的圖片 int fish_width, fish_height; //魚的寬高 Random r = new Random(); //魚y座標的隨機數 int blood; //魚的血量值 boolean catched; //魚是否被捕 int k, step_size; //魚的血量等級,移動速度 public Fish(int m) { super(); String preName = m > 9 ? m + "" : "0" + m; //通過for迴圈讀取魚動作圖片陣列 for (int i = 0; i < fishImages.length; i++) { int j = i + 1; String lastName = j > 9 ? "10" : "0" + j; File file = new File("images/fish" + preName + "_" + lastName + ".png"); try { fishImages[i] = ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); } } fishImage = fishImages[0]; fish_width = this.fishImage.getWidth(); fish_height = this.fishImage.getHeight(); fish_x = 800; fish_y = r.nextInt(450 - fish_height); blood = m * 3; this.k = m; step_size = r.nextInt(5) + 1; //初始化catchImages if (m > 7) { catchImages = new BufferedImage[4]; } else if (m <= 7) { catchImages = new BufferedImage[2]; } //通過for迴圈讀取魚被捕圖片陣列 for (int i = 1; i <= catchImages.length; i++) { File file = new File("images/fish" + preName + "_catch_0" + i + ".png"); try { catchImages[i - 1] = ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); } } } //魚移動的方法 public void move() { fish_x -= step_size; } @Override public void run() { super.run(); while (true) { move(); //呼叫魚移動的方法 //如果魚出界,重新生成 if (fish_x < -fish_width || catched) { turnOut(); //魚被捕,顫動 newFish(); } change(); //呼叫魚搖擺遊動的方法 try { Thread.sleep(15); } catch (InterruptedException e) { e.printStackTrace(); } } } //重新生成一條魚 public void newFish() { fish_x = 800; fish_y = r.nextInt(450 - fish_height); if (fish_y >= 450) { // System.out.println(fish_height + " " + fish_y); } catched = false; blood = k * 3; step_size = r.nextInt(5) + 1; } // 魚搖擺遊動的方法 int index = 0; public void change() { index++; fishImage = fishImages[index / 3 % 10]; } //魚被捕動畫的方法 public void turnOut() { for (int i = 0; i < catchImages.length; i++) { fishImage = catchImages[i]; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } } //漁網類 class Net { int netX, netY;//網的座標 int netWidth, netHeight;//網的寬高 BufferedImage netImage;//網的圖片 public Net() { super(); File file = new File("images/net_" + 1 + ".png"); try { netImage = ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); } netX = 300; netY = 300; netWidth = netImage.getWidth(); netHeight = netImage.getHeight(); } // 魚網切換的方法 int power = 0; public void change() { power++; int x = this.netX + this.netWidth / 2; int y = this.netY + this.netHeight / 2; File file = new File("images/net_" + (power % 7 + 1) + ".png"); try { netImage = ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); } this.netWidth = netImage.getWidth(); this.netHeight = netImage.getHeight(); moveTo(x, y); } //漁網移動的方法 public void moveTo(int x, int y) { this.netX = x - this.netWidth / 2; this.netY = y - this.netHeight / 2; } //捕魚 public boolean catchFish(Fish fish) { //網的中心座標 int zX = netX + netWidth / 2; int zY = netY + netHeight / 2; //魚的身體部分中心座標 int fX = fish.fish_x + fish.fish_width * 2 / 3; int fY = fish.fish_y + fish.fish_height / 2; //如果網的中心座標在魚的身體部分 if (zX > fish.fish_x && zX < fish.fish_x + fish.fish_width * 2 / 3 && zY > fish.fish_y && zY < fish.fish_y + fish.fish_height) { fish.blood -= ((power % 7 + 1) * 2); // System.out.println(fish.blood); } else if (fX > netX && fX < netX + netWidth && fY > netY && fY < netY + netHeight) { //如果魚的身體部分中心座標在網裡 fish.blood -= ((power % 7 + 1) * 2); // System.out.println(fish.blood); } return fish.blood <= 0; } }