ADD file via upload

main
ppx98yace 4 months ago
parent b0fb4761c6
commit 1f2a49e92d

@ -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<Point> 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<Point> getBody() { return new LinkedList<>(body); }
}
Loading…
Cancel
Save