第十一次实验课代码
添加C08~C011
This commit is contained in:
11
C08-SnackGame/C08-SnackGame.iml
Normal file
11
C08-SnackGame/C08-SnackGame.iml
Normal 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>
|
||||
17
C08-SnackGame/src/game/Direction.java
Normal file
17
C08-SnackGame/src/game/Direction.java
Normal 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;
|
||||
}
|
||||
}
|
||||
7
C08-SnackGame/src/game/Drawable.java
Normal file
7
C08-SnackGame/src/game/Drawable.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package game;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public interface Drawable {
|
||||
void draw(Graphics g);
|
||||
}
|
||||
38
C08-SnackGame/src/game/Food.java
Normal file
38
C08-SnackGame/src/game/Food.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
15
C08-SnackGame/src/game/GameElement.java
Normal file
15
C08-SnackGame/src/game/GameElement.java
Normal 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);
|
||||
}
|
||||
5
C08-SnackGame/src/game/Movable.java
Normal file
5
C08-SnackGame/src/game/Movable.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package game;
|
||||
|
||||
public interface Movable {
|
||||
void move();
|
||||
}
|
||||
31
C08-SnackGame/src/game/SnakeNode.java
Normal file
31
C08-SnackGame/src/game/SnakeNode.java
Normal 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;
|
||||
}
|
||||
}
|
||||
85
C08-SnackGame/src/view/GamePanel.java
Normal file
85
C08-SnackGame/src/view/GamePanel.java
Normal 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);
|
||||
}
|
||||
}
|
||||
18
C08-SnackGame/src/view/SnakeGame.java
Normal file
18
C08-SnackGame/src/view/SnakeGame.java
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user