溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java實現貪吃蛇大作戰小游戲的代碼怎么寫

發布時間:2022-07-22 09:53:59 來源:億速云 閱讀:145 作者:iii 欄目:開發技術

Java實現貪吃蛇大作戰小游戲的代碼怎么寫

貪吃蛇大作戰是一款經典的休閑游戲,玩家通過控制蛇的移動來吃掉食物,蛇的身體會隨著吃食物而變長,同時需要避免撞到墻壁或自己的身體。本文將詳細介紹如何使用Java語言實現一個簡單的貪吃蛇大作戰小游戲。

1. 項目結構

在開始編寫代碼之前,我們需要先規劃好項目的結構。一個典型的貪吃蛇游戲項目可以分為以下幾個部分:

  • 游戲主類:負責游戲的啟動、主循環和渲染。
  • 蛇類:負責蛇的移動、生長和碰撞檢測。
  • 食物類:負責食物的生成和位置管理。
  • 游戲面板類:負責繪制游戲界面和更新游戲狀態。

2. 創建游戲主類

首先,我們創建一個名為SnakeGame的類,作為游戲的主類。這個類將負責初始化游戲、啟動游戲循環以及處理用戶輸入。

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;

public class SnakeGame extends JFrame implements ActionListener, KeyListener {
    private static final int WIDTH = 600;
    private static final int HEIGHT = 600;
    private static final int UNIT_SIZE = 20;
    private static final int GAME_UNITS = (WIDTH * HEIGHT) / (UNIT_SIZE * UNIT_SIZE);
    private static final int DELAY = 75;

    private final int[] x = new int[GAME_UNITS];
    private final int[] y = new int[GAME_UNITS];
    private int bodyParts = 6;
    private int applesEaten;
    private int appleX;
    private int appleY;
    private char direction = 'R';
    private boolean running = false;
    private Timer timer;

    public SnakeGame() {
        this.setTitle("Snake Game");
        this.setSize(WIDTH, HEIGHT);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.addKeyListener(this);
        this.setBackground(Color.BLACK);
        startGame();
    }

    public void startGame() {
        newApple();
        running = true;
        timer = new Timer(DELAY, this);
        timer.start();
    }

    public void paint(Graphics g) {
        if (running) {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, WIDTH, HEIGHT);

            g.setColor(Color.RED);
            g.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE);

            for (int i = 0; i < bodyParts; i++) {
                if (i == 0) {
                    g.setColor(Color.GREEN);
                } else {
                    g.setColor(new Color(45, 180, 0));
                }
                g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
            }

            g.setColor(Color.WHITE);
            g.setFont(new Font("Ink Free", Font.BOLD, 40));
            FontMetrics metrics = getFontMetrics(g.getFont());
            g.drawString("Score: " + applesEaten, (WIDTH - metrics.stringWidth("Score: " + applesEaten)) / 2, g.getFont().getSize());
        } else {
            gameOver(g);
        }
    }

    public void newApple() {
        appleX = (int) (Math.random() * (WIDTH / UNIT_SIZE)) * UNIT_SIZE;
        appleY = (int) (Math.random() * (HEIGHT / UNIT_SIZE)) * UNIT_SIZE;
    }

    public void move() {
        for (int i = bodyParts; i > 0; i--) {
            x[i] = x[i - 1];
            y[i] = y[i - 1];
        }

        switch (direction) {
            case 'U':
                y[0] = y[0] - UNIT_SIZE;
                break;
            case 'D':
                y[0] = y[0] + UNIT_SIZE;
                break;
            case 'L':
                x[0] = x[0] - UNIT_SIZE;
                break;
            case 'R':
                x[0] = x[0] + UNIT_SIZE;
                break;
        }
    }

    public void checkApple() {
        if ((x[0] == appleX) && (y[0] == appleY)) {
            bodyParts++;
            applesEaten++;
            newApple();
        }
    }

    public void checkCollisions() {
        // Check if head collides with body
        for (int i = bodyParts; i > 0; i--) {
            if ((x[0] == x[i]) && (y[0] == y[i])) {
                running = false;
            }
        }

        // Check if head touches left border
        if (x[0] < 0) {
            running = false;
        }

        // Check if head touches right border
        if (x[0] > WIDTH) {
            running = false;
        }

        // Check if head touches top border
        if (y[0] < 0) {
            running = false;
        }

        // Check if head touches bottom border
        if (y[0] > HEIGHT) {
            running = false;
        }

        if (!running) {
            timer.stop();
        }
    }

    public void gameOver(Graphics g) {
        g.setColor(Color.RED);
        g.setFont(new Font("Ink Free", Font.BOLD, 75));
        FontMetrics metrics = getFontMetrics(g.getFont());
        g.drawString("Game Over", (WIDTH - metrics.stringWidth("Game Over")) / 2, HEIGHT / 2);

        g.setColor(Color.WHITE);
        g.setFont(new Font("Ink Free", Font.BOLD, 40));
        g.drawString("Score: " + applesEaten, (WIDTH - metrics.stringWidth("Score: " + applesEaten)) / 2, g.getFont().getSize());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (running) {
            move();
            checkApple();
            checkCollisions();
        }
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                if (direction != 'R') {
                    direction = 'L';
                }
                break;
            case KeyEvent.VK_RIGHT:
                if (direction != 'L') {
                    direction = 'R';
                }
                break;
            case KeyEvent.VK_UP:
                if (direction != 'D') {
                    direction = 'U';
                }
                break;
            case KeyEvent.VK_DOWN:
                if (direction != 'U') {
                    direction = 'D';
                }
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    public static void main(String[] args) {
        new SnakeGame();
    }
}

3. 蛇類的實現

SnakeGame類中,我們已經定義了蛇的移動、碰撞檢測等邏輯。接下來,我們將這些邏輯進一步封裝到一個獨立的Snake類中。

public class Snake {
    private final int[] x;
    private final int[] y;
    private int bodyParts;
    private char direction;

    public Snake(int maxBodyParts) {
        x = new int[maxBodyParts];
        y = new int[maxBodyParts];
        bodyParts = 6;
        direction = 'R';
    }

    public void move() {
        for (int i = bodyParts; i > 0; i--) {
            x[i] = x[i - 1];
            y[i] = y[i - 1];
        }

        switch (direction) {
            case 'U':
                y[0] = y[0] - SnakeGame.UNIT_SIZE;
                break;
            case 'D':
                y[0] = y[0] + SnakeGame.UNIT_SIZE;
                break;
            case 'L':
                x[0] = x[0] - SnakeGame.UNIT_SIZE;
                break;
            case 'R':
                x[0] = x[0] + SnakeGame.UNIT_SIZE;
                break;
        }
    }

    public void grow() {
        bodyParts++;
    }

    public boolean checkCollision() {
        // Check if head collides with body
        for (int i = bodyParts; i > 0; i--) {
            if ((x[0] == x[i]) && (y[0] == y[i])) {
                return true;
            }
        }

        // Check if head touches borders
        return x[0] < 0 || x[0] >= SnakeGame.WIDTH || y[0] < 0 || y[0] >= SnakeGame.HEIGHT;
    }

    public int getBodyParts() {
        return bodyParts;
    }

    public int[] getX() {
        return x;
    }

    public int[] getY() {
        return y;
    }

    public void setDirection(char direction) {
        this.direction = direction;
    }
}

4. 食物類的實現

接下來,我們創建一個Food類,用于管理食物的生成和位置。

import java.util.Random;

public class Food {
    private int x;
    private int y;

    public Food() {
        spawn();
    }

    public void spawn() {
        Random random = new Random();
        x = random.nextInt(SnakeGame.WIDTH / SnakeGame.UNIT_SIZE) * SnakeGame.UNIT_SIZE;
        y = random.nextInt(SnakeGame.HEIGHT / SnakeGame.UNIT_SIZE) * SnakeGame.UNIT_SIZE;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

5. 游戲面板類的實現

最后,我們創建一個GamePanel類,用于繪制游戲界面和更新游戲狀態。

import javax.swing.*;
import java.awt.*;

public class GamePanel extends JPanel {
    private final Snake snake;
    private final Food food;
    private int score;

    public GamePanel(Snake snake, Food food) {
        this.snake = snake;
        this.food = food;
        this.score = 0;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        draw(g);
    }

    public void draw(Graphics g) {
        // Draw food
        g.setColor(Color.RED);
        g.fillOval(food.getX(), food.getY(), SnakeGame.UNIT_SIZE, SnakeGame.UNIT_SIZE);

        // Draw snake
        for (int i = 0; i < snake.getBodyParts(); i++) {
            if (i == 0) {
                g.setColor(Color.GREEN);
            } else {
                g.setColor(new Color(45, 180, 0));
            }
            g.fillRect(snake.getX()[i], snake.getY()[i], SnakeGame.UNIT_SIZE, SnakeGame.UNIT_SIZE);
        }

        // Draw score
        g.setColor(Color.WHITE);
        g.setFont(new Font("Ink Free", Font.BOLD, 40));
        FontMetrics metrics = getFontMetrics(g.getFont());
        g.drawString("Score: " + score, (SnakeGame.WIDTH - metrics.stringWidth("Score: " + score)) / 2, g.getFont().getSize());
    }

    public void update() {
        snake.move();
        if (snake.getX()[0] == food.getX() && snake.getY()[0] == food.getY()) {
            snake.grow();
            food.spawn();
            score++;
        }
        if (snake.checkCollision()) {
            // Game over logic
        }
    }
}

6. 整合游戲邏輯

最后,我們將所有類整合到SnakeGame類中,并啟動游戲。

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class SnakeGame extends JFrame implements ActionListener, KeyListener {
    private static final int WIDTH = 600;
    private static final int HEIGHT = 600;
    private static final int UNIT_SIZE = 20;
    private static final int DELAY = 75;

    private final Snake snake;
    private final Food food;
    private final GamePanel gamePanel;
    private Timer timer;

    public SnakeGame() {
        this.setTitle("Snake Game");
        this.setSize(WIDTH, HEIGHT);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.addKeyListener(this);
        this.setBackground(Color.BLACK);

        snake = new Snake((WIDTH * HEIGHT) / (UNIT_SIZE * UNIT_SIZE));
        food = new Food();
        gamePanel = new GamePanel(snake, food);
        this.add(gamePanel);

        startGame();
    }

    public void startGame() {
        timer = new Timer(DELAY, this);
        timer.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        gamePanel.update();
        gamePanel.repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_LEFT:
                if (snake.getDirection() != 'R') {
                    snake.setDirection('L');
                }
                break;
            case KeyEvent.VK_RIGHT:
                if (snake.getDirection() != 'L') {
                    snake.setDirection('R');
                }
                break;
            case KeyEvent.VK_UP:
                if (snake.getDirection() != 'D') {
                    snake.setDirection('U');
                }
                break;
            case KeyEvent.VK_DOWN:
                if (snake.getDirection() != 'U') {
                    snake.setDirection('D');
                }
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    public static void main(String[] args) {
        new SnakeGame();
    }
}

7. 總結

通過以上步驟,我們成功實現了一個簡單的貪吃蛇大作戰小游戲。這個游戲雖然功能簡單,但涵蓋了游戲開發中的許多基本概念,如游戲循環、碰撞檢測、用戶輸入處理等。希望本文能幫助你理解如何使用Java編寫一個簡單的游戲,并為你的游戲開發之路打下堅實的基礎。


注意:本文提供的代碼是一個基礎版本的貪吃蛇游戲,實際開發中可以根據需求進行擴展和優化,例如增加難度級別、多人模式、音效等。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女