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