one
package com.wang;
/**
* 枚举:枚举就是几个固定的常量
*/
public enum Direction {
UP,DOWN,LEFT,RIGHT
}
**
two
**
package com.wang;
import javax.swing.*;
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;
public class MainFrame extends JFrame {
// 蛇
private Snake snake;
// 定时器,在指定的时间调用这个蛇移动的方法
private Timer timer;
private JPanel jPanel; // 游戏棋盘
private Node food; // 食物
public MainFrame() throws HeadlessException {
// 初始化食物
initFood();
// 初始化窗体参数
initFrame();
// 初始化游戏棋盘
initGamePanel();
// 初始化蛇
initSnake();
// 初始化定时器
initTimer();
// 设置键盘监听,让蛇随着上下左右方向移动
setListener();
}
// 初始化食物
private void initFood() {
food = new Node();
food.random();
}
// 设置一个键盘监听
private void setListener() {
addKeyListener(new KeyAdapter() {
// 当键盘按下时,会自动调用此方法
@Override
public void keyPressed(KeyEvent e) {
System.out.println("键盘按下");
// 键盘中的每一个键都有一个编号
switch (e.getKeyCode()){
case KeyEvent.VK_UP: // 上键
// 修改蛇的运动方向
if (snake.getDirection()!=Direction.DOWN){
snake.setDirection(Direction.UP);
}
break;
case KeyEvent.VK_DOWN: // 下键
if (snake.getDirection()!=Direction.UP){
snake.setDirection(Direction.DOWN);
}
break;
case KeyEvent.VK_LEFT: // 左键
if (snake.getDirection()!=Direction.RIGHT){
snake.setDirection(Direction.LEFT);
}
break;
case KeyEvent.VK_RIGHT: // 右键
if (snake.getDirection()!=Direction.LEFT){
snake.setDirection(Direction.RIGHT);
}
break;
}
}
});
}
//初始化定时器
private void initTimer() {
// 创建定时任务对象
timer = new Timer();
// 初始化定时任务
TimerTask timerTask = new TimerTask(){
@Override
public void run() {
snake.move();
// 判断蛇是否和食物重合
Node head = snake.getBody().getFirst();
if (head.getX()==food.getX()&&head.getY()==food.getY()){
snake.eat(food);
food.random();
}
// 重绘游戏棋盘
jPanel.repaint();
}
};
// 每100毫秒,执行一次定时任务
timer.scheduleAtFixedRate(timerTask,0,100);
}
private void initSnake() {
snake = new Snake();
}
// 初始化游戏棋盘
private void initGamePanel(){
jPanel = new JPanel(){
// 绘制游戏棋盘中的内容
@Override
public void paint(Graphics graphics){
// 清空棋盘
graphics.clearRect(0,0,600,600);
// Graphics graphics 可以看作是一个画笔,他提供了很多方法可以来绘制一些基本的图形(直线,矩形等)
// 绘制40条横线
for (int i = 0; i <= 40; i++) {
graphics.drawLine(0,i*15,600,i*15);
}
// 绘制40条竖线
for (int i = 0; i <= 40; i++) {
graphics.drawLine(i*15,0,i*15,600);
}
// 绘制蛇
LinkedList<Node> body = snake.getBody();
for (Node node : body) {
graphics.fillRect(node.getX()*15,node.getY()*15,15,15);
}
// 绘制实物
graphics.fillRect(food.getX()*15,food.getY()*15,15,15);
}
};
// 把棋盘添加到窗体中
add(jPanel);
}
// 初始化窗体参数
private void initFrame(){
// 设置宽高
setSize(610,640);
// 设置窗体的位置
setLocation(400,400);
// 设置关闭按钮的作用(退出程序)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗体大小不可变
setResizable(false);
}
public static void main(String[] args) {
// 创建窗体对象,并显示
new MainFrame().setVisible(true);
}
}
**
three
**
package com.wang;
import java.util.Random;
/**
* 节点类:每一条蛇是由若干个节点组成的,每一个节点有横纵坐标来确定位置
*/
public class Node {
private int x;
private int 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 Node(int x, int y) {
this.x = x;
this.y = y;
}
public Node() {
}
// 随机生成位置的方法
public void random(){
Random random = new Random();
// 随机生成横坐标
this.x = random.nextInt(40);
// 随机生成纵坐标
this.y = random.nextInt(40);
}
}
**
four
**
package com.wang;
import java.util.LinkedList;
/**
* Snake类表示蛇
*│一条蛇有多个节点使用LinkedList集合存储Node节点,蛇出生的时候有6个节点。
* */
public class Snake {
// 蛇的身体
private LinkedList<Node> body;
// 蛇的运动方向,默认向左
private Direction direction = Direction.LEFT;
// 蛇是否活着
private boolean isLiving = true;
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 Snake() {
// 初始化蛇的身体
initSnake();
}
private void initSnake() {
// 创建集合
body = new LinkedList<>();
// 创建6个节点,添加到集合中
body.add(new Node(16,20));
body.add(new Node(17,20));
body.add(new Node(18,20));
body.add(new Node(19,20));
body.add(new Node(20,20));
body.add(new Node(21,20));
}
// 蛇回沿着舌头的方向移动
// 控制蛇移动:在蛇头的运动方向添加一个节点,然后把蛇尾的节点删除
public void move(){
if (isLiving){
// 要去获取蛇头
Node head = body.getFirst();
switch (direction){
case UP:
// 舌头的上面添加一个节点
body.addFirst(new Node(head.getX(),head.getY()-1));
break;
case DOWN:
body.addFirst(new Node(head.getX(),head.getY()+1));
break;
case LEFT:
body.addFirst(new Node(head.getX()-1,head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX()+1,head.getY()));
break;
}
// 删除最后的节点
body.removeLast();
// 判断蛇是否撞墙
head = body.getFirst();
if (head.getX()<0||head.getY()<0||head.getX()>=40||head.getY()>=40){
isLiving = false;
}
// 判断蛇是否碰到自己的身体
for (int i = 1; i <body.size() ; i++) {
Node node = body.get(i);
if (head.getX()==node.getX()&&head.getY()==node.getY()){
isLiving = false;
}
}
}
}
// 吃食物:沿着舌头的移动方向添加一个节点
public void eat(Node food) {
// 获取蛇头
Node head = body.getFirst();
switch (direction){
case UP:
// 舌头的上面添加一个节点
body.addFirst(new Node(head.getX(),head.getY()-1));
break;
case DOWN:
body.addFirst(new Node(head.getX(),head.getY()+1));
break;
case LEFT:
body.addFirst(new Node(head.getX()-1,head.getY()));
break;
case RIGHT:
body.addFirst(new Node(head.getX()+1,head.getY()));
break;
}
}
}