废话少说,上代码。
package priv.caoMingLiang.frame;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
import priv.caoMingLiang.model.Food;
import priv.caoMingLiang.model.Node;
import priv.caoMingLiang.model.Snake;
import priv.caoMingLiang.type.Direction;
public class MainFrame extends JFrame {
private Snake snake;
private JPanel gamePanel;
private Timer timer; // 定时器
private boolean canOnClick = true; // 改变方向冷却
private Food food;
public MainFrame() throws HeadlessException {
super();
// 初始化主窗体
initMainFrame();
// 初始化游戏面板
initGamePanel();
// 初始化蛇
initSnake();
// 初始化食物
initFood();
// 初始化定时器
initTimer();
// 设置键盘监听
setKeyListener();
}
private void initFood() {
food = new Food();
food.randomNode();
}
private void setKeyListener() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
if (canOnClick) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
case KeyEvent.VK_W:
if (snake.getDirection() != Direction.DOWN) {
snake.setDirection(Direction.UP);
}
break;
case KeyEvent.VK_LEFT:
case KeyEvent.VK_A:
if (snake.getDirection() != Direction.RIGHT) {
snake.setDirection(Direction.LEFT);
}
break;
case KeyEvent.VK_DOWN:
case KeyEvent.VK_S:
if (snake.getDirection() != Direction.UP) {
snake.setDirection(Direction.DOWN);
}
break;
case KeyEvent.VK_RIGHT:
case KeyEvent.VK_D:
if (snake.getDirection() != Direction.LEFT) {
snake.setDirection(Direction.RIGHT);
}
break;
}
canOnClick = false;
}
}
});
}
/**
* 初始化定时任务
*/
private void initTimer() {
timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
snake.move();
if (snake.isAlive) {
gamePanel.repaint();
Node head = snake.getBody().getFirst();
if (food.getX() == head.getX() && food.getY() == head.getY()) {
snake.eat(food);
food.randomNode();
}
} else {
initSnake();
}
if (!canOnClick) {
canOnClick = true;
}
}
};
timer.scheduleAtFixedRate(task, 0, 120);
}
/**
* 初始化主窗体
*/
private void initMainFrame() {
setTitle("贪吃蛇");
setSize(610, 640); // 设置窗体大小
setLocation(400, 40); // 设置窗体位置
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
}
/**
* 初始化游戏面板
*/
private void initGamePanel() {
gamePanel = new JPanel() {
@Override
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <= 40; i++) {
g.drawLine(0, i * 15, 600, i * 15);
}
for (int i = 0; i <= 40; i++) {
g.drawLine(i * 15, 0, i * 15, 600);
}
LinkedList<Node> body = snake.getBody();
for (int i = 0; i < body.size(); i++) {
Node node = body.get(i);
g.fillRect(node.getX() * 15, node.getY() * 15, 15, 15);
}
g.setColor(Color.RED);
g.fillOval(food.getX() * 15, food.getY() * 15, 15, 15);
}
};
add(gamePanel);
}
private void initSnake() {
snake = new Snake();
}
}
package priv.caoMingLiang.model;
import java.util.Random;
public class Node {
private Random random = new Random();
private int x;
private int y;
public Node() {
super();
// TODO Auto-generated constructor stub
}
public Node(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void randomNode() {
x = random.nextInt(40);
y = random.nextInt(40);
}
}
package priv.caoMingLiang.model;
import java.util.LinkedList;
import priv.caoMingLiang.type.Direction;
public class Snake {
private LinkedList<Node> body;
private Direction direction = Direction.LEFT;
public boolean isAlive = true;
public Snake() {
super();
initSnake();
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
public LinkedList<Node> getBody() {
return body;
}
public void setBody(LinkedList<Node> body) {
this.body = body;
}
public void initSnake() {
body = new LinkedList<>();
for (int i = 19; i < 22; i++) {
body.add(new Node(i, 20));
}
}
public void move() {
if (isAlive) {
Node head = body.getFirst(); // 获取蛇头
int x = head.getX();
int y = head.getY();
switch (direction) {
case UP:
body.addFirst(new Node(x, y - 1));
break;
case DOWN:
body.addFirst(new Node(x, y + 1));
break;
case LEFT:
body.addFirst(new Node(x - 1, y));
break;
case RIGHT:
body.addFirst(new Node(x + 1, y));
break;
default:
break;
}
body.removeLast();
if (x < 0 || x >= 40 || y < 0 || y >= 40) {
isAlive = false;
}
for (int i = 4; i < body.size(); i++) {
Node node = body.get(i);
int x0 = node.getX();
int y0 = node.getY();
if (x == x0 && y == y0) {
isAlive = false;
break;
}
}
}
}
public void eat(Food food) {
Node head = body.getFirst(); // 获取蛇头
int x = head.getX();
int y = head.getY();
switch (direction) {
case UP:
body.addFirst(new Node(x, y - 1));
break;
case DOWN:
body.addFirst(new Node(x, y + 1));
break;
case LEFT:
body.addFirst(new Node(x - 1, y));
break;
case RIGHT:
body.addFirst(new Node(x + 1, y));
break;
default:
break;
}
}
}
好吧,其实跟节点类没区别,就是为了有那个意思,继承完啥都没写
package priv.caoMingLiang.model;
public class Food extends Node {
}
package priv.caoMingLiang.type;
public enum Direction {
UP,DOWN,LEFT,RIGHT
}
package priv.caoMingLiang.main;
import priv.caoMingLiang.frame.MainFrame;
public class Start {
public static void main(String[] args) {
new MainFrame().setVisible(true);
}
}