第十一次实验课代码

添加C08~C011
This commit is contained in:
2025-11-20 17:01:56 +08:00
parent 1c869f816f
commit 9930f2421a
67 changed files with 1137 additions and 7 deletions

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,17 @@
package game;
import java.awt.*;
public enum Direction {
UP(new Point(0,-1)),
DOWN(new Point(0,1)),
LEFT(new Point(-1,0)),
RIGHT(new Point(1,0));
private Point offset;
Direction(Point offset) {
this.offset = offset;
}
public static Point getOffset(Direction dir) {
return dir.offset;
}
}

View File

@@ -0,0 +1,7 @@
package game;
import java.awt.*;
public interface Drawable {
void draw(Graphics g);
}

View File

@@ -0,0 +1,38 @@
package game;
import java.awt.*;
import java.util.Random;
public class Food extends GameElement{
private static Random randeom = new Random();
public Food(int width,int height) {
super(0,0);
randomPosition(width,height);
}
/**
* 随机设置位置坐标
* @param width 可用宽度范围
* @param height 可用高度范围
*/
public void randomPosition(int width, int height) {
//计算一排或一列最多的格子数
int maxX = width/SIZE;
int maxY = height/SIZE;
//将位置坐标映射到像素点
int x = randeom.nextInt(maxX)*SIZE;
int y = randeom.nextInt(maxY)*SIZE;
//设置坐标
position.setLocation(x,y);
}
@Override
public void draw(Graphics g) {
//红色填充,黑色边框
g.setColor(Color.RED);
g.fillOval(position.x,position.y,SIZE,SIZE);
g.setColor(Color.BLACK);
g.drawOval(position.x,position.y,SIZE,SIZE);
}
}

View File

@@ -0,0 +1,15 @@
package game;
import java.awt.*;
public abstract class GameElement {
protected Point position;
public static final int SIZE = 20;
protected GameElement(int x,int y) {
position = new Point(x,y);
}
public Point getPosition() {
return position;
}
public abstract void draw(Graphics g);
}

View File

@@ -0,0 +1,5 @@
package game;
public interface Movable {
void move();
}

View File

@@ -0,0 +1,31 @@
package game;
import java.awt.*;
public class SnakeNode extends GameElement implements Movable{
private Direction direction;
public SnakeNode(int x, int y, Direction direction) {
super(x, y);
this.direction = direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
@Override
public void draw(Graphics g) {
//绿色填充,黑色边框
g.setColor(Color.GREEN);
g.fillRect(position.x, position.y, SIZE, SIZE);
// 绘制边框,让蛇身更清晰
g.setColor(Color.BLACK);
g.drawRect(position.x, position.y, SIZE, SIZE);
}
@Override
public void move() {
Point offset = Direction.getOffset(direction);
position.x += offset.x*SIZE;
position.y += offset.y*SIZE;
}
}

View File

@@ -0,0 +1,85 @@
package view;
import game.Direction;
import game.Food;
import game.SnakeNode;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class GamePanel extends JPanel {
private static final int WIDTH = 600;
private static final int HEIGHT = 600;
private boolean isRunning;
// FIXME 蛇身体节点 未来需要改进
private SnakeNode[] snakeBody = new SnakeNode[3];
private final Food food;
public GamePanel() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.WHITE); // 背景色设为白色
// FIXME 初始化蛇 未来需要改进
snakeBody[0] = new SnakeNode(100, 100, Direction.RIGHT);
snakeBody[1] = new SnakeNode(80, 100, Direction.RIGHT);
snakeBody[2] = new SnakeNode(60, 100, Direction.RIGHT);
food = new Food(WIDTH, HEIGHT);
// 键盘监听
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// TODO 按下按键后需要做处理
}
});
setFocusable(true); // 确保面板能接收键盘事件
// 游戏循环
new Thread(() -> {
while (isRunning) {
try {
Thread.sleep(250);
moveSnake(); // 移动蛇
checkCollision(); // 检查碰撞
repaint(); // 调用paintComponent重绘
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
private void moveSnake() {
// TODO
}
private void checkCollision() {
// TODO
}
private void gameOver() {
isRunning = false;
JOptionPane.showMessageDialog(this, "游戏结束!得分:");
System.exit(0);
}
// 核心改进重写paintComponent而非paint利用Swing双缓冲
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // 先绘制背景(双缓冲关键步骤)
// 绘制蛇
for (SnakeNode node : snakeBody) {
node.draw(g);
}
// 绘制食物
food.draw(g);
}
}

View File

@@ -0,0 +1,18 @@
package view;
import javax.swing.*;
public class SnakeGame extends JFrame {
public SnakeGame() {
setTitle("贪吃蛇");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new GamePanel()); // 添加游戏面板
pack(); // 自动调整窗口大小以适应面板
setLocationRelativeTo(null); // 窗口居中
setVisible(true);
}
public static void main(String[] args) {
new SnakeGame();
}
}