一個Java開發的貪喫蛇小遊戲
一、遊戲操作說明
上下左右控制貪喫蛇走位,空格鍵暫停或者開始遊戲 藍色食物得10分,黃色食物得20分,紅色食物得30分。小蛇的移動速度會隨着長度的增加而變快,最快是初始速度的兩倍,這裏可以在代碼中自定義設置。目前還有一個bug尚未解決,就是小蛇可以回頭走,理論是應該往一個方向可以掉頭但是不可以直接往相反的方向走,這樣默認就是咬到自己遊戲結束,以後會修復這個問題
二、程序代碼
1、StartGame.java(主函數類)
用於設置窗口的一些參數
package com.java.snake;
import javax.swing.*;
public class StartGame {
public static void main(String[] args) {
// 1.繪製一個靜態窗口並設置窗口標題
JFrame jFrame = new JFrame("貪喫蛇小遊戲");
jFrame.setBounds(10, 10, 900, 720); // 設置起始座標和窗口大小
jFrame.setResizable(false); // 設置不可以調整窗口大小
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 設置可以關閉窗口
// 2.繪製面板
jFrame.add(new GamePanel());
jFrame.setVisible(true); // 讓窗口可以展現出來
}
}
2、GamePanel.java
這個類是程序的主要代碼,包括畫圖和設置幀數還有鍵盤的監聽
package com.java.snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
public class GamePanel extends JPanel implements KeyListener, ActionListener {
int length; // 蛇的長度
String fx; // 方向 R:右 L:左 U:上 D:下
int[] snakeX = new int[600]; // 蛇的X軸座標
int[] snakeY = new int[500]; // 蛇的Y軸座標
boolean isStart; // 遊戲是否開始的表示,默認未開始
boolean isFail; // 是否失敗標識
int score; // 分數
int num; // 食物顏色編號
int foodX;
int foodY;
Random random = new Random();
int seconds = 100;
Timer timer = new Timer(seconds, this); // 設置一個定時器
// 構造器
public GamePanel() {
init();
// 獲取鍵盤監聽時間
this.setFocusable(true);
this.addKeyListener(this);
timer.start(); // 讓時間動起來
}
public void init() {
length = 3; // 初始化蛇長度爲3
fx = "R"; // 初始化蛇頭方向是往右
// 頭部座標
snakeX[0] = 100;
snakeY[0] = 100;
snakeX[1] = 75;
snakeY[1] = 100;
snakeX[2] = 50;
snakeY[2] = 100;
isStart = false;
isFail = false;
// 隨機初始化食物
foodX = 25 + 25 * random.nextInt(34);
foodY = 75 + 25 * random.nextInt(24);
score = 0; // 默認分數爲0
seconds = 100;
}
// 面板:畫界面 畫蛇
// Graphics:畫筆
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.white); // 設置背景顏色
Data.header.paintIcon(this, g, 25, 11); // 繪製遊戲頭部圖片
g.fillRect(25, 75, 850, 600); // 繪製遊戲區域
// 畫一條靜態的小蛇
if ("R".equals(fx))
Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
if ("L".equals(fx))
Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
if ("U".equals(fx))
Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
if ("D".equals(fx))
Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
// 蛇的長度用length進行控制
for (int i = 1; i < length; i++) {
Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
}
if (num == 0)
Data.foodBlue.paintIcon(this, g, foodX, foodY);
if (num == 1)
Data.foodYellow.paintIcon(this, g, foodX, foodY);
if (num == 2)
Data.foodRed.paintIcon(this, g, foodX, foodY);
// 遊戲未開始時話一個字符串
if (!isStart) {
g.setColor(Color.white); // 設置畫筆顏色
g.setFont(new Font("微軟雅黑", Font.BOLD, 40)); // 設置字體
g.drawString("按下空格開始遊戲", 300, 300);
}
// 遊戲未開始時話一個字符串
if (!isStart) {
g.setColor(Color.white); // 設置畫筆顏色
g.setFont(new Font("微軟雅黑", Font.BOLD, 40)); // 設置字體
g.drawString("按下空格開始遊戲", 300, 300);
}
// 遊戲失敗時話一個字符串
if (isFail) {
g.setColor(Color.red); // 設置畫筆顏色
g.setFont(new Font("微軟雅黑", Font.BOLD, 40)); // 設置字體
g.drawString("遊戲結束,按下空格重新開始遊戲", 150, 300);
}
g.setColor(Color.white);
g.setFont(new Font("微軟雅黑", Font.BOLD, 18));
g.drawString("長度:" + length, 750, 35);
g.drawString("分數:" + score, 750, 55);
}
// 定時器,監聽時間,幀:執行定時操作
@Override
public void actionPerformed(ActionEvent e) {
// 如果遊戲處於開始狀態並且遊戲沒有結束
if (isStart && !isFail) {
// 右移動
for (int i = length - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
// 通過控制方向讓小蛇移動
if ("U".equals(fx)) {
// 頭部移動
snakeY[0] -= 25;
// 邊界判斷
if (snakeY[0] < 75) {
snakeY[0] = 650;
}
} else if ("D".equals(fx)) {
// 頭部移動
snakeY[0] += 25;
// 邊界判斷
if (snakeY[0] > 650) {
snakeY[0] = 75;
}
} else if ("R".equals(fx)) {
// 頭部移動
snakeX[0] += 25;
// 邊界判斷
if (snakeX[0] > 850) {
snakeX[0] = 25;
}
} else if ("L".equals(fx)) {
// 頭部移動
snakeX[0] -= 25;
// 邊界判斷
if (snakeX[0] < 25) {
snakeX[0] = 850;
}
}
if (snakeX[0] == foodX && snakeY[0] == foodY) {
// 長度加一
length++;
// 增加分數
if (num == 0)
score += 10;
if (num == 1)
score += 20;
if (num == 2)
score += 30;
// 幀數加時
if (seconds > 50) {
timer.setDelay(seconds -= 1);
}
// 重新隨機生成一個顏色食物
foodX = 25 + 25 * random.nextInt(34);
foodY = 75 + 25 * random.nextInt(24);
num = random.nextInt(3);
}
// 失敗判定
for (int i = 1; i < length; i++) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
isFail = true;
break;
}
}
// 刷新界面
repaint();
}
//
timer.start(); // 讓時間動起來
}
@Override
public void keyPressed(KeyEvent e) {
// 鍵盤按下未釋放
int keyCode = e.getKeyCode();
// 如果按下的是空格
if (keyCode == KeyEvent.VK_SPACE) {
if (isFail) {
// 重新開始遊戲
init();
isStart = true;
} else {
// 遊戲開始或者暫停
isStart = !isStart;
}
// 刷新界面
repaint();
}
if (keyCode == KeyEvent.VK_UP) {
fx = "U";
} else if (keyCode == KeyEvent.VK_DOWN) {
fx = "D";
} else if (keyCode == KeyEvent.VK_RIGHT) {
fx = "R";
} else if (keyCode == KeyEvent.VK_LEFT) {
fx = "L";
}
}
@Override
public void keyReleased(KeyEvent e) {
// 鍵盤釋放
}
@Override
public void keyTyped(KeyEvent e) {
// 鍵盤按下並釋放 敲擊
}
}
3、Data.java
這個類寫的是一些數據。導入一些外部的圖片素材,在GamePanel.java中畫到面板上
package com.java.snake;
import javax.swing.*;
import java.net.URL;
// 存放外部數據
public class Data {
// 遊戲頭部的圖片
public static URL headerUrl = Data.class.getResource("/static/header.png");
public static ImageIcon header = new ImageIcon(headerUrl);
// 導入一些圖片素材
public static URL upUrl = Data.class.getResource("/static/up.png");
public static URL downUrl = Data.class.getResource("/static/down.png");
public static URL leftUrl = Data.class.getResource("/static/left.png");
public static URL rightUrl = Data.class.getResource("/static/right.png");
public static URL bodyUrl = Data.class.getResource("/static/body.png");
public static ImageIcon up = new ImageIcon(upUrl); // 上
public static ImageIcon down = new ImageIcon(downUrl); // 下
public static ImageIcon left = new ImageIcon(leftUrl); // 左
public static ImageIcon right = new ImageIcon(rightUrl); // 右
public static ImageIcon body = new ImageIcon(bodyUrl); // 身體
// 食物
public static URL foodBlueUrl = Data.class.getResource("/static/food_blue.png");
public static URL foodYellowUrl = Data.class.getResource("/static/food_yellow.png");
public static URL foodRedUrl = Data.class.getResource("/static/food_red.png");
public static ImageIcon foodBlue = new ImageIcon(foodBlueUrl); // 藍色食物,加一個長度
public static ImageIcon foodYellow = new ImageIcon(foodYellowUrl); // 黃色食物,加兩個長度
public static ImageIcon foodRed = new ImageIcon(foodRedUrl); // 紅色食物,加三個長度
}