package com.mihuo.test.game;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
* 贪吃蛇游戏
* @author CSDN 大家都说我身材好
* @email mihuo12358@hotmail.com
*
*/
public class SnakeGame extends JPanel implements ActionListener {
private final int TILE_SIZE = 24; // 每个格子的大小
private final int GRID_WIDTH = 20; // 游戏区域的宽度(格子数)
private final int GRID_HEIGHT = 20; // 游戏区域的高度(格子数)
private final LinkedList<Point> snake = new LinkedList<Point>(); // 蛇的身体,由点组成
private Point food; // 食物的位置
private boolean running = false; // 游戏是否正在运行
private int direction = KeyEvent.VK_RIGHT; // 蛇的当前移动方向
private int score = 0; // 玩家的得分
public SnakeGame() {
setPreferredSize(new Dimension(GRID_WIDTH * TILE_SIZE, GRID_HEIGHT * TILE_SIZE)); // 设置游戏窗口的大小
setBackground(Color.BLACK); // 设置游戏窗口的背景色
setFocusable(true); // 使游戏窗口能够获得焦点,以便接收键盘事件
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) { // 处理键盘按下事件
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (direction != KeyEvent.VK_RIGHT)) {
direction = KeyEvent.VK_LEFT; // 改变蛇的移动方向向左
}
if ((key == KeyEvent.VK_RIGHT) && (direction != KeyEvent.VK_LEFT)) {
direction = KeyEvent.VK_RIGHT; // 改变蛇的移动方向向右
}
if ((key == KeyEvent.VK_UP) && (direction != KeyEvent.VK_DOWN)) {
direction = KeyEvent.VK_UP; // 改变蛇的移动方向向上
}
if ((key == KeyEvent.VK_DOWN) && (direction != KeyEvent.VK_UP)) {
direction = KeyEvent.VK_DOWN; // 改变蛇的移动方向向下
}
}
});
initGame(); // 初始化游戏
}
private void initGame() {
snake.clear(); // 清空蛇的身体
snake.add(new Point(5, 5)); // 在游戏区域中央初始化蛇的位置
spawnFood(); // 生成食物
running = true; // 游戏开始运行
Timer timer = new Timer(150, this); // 创建一个计时器,每150毫秒触发一次动作事件
timer.start(); // 启动计时器
}
private void spawnFood() {
Random rand = new Random(); // 创建一个随机数生成器
int x, y;
do {
x = rand.nextInt(GRID_WIDTH); // 生成食物的x坐标
y = rand.nextInt(GRID_HEIGHT); // 生成食物的y坐标
} while (snake.contains(new Point(x, y))); // 确保食物不会生成在蛇的身体上
food = new Point(x, y); // 设置食物的位置
}
@Override
public void actionPerformed(ActionEvent e) { // 处理动作事件,即计时器触发的事件
if (running) {
move(); // 移动蛇
checkCollision(); // 检查是否有碰撞
checkFood(); // 检查是否吃到食物
repaint(); // 重绘游戏界面
}
}
private void move() {
Point head = (Point) snake.getFirst().clone(); // 获取蛇的头部的位置
switch (direction) { // 根据当前方向移动头部
case KeyEvent.VK_UP:
head.translate(0, -1);
break;
case KeyEvent.VK_DOWN:
head.translate(0, 1);
break;
case KeyEvent.VK_LEFT:
head.translate(-1, 0);
break;
case KeyEvent.VK_RIGHT:
head.translate(1, 0);
break;
}
snake.addFirst(head); // 将新的头部添加到蛇的身体前端
snake.removeLast(); // 移除蛇的身体末端,实现蛇的移动
}
private void checkCollision() {
Point head = snake.getFirst(); // 获取蛇的头部的位置
if ((head.x < 0) || (head.y < 0) || (head.x >= GRID_WIDTH) || (head.y >= GRID_HEIGHT)) { // 检查是否撞墙
running = false; // 游戏结束
}
if (snake.subList(1, snake.size()).contains(head)) { // 检查是否撞到自己
running = false; // 游戏结束
}
}
private void checkFood() {
if (snake.getFirst().equals(food)) { // 检查蛇的头部是否与食物位置相同
snake.addLast(new Point(-1, -1)); // 添加一个临时点以在下次移动时移除,实现蛇的身体增长
score += 100; // 吃到食物,分数加100
spawnFood(); // 重新生成食物
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (running) {
g.setColor(Color.RED);
g.fillRect(food.x * TILE_SIZE, food.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); // 绘制食物
g.setColor(Color.GREEN);
for (Point point : snake) { // 遍历蛇的身体,绘制每一部分
g.fillRect(point.x * TILE_SIZE, point.y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
drawScore(g); // 绘制分数
} else {
showGameOver(g); // 显示游戏结束信息
}
}
private void drawScore(Graphics g) {
String msg = "分数: " + score;
Font font = new Font("Helvetica", Font.BOLD, 20);
g.setColor(Color.WHITE);
g.setFont(font);
g.drawString(msg, 10, 20); // 在游戏界面上绘制分数
}
private void showGameOver(Graphics g) {
String msg = "游戏已结束";
Font font = new Font("Helvetica", Font.BOLD, 50);
g.setColor(Color.WHITE);
g.setFont(font);
g.drawString(msg, 120, getSize().height / 2); // 在游戏界面上绘制游戏结束信息
}
public static void main(String[] args) {
JFrame frame = new JFrame("贪吃蛇游戏"); // 创建游戏窗口
SnakeGame snakeGame = new SnakeGame(); // 创建游戏面板
frame.add(snakeGame); // 将游戏面板添加到窗口中
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置默认的关闭操作
frame.pack(); // 自动调整窗口大小以适应内容
frame.setVisible(true); // 显示窗口
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
这是一个使用Java语言和Graphics技术实现的简单贪吃蛇游戏代码。它包含了一个基本的贪吃蛇游戏逻辑,包括食物的生成、蛇的移动、吃到食物后的增长以及游戏结束的条件。代码结构清晰,注释详细,易于理解和学习。 这个资源适用于Java初学者和对游戏开发感兴趣的大家。它可以帮助大家掌握Java图形界面编程的基本知识,理解事件处理机制,以及学习游戏循环和状态管理的概念。同时,它也是一个很好的实践项目,可以帮助大家将所学的Java知识应用到实际的项目中。 学习Java图形界面编程:通过实现贪吃蛇游戏,大家可以学习Java中的Graphics类和相关的绘图方法,掌握如何在窗口中绘制图形和文字。 理解事件处理机制:代码中包含了键盘事件的处理,大家可以学习如何监听和响应用户的输入。 实践游戏开发:贪吃蛇游戏是一个经典的游戏,通过实现它可以了解游戏开发的基本流程和技巧。 拓展和定制:大家可以根据自己的需求对代码进行修改和扩展,增加更多的功能,如增加障碍物、实现多个关卡等。 代码中的注释详细,对于每个关键的部分都有解释,方便大家理解。
资源推荐
资源详情
资源评论
收起资源包目录
贪吃蛇java代码.zip (1个子文件)
SnakeGame.java 6KB
共 1 条
- 1
资源评论
大家都说我身材好
- 粉丝: 139
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功