mirror of
https://gitee.com/yanmu_ym/cpp.git
synced 2026-02-02 17:18:52 +08:00
Make
This commit is contained in:
30
Make/java/Snake/src/C.java
Normal file
30
Make/java/Snake/src/C.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
public final class C {
|
||||||
|
// 格子行列数
|
||||||
|
public static final int LINE_NUM = 20;
|
||||||
|
|
||||||
|
// 格子宽度
|
||||||
|
public static final int UNIT_WIDTH = 20;
|
||||||
|
|
||||||
|
// Frame的宽度
|
||||||
|
public static final int FRAME_W = LINE_NUM * UNIT_WIDTH + 16;
|
||||||
|
|
||||||
|
// Frame的高度
|
||||||
|
public static final int FRAME_H = LINE_NUM * UNIT_WIDTH + 39;
|
||||||
|
|
||||||
|
// 速度 范围为1~10
|
||||||
|
public static final int SPEED = 5;
|
||||||
|
|
||||||
|
// 背景颜色
|
||||||
|
public static final Color BGCOLOR = Color.GRAY;
|
||||||
|
|
||||||
|
// 格子线颜色
|
||||||
|
public static final Color GRIDCOLOR = new Color(120, 120, 120);
|
||||||
|
|
||||||
|
// 蛇身颜色
|
||||||
|
public static final Color SNAKECOLOR = Color.BLACK;
|
||||||
|
|
||||||
|
// 食物颜色
|
||||||
|
public static final Color FOODCOLOR = Color.GREEN;
|
||||||
|
}
|
||||||
10
Make/java/Snake/src/Main.java
Normal file
10
Make/java/Snake/src/Main.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
new SnakeFrame("̰³ÔÉß");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
18
Make/java/Snake/src/Makefile
Normal file
18
Make/java/Snake/src/Makefile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
snake.jar : C.class Main.class SnakeFrame.class SnakePanel.class
|
||||||
|
jar -cvfe snake.jar Main *.class
|
||||||
|
|
||||||
|
C.class : C.java
|
||||||
|
javac C.java
|
||||||
|
|
||||||
|
Main.class : Main.java
|
||||||
|
javac Main.java
|
||||||
|
|
||||||
|
SnakeFrame.class : SnakeFrame.java
|
||||||
|
javac SnakeFrame.java
|
||||||
|
|
||||||
|
SnakePanel.class : SnakePanel.java
|
||||||
|
javac SnakePanel.java
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm *.class *.jar
|
||||||
43
Make/java/Snake/src/SnakeFrame.java
Normal file
43
Make/java/Snake/src/SnakeFrame.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.HeadlessException;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class SnakeFrame extends JFrame {
|
||||||
|
|
||||||
|
private SnakePanel snakePanel;
|
||||||
|
|
||||||
|
public SnakeFrame() throws HeadlessException {
|
||||||
|
this("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public SnakeFrame(String title) throws HeadlessException {
|
||||||
|
super(title);
|
||||||
|
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||||
|
Dimension dim = toolkit.getScreenSize();
|
||||||
|
this.setBounds((dim.width - C.FRAME_W) / 2, (dim.height - C.FRAME_H) / 2, C.FRAME_W, C.FRAME_H);
|
||||||
|
this.snakePanel = new SnakePanel();
|
||||||
|
this.setContentPane(this.snakePanel);
|
||||||
|
|
||||||
|
this.setVisible(true);
|
||||||
|
this.setResizable(false);
|
||||||
|
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
this.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {
|
||||||
|
SnakeFrame.this.windowOpened(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void windowOpened(WindowEvent e) {
|
||||||
|
this.snakePanel.initSomething();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
237
Make/java/Snake/src/SnakePanel.java
Normal file
237
Make/java/Snake/src/SnakePanel.java
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
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.function.Consumer;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class SnakePanel extends JPanel {
|
||||||
|
|
||||||
|
private JLabel infoStart;
|
||||||
|
private JLabel infoOver;
|
||||||
|
|
||||||
|
private boolean inited;
|
||||||
|
private boolean gameOver;
|
||||||
|
private boolean gamePause;
|
||||||
|
private boolean gameStart;
|
||||||
|
|
||||||
|
private int direction;
|
||||||
|
private int food;
|
||||||
|
private int nextNode;
|
||||||
|
private LinkedList<Integer> snakeNodes;
|
||||||
|
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
public SnakePanel() {
|
||||||
|
this.setBackground(C.BGCOLOR);
|
||||||
|
this.setLayout(null);
|
||||||
|
this.setFocusable(true);
|
||||||
|
this.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
SnakePanel.this.keyPressed(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Font font = new Font("黑体", Font.BOLD, 28);
|
||||||
|
this.infoOver = new JLabel("游戏结束");
|
||||||
|
this.infoOver.setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
this.infoOver.setFont(font);
|
||||||
|
this.infoStart = new JLabel("按空格键开始或暂停游戏");
|
||||||
|
this.infoStart.setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
this.infoStart.setFont(font);
|
||||||
|
this.add(this.infoOver);
|
||||||
|
this.add(this.infoStart);
|
||||||
|
this.hideInfo();
|
||||||
|
this.gameStart = false;
|
||||||
|
|
||||||
|
this.direction = 1;
|
||||||
|
|
||||||
|
this.snakeNodes = new LinkedList<>();
|
||||||
|
this.food = -1;
|
||||||
|
|
||||||
|
this.timer = new Timer(1000 / C.SPEED, new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
SnakePanel.this.snakeMove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateFood() {
|
||||||
|
do {
|
||||||
|
this.food = (int)(Math.random() * C.LINE_NUM * C.LINE_NUM);
|
||||||
|
} while(this.snakeNodes.contains(this.food));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showInfo() {
|
||||||
|
if(this.gameOver) {
|
||||||
|
this.infoOver.setVisible(true);
|
||||||
|
}
|
||||||
|
this.infoStart.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideInfo() {
|
||||||
|
this.infoOver.setVisible(false);
|
||||||
|
this.infoStart.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
super.paint(g);
|
||||||
|
if(!this.inited) {
|
||||||
|
this.initPaint(g);
|
||||||
|
this.inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaint(Graphics g) {
|
||||||
|
g.setColor(C.GRIDCOLOR);
|
||||||
|
|
||||||
|
for(int i = 0; i <= C.LINE_NUM; i++) {
|
||||||
|
g.drawLine(0, i * C.UNIT_WIDTH, this.getWidth(), i * C.UNIT_WIDTH);
|
||||||
|
g.drawLine(i * C.UNIT_WIDTH, 0, i * C.UNIT_WIDTH, this.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ???我当时为什么要用forEach这个写法?不是有简单写法???
|
||||||
|
this.snakeNodes.forEach(new Consumer<Integer>() {
|
||||||
|
@Override
|
||||||
|
public void accept(Integer t) {
|
||||||
|
SnakePanel.this.paintUnit(g, C.SNAKECOLOR, t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.paintUnit(g, C.FOODCOLOR, this.food);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paintUnit(Graphics g, Color color, int pos) {
|
||||||
|
g.setColor(color);
|
||||||
|
g.fillRect(X(pos) + 1, Y(pos) + 1, C.UNIT_WIDTH - 1, C.UNIT_WIDTH - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int X(int pos) {
|
||||||
|
return pos % C.LINE_NUM * C.UNIT_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int Y(int pos) {
|
||||||
|
return pos / C.LINE_NUM * C.UNIT_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void keyPressed(KeyEvent e) {
|
||||||
|
int temDirect = this.direction;
|
||||||
|
switch (e.getKeyCode()) {
|
||||||
|
case KeyEvent.VK_SPACE:
|
||||||
|
if(!this.gameStart) {
|
||||||
|
this.hideInfo();
|
||||||
|
this.snakeNodes.clear();
|
||||||
|
this.snakeNodes.add(3);
|
||||||
|
this.snakeNodes.add(2);
|
||||||
|
this.snakeNodes.add(1);
|
||||||
|
this.direction = 1;
|
||||||
|
this.nextNode = 4;
|
||||||
|
this.generateFood();
|
||||||
|
this.gameOver = false;
|
||||||
|
this.gamePause = false;
|
||||||
|
this.gameStart = true;
|
||||||
|
this.inited = false;
|
||||||
|
this.update(this.getGraphics());
|
||||||
|
} else if (!this.gameOver) {
|
||||||
|
this.gamePause = !this.gamePause;
|
||||||
|
}
|
||||||
|
if(!this.timer.isRunning()) {
|
||||||
|
this.inited = false;
|
||||||
|
this.timer.start();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyEvent.VK_LEFT:
|
||||||
|
this.setDirection(-1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyEvent.VK_UP:
|
||||||
|
this.setDirection(-C.LINE_NUM);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyEvent.VK_RIGHT:
|
||||||
|
this.setDirection(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyEvent.VK_DOWN:
|
||||||
|
this.setDirection(C.LINE_NUM);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDirection(int direction) {
|
||||||
|
if (this.gameOver || this.gamePause) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
int currentDirection = this.snakeNodes.get(0) - this.snakeNodes.get(1);
|
||||||
|
this.direction = (direction == -currentDirection) ? currentDirection : direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void snakeMove() {
|
||||||
|
this.nextNode = this.snakeNodes.get(0) + this.direction;
|
||||||
|
this.judgeOver();
|
||||||
|
if(this.gameOver || this.gamePause) {
|
||||||
|
this.timer.stop();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
this.snakeNodes.addFirst(this.nextNode);
|
||||||
|
this.paintUnit(this.getGraphics(), C.SNAKECOLOR, this.nextNode);
|
||||||
|
if(this.nextNode == this.food) {
|
||||||
|
this.generateFood();
|
||||||
|
this.paintUnit(this.getGraphics(), C.FOODCOLOR, this.food);
|
||||||
|
} else {
|
||||||
|
this.paintUnit(this.getGraphics(), C.BGCOLOR, this.snakeNodes.removeLast());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void judgeOver() {
|
||||||
|
boolean hitSelf = this.snakeNodes.contains(this.nextNode);
|
||||||
|
boolean hitWall = (this.nextNode < 0) || (this.nextNode > (C.LINE_NUM * C.LINE_NUM))
|
||||||
|
|| ((this.direction == 1) && (this.nextNode % C.LINE_NUM == 0))
|
||||||
|
|| ((this.direction == -1) && (this.nextNode % C.LINE_NUM == C.LINE_NUM - 1));
|
||||||
|
if(hitSelf || hitWall) {
|
||||||
|
this.gameOver = true;
|
||||||
|
this.gameStart = false;
|
||||||
|
this.gamePause = false;
|
||||||
|
this.showInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initSomething() {
|
||||||
|
this.infoOver.setBounds(0, 0, this.getWidth(), 30);
|
||||||
|
this.infoStart.setBounds(0, 40, this.getWidth(), 30);
|
||||||
|
this.showInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user