From 1f2a49e92d3e85e5e8cb0d075b7db14c944f0dd3 Mon Sep 17 00:00:00 2001 From: ppx98yace <3576677045@qq.com> Date: Sat, 29 Mar 2025 23:23:34 +0800 Subject: [PATCH] ADD file via upload --- src/Snake.java | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/Snake.java diff --git a/src/Snake.java b/src/Snake.java new file mode 100644 index 0000000..c3b4ebc --- /dev/null +++ b/src/Snake.java @@ -0,0 +1,130 @@ +package com.snakegame; + +import java.awt.*; +import java.awt.geom.GeneralPath; +import java.util.LinkedList; +import java.awt.event.KeyEvent; // 导入 KeyEvent + +public class Snake { + private final LinkedList body = new LinkedList<>(); + private final Color[] colors; + private final boolean gradientEnabled; + private Direction direction = Direction.RIGHT; + private Direction nextDirection = Direction.RIGHT; + + // 方向枚举 + private enum Direction { + UP(0, -1), + DOWN(0, 1), + LEFT(-1, 0), + RIGHT(1, 0); + + public final int dx; + public final int dy; + + Direction(int dx, int dy) { + this.dx = dx; + this.dy = dy; + } + } + + // 构造函数 + public Snake(int x, int y, Color[] colors, boolean gradientEnabled) { + if (colors.length < 2) throw new IllegalArgumentException("需要至少2个颜色"); + this.colors = colors.clone(); + this.gradientEnabled = gradientEnabled; + reset(x, y); + } + + // 重置位置 + private void reset(int x, int y) { + body.clear(); + body.add(new Point(x, y)); + body.add(new Point(x - 1, y)); + body.add(new Point(x - 2, y)); + } + + // 移动逻辑 + public void move() { + direction = nextDirection; + Point newHead = new Point( + body.getFirst().x + direction.dx, + body.getFirst().y + direction.dy + ); + body.addFirst(newHead); + body.removeLast(); + } + + // 身体增长 + public void grow() { + body.addLast(new Point(body.getLast())); + } + + // 按键处理 + public void handleKeyPress(int keyCode) { + switch (keyCode) { + case KeyEvent.VK_UP: + if (direction != Direction.DOWN) nextDirection = Direction.UP; + break; + case KeyEvent.VK_DOWN: + if (direction != Direction.UP) nextDirection = Direction.DOWN; + break; + case KeyEvent.VK_LEFT: + if (direction != Direction.RIGHT) nextDirection = Direction.LEFT; + break; + case KeyEvent.VK_RIGHT: + if (direction != Direction.LEFT) nextDirection = Direction.RIGHT; + break; + } + } + + // 绘制逻辑 + public void draw(Graphics g, int tileSize) { + Graphics2D g2d = (Graphics2D) g; + for (int i = 0; i < body.size(); i++) { + Point p = body.get(i); + g2d.setColor(getSegmentColor(i)); + if (i == 0) { + // 绘制蛇头(三角形) + drawSnakeHead(g2d, p.x * tileSize, p.y * tileSize, tileSize); + } else { + // 绘制蛇身(圆形) + g2d.fillOval(p.x * tileSize, p.y * tileSize, tileSize - 2, tileSize - 2); + } + } + } + + private void drawSnakeHead(Graphics2D g2d, int x, int y, int tileSize) { + GeneralPath path = new GeneralPath(); + int headSize = tileSize / 2; + path.moveTo(x + tileSize / 2, y); + path.lineTo(x + tileSize / 2 - headSize, y + headSize); + path.lineTo(x + tileSize / 2 + headSize, y + headSize); + path.closePath(); + g2d.fill(path); + } + + private Color getSegmentColor(int index) { + // 头部颜色(使用数组第一个元素) + if (index == 0) return colors[0]; + + // 未启用渐变时(使用数组第二个元素) + if (!gradientEnabled) return colors[1]; + + // 渐变计算(从第二个颜色渐变到第一个颜色) + Color startColor = colors[1]; // 身体基础色 + Color endColor = colors[0]; // 头部颜色 + float ratio = (float) (index - 1) / (body.size() - 1); + + return new Color( + (int) (startColor.getRed() * (1 - ratio) + endColor.getRed() * ratio), + (int) (startColor.getGreen() * (1 - ratio) + endColor.getGreen() * ratio), + (int) (startColor.getBlue() * (1 - ratio) + endColor.getBlue() * ratio) + ); + } + + // 辅助方法 + public Point getHead() { return body.getFirst(); } + public boolean contains(Point point) { return body.contains(point); } + public LinkedList getBody() { return new LinkedList<>(body); } +} \ No newline at end of file