Java贪吃蛇小游戏

Java贪吃蛇小游戏

在这里插入图片描述

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.LinkedList;
import java.util.Random;

public class SnakeGame extends JFrame implements ActionListener, KeyListener {
    private static final long serialVersionUID = 1L;

    // 游戏区域的格子数和每个格子的大小
    private static final int GRID_SIZE = 20;
    private static final int CELL_SIZE = 20;

    // 蛇的坐标集合,食物的坐标,蛇的移动方向,计时器
    private LinkedList<Point> snake;
    private Point food;
    private char direction;
    private Timer timer;

    // 游戏窗口的构造函数
    public SnakeGame() {
        setTitle("Snake Game");  // 设置窗口标题
        setSize(GRID_SIZE * CELL_SIZE, GRID_SIZE * CELL_SIZE);  // 设置窗口大小
        setResizable(false);  // 设置窗口不可调整大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 设置默认关闭操作
        setLocationRelativeTo(null);  // 设置窗口居中显示

        // 初始化蛇的起始位置,方向为向右
        snake = new LinkedList<>();
        snake.add(new Point(GRID_SIZE / 2, GRID_SIZE / 2));
        direction = 'R';

        // 生成初始食物
        spawnFood();

        // 设置计时器,用于触发蛇的移动
        timer = new Timer(100, this);
        timer.start();

        // 添加键盘事件监听器
        addKeyListener(this);
        setFocusable(true);
    }

    // 生成食物的方法
    public void spawnFood() {
        Random rand = new Random();
        int x = rand.nextInt(GRID_SIZE);
        int y = rand.nextInt(GRID_SIZE);

        food = new Point(x, y);

        // 确保食物不会生成在蛇的身体上
        while (snake.contains(food)) {
            x = rand.nextInt(GRID_SIZE);
            y = rand.nextInt(GRID_SIZE);
            food.setLocation(x, y);
        }
    }

    // 移动蛇的方法
    public void move() {
        Point head = snake.getFirst();
        Point newHead = new Point(head);

        switch (direction) {
            case 'U':
                newHead.translate(0, -1);
                break;
            case 'D':
                newHead.translate(0, 1);
                break;
            case 'L':
                newHead.translate(-1, 0);
                break;
            case 'R':
                newHead.translate(1, 0);
                break;
        }

        // 检查碰撞
        if (newHead.equals(food)) {
            snake.addFirst(food);
            spawnFood();
        } else {
            snake.addFirst(newHead);
            // 如果蛇没吃到食物,则移除尾部,否则保持尾部
            snake.removeLast();
        }

        // 检查蛇是否撞到自己
        if (snake.size() > 1 && snake.subList(1, snake.size()).contains(newHead)) {
            gameOver();
        }

        // 检查蛇是否撞到墙壁
        if (newHead.x < 0 || newHead.x >= GRID_SIZE || newHead.y < 0 || newHead.y >= GRID_SIZE) {
            gameOver();
        }
    }

    // 游戏结束的方法
    public void gameOver() {
        timer.stop();
        JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.INFORMATION_MESSAGE);
        System.exit(0);
    }

    // 画图的方法,用于绘制蛇、食物和网格
    public void paint(Graphics g) {
        super.paint(g);

        // 绘制蛇
        g.setColor(Color.GREEN);
        for (Point point : snake) {
            g.fillRect(point.x * CELL_SIZE, point.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
        }

        // 绘制食物
        g.setColor(Color.RED);
        g.fillRect(food.x * CELL_SIZE, food.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);

        // 绘制网格线
        g.setColor(Color.BLACK);
        for (int i = 0; i < GRID_SIZE; i++) {
            g.drawLine(i * CELL_SIZE, 0, i * CELL_SIZE, GRID_SIZE * CELL_SIZE);
            g.drawLine(0, i * CELL_SIZE, GRID_SIZE * CELL_SIZE, i * CELL_SIZE);
        }
    }

    // 主函数,创建SnakeGame对象并显示窗口
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SnakeGame game = new SnakeGame();
            game.setVisible(true);
        });
    }

    // 计时器触发的事件处理
    @Override
    public void actionPerformed(ActionEvent e) {
        move();
        repaint();
    }

    // 键盘按下事件处理
    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP:
                if (direction != 'D') direction = 'U';
                break;
            case KeyEvent.VK_DOWN:
                if (direction != 'U') direction = 'D';
                break;
            case KeyEvent.VK_LEFT:
                if (direction != 'R') direction = 'L';
                break;
            case KeyEvent.VK_RIGHT:
                if (direction != 'L') direction = 'R';
                break;
        }
    }

    // 未使用的键盘事件处理方法
    @Override
    public void keyTyped(KeyEvent e) {
    }

    // 未使用的键盘事件处理方法
    @Override
    public void keyReleased(KeyEvent e) {
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/169005.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【开源】基于Vue.js的计算机机房作业管理系统的设计和实现

项目编号&#xff1a; S 017 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S017&#xff0c;文末获取源码。} 项目编号&#xff1a;S017&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课…

前端本地存储数据库IndexedDB

前端本地存储数据库IndexedDB 1、前言2、什么是 indexedDB&#xff1f;3、什么是 localForage&#xff1f;4、localForage 的使用5、VUE 推荐使用 Pinia 管理 localForage 1、前言 前端本地化存储算是一个老生常谈的话题了&#xff0c;我们对于 cookies、Web Storage&#xff…

【C++ STL】string类-----迭代器(什么是迭代器?迭代器分哪几类?迭代器的接口如何使用?)

目录 一、前言 二、什么是迭代器 三、迭代器的分类与接口 &#x1f4a6;迭代器的分类 &#x1f4a6;迭代器的接口 &#x1f4a6;迭代器与接口之间的关联 四、string类中迭代器的应用 &#x1f4a6; 定义string类----迭代器 &#x1f4a6;string类中迭代器进行遍历 ✨be…

庖丁解牛:NIO核心概念与机制详解 06 _ 连网和异步 I/O

文章目录 Pre概述异步 I/OSelectors打开一个 ServerSocketChannel选择键内部循环监听新连接接受新的连接删除处理过的 SelectionKey传入的 I/O回到主循环 Pre 庖丁解牛&#xff1a;NIO核心概念与机制详解 01 庖丁解牛&#xff1a;NIO核心概念与机制详解 02 _ 缓冲区的细节实现…

C# 监测 Windows 设备变动事件

本程序通过WPF窗口的 WindowProc 函数处理Windows的硬件或配置改变的事件。开发环境为VS 2022。 基础信息 硬件或配置改变的基础有以下内容&#xff1a; 消息: WM_DEVICECHANGE 要实现的WindowProc 函数参数&#xff1a; protected IntPtr WndProc(IntPtr hwnd, int msg, In…

React 中 react-i18next 切换语言( 项目国际化 )

背景 平时中会遇到需求&#xff0c;就是切换语言&#xff0c;语种等。其实总的来说都是用i18n来实现的 思路 首先在项目中安装i18n插件&#xff0c;然后将插件引入到项目&#xff0c;然后配置语言包&#xff08;语言包需要你自己来进行配置&#xff0c;自己编写语言包&#xff…

C++初阶 | [四] 类和对象(下)

摘要&#xff1a;初始化列表&#xff0c;explicit关键字&#xff0c;匿名对象&#xff0c;static成员&#xff0c;友元&#xff0c;内部类&#xff0c;编译器优化 类是对某一类实体(对象)来进行描述的&#xff0c;描述该对象具有哪些属性、哪些方法&#xff0c;描述完成后就形成…

【zabbix监控三】zabbix之部署代理服务器

一、部署代理服务器 分布式监控的作用&#xff1a; 分担server的几种压力解决多机房之间的网络延时问题 1、搭建proxy主机 1.1 关闭防火墙&#xff0c;修改主机名 systemctl disbale --now firewalld setenforce 0 hostnamectl set-hostname zbx-proxy su1.2 设置zabbix下…

【C++ Primer Plus学习记录】for循环

很多情况下都需要程序执行重复的任务&#xff0c;C中的for循环可以轻松地完成这种任务。 我们来从程序清单5.1了解for循环所做的工作&#xff0c;然后讨论它是如何工作的。 //forloop.cpp #if 1 #include<iostream> using namespace std;int main() {int i;for (i 0; …

百云齐鲁 | 云轴科技ZStack成功实践精选(山东)

山东省作为我国重要的工业基地和北方地区经济发展的战略支点&#xff0c;在“十四五”规划中将数字强省建设分为数字基础设施、数字科技、数字经济、数字政府、数字社会、数字生态六大部分&#xff0c;涵盖政治、经济、民生等多个方面&#xff0c;并将大数据、云计算、人工智能…

数电实验-----实现74LS153芯片扩展为8选1数据选择器以及应用(Quartus II )

目录 一、74LS153芯片介绍 管脚图 功能表 二、4选1选择器扩展为8选1选择器 1.扩展原理 2.电路图连接&#xff08;Quartus II &#xff09; 3.仿真结果 三、8选1选择器的应用 1.三变量表决器 2.奇偶校验电路 一、74LS153芯片介绍 74ls153芯片是属于四选一选择器的芯片。…

Nginx-负载均衡-动静分离-虚拟主机

负载均衡 负载均衡基本使用 1 配置上游服务器 upstream myserver { #是server外层server ip1:8080;server ip1:8080; }2 配置代理 server {location / { proxy_pass http://myserver;#请求转向myserver 定义的服务器列表 注意这个http不能丢 pro…

VulnHub DC-7

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

【数据结构与算法】Kadane‘s算法(动态规划、最大子数组和)

文章目录 一、算法原理二、例题2.1 最大子数组和2.2 环形子数组的最大和 一、算法原理 Kadanes算法是一种用于解决最大子数组和问题的动态规划算法。这类问题的目标是在给定整数数组中找到一个连续的子数组&#xff0c;使其元素之和最大&#xff08;数组含有负数&#xff09;。…

MySQL为什么选择了B+树

首先MySQL的数据**&#xff08;索引记录&#xff09;**是存在磁盘里的&#xff0c;磁盘读取非常慢&#xff0c;所以要尽可能减少磁盘操作&#xff0c;因此我们需要更好的利用索引。 首先索引按顺序排列了数据&#xff0c;那么很显然最好的查找方式是二分查找&#xff0c;数组自…

【Spring Boot】使用WebSocket协议完成来单提醒及客户催单功能

1 WebSocket介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信(双向传输)——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c; 并进行双向数据传输。 1.1 HTTP协议和WebSocket协议对比 1、HTTP是短…

【10套模拟】【7】

关键字&#xff1a; 二叉排序树插入一定是叶子、单链表简单选择排序、子串匹配、层次遍历

【Python】问题描述:输入A、B,输出A+B。样例输入12 45样例输出57

1、问题描述 输入A、B&#xff0c;输出AB。 样例输入 12 45 样例输出 57 nums list(map(int,input().split(" "))) print(sum(nums))

Java 算法篇-链表的经典算法:判断回文链表、判断环链表与寻找环入口节点(“龟兔赛跑“算法实现)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 链表的创建 2.0 判断回文链表说明 2.1 快慢指针方法 2.2 使用递归方式实现反转链表方法 2.3 实现判断回文链表 - 使用快慢指针与反转链表方法 3.0 判断环链表说明…

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于人工水母优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…