Java实现贪吃蛇大作战小游戏的代码怎么写

发布时间:2022-07-22 09:53:59 作者:iii
来源:亿速云 阅读:142

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编写一个简单的游戏,并为你的游戏开发之路打下坚实的基础。


注意:本文提供的代码是一个基础版本的贪吃蛇游戏,实际开发中可以根据需求进行扩展和优化,例如增加难度级别、多人模式、音效等。

推荐阅读:
  1. java实现贪吃蛇游戏代码示例
  2. 利用java实现贪吃蛇小游戏的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:springboot项目中jacoco服务端怎么部署使用

下一篇:微信小程序视图容器和基本内容组件实例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》