java实现贪吃蛇
- 说在前面
- 整体思路
- 代码实现
- MainFrame
- Snake
- Node
- Direction
- 整体调用
- 总结
说在前面
一直想实现一个贪吃蛇,于是在CSDN github上都找到了许多源码,于是自己不到三百行,实现了一个贪吃蛇代码
哈哈哈哈哈 虽然特别的简陋 但是包括了核心算法
super版的大家可以自己添加(比如添加更好看的背景图片 音乐 等等
整体思路
(想要直接看代码的可以直接进入代码区喽)
1. 运行界面的设计
2. 蛇 snake本身的设计
也就是如何让蛇 动起来(控制方向与键盘监听)
3. 吃小苹果的状态变化 (蛇身变长)
4. 游戏结束控制(吃到自己 撞墙)
代码实现
整体框架
总共四个类:
MainFrame: 主游戏以及界面设置
Snake: 控制蛇运动
Node: 实现蛇 与 小苹果(如何达到展示蛇与小苹果呢?)
Direction: 枚举类 方向(提高可扩展性与可读性)
MainFrame
public class MainFrame {
JFrame frame=new JFrame();
private JPanel jpanel;//棋盘
private Snake snake;
private Node food; //食物
private Timer timer; //定时器,在指定时间 调用蛇移动的方法
public MainFrame() throws HeadlessException{
//创建窗体
initFrame();
//初始化游戏棋盘
initGamePanel();
//创建蛇
initSnake();
//初始化定时器
initFood();
initTimer();
//设置键盘监听
setKeyListener();
}
/**
*中间是方法的具体实现
**/
public static void main(String[] args) {
new MainFrame();
}
通过注释可以知道整个游戏的流程
Snake
public class Snake {
private LinkedList<Node> body;
//蛇的运动方向 默认向左
private Direction direction=Direction.LEFT;
//蛇是否活着
private boolean isLiving=true;
//初始化蛇
public Snake(){
initSnakeBody();
}
private void initSnakeBody() {
//创建集合
body=new LinkedList<>();
//创建六个节点创建在集合中
for(int i=0;i<6;i++)
body.add(new Node(16+i,20));
}
//蛇按照蛇头的方向移动
//控制蛇移动 哪个方向就加一个节点
public void move() {}
public void eat(Node food){}
public void addHead(Node head){}
Getter && Setter 方法
通过成员变量,我们可以看出主要逻辑:
蛇与Node是组合关系 因为有蛇就要创建它,但是两者没有继承父子类关系
因此使用 组合 即:初始化是新建了其对象
Snake类有其对应的方法
Node
//省略了 Getter与Setter方法
public class Node {
private int x;
private int y;
public Node(){
}
public Node(int x,int y){
this.x=x;
this.y=y;
}
//随机位置生成
public void random(){
Random r=new Random();
//
this.x=r.nextInt(40); //40是范围
this.y=r.nextInt(40);
}
public boolean equal(Node node_other){
return this.x==node_other.getX() && this.y==node_other.getY();
}
}
Node类就要实现 网格初始化的Rondom方法,以及拥有含参构造方法,以便snake初始化生成蛇可以定位
Direction
枚举类就很简单了方便表达
public enum Direction {
UP,
DOWN,
LEFT,
RIGHT;
}
整体调用
先初始化棋盘与蛇的位置
MainFrame 中有一个timer,每100毫秒调用Snake的move()方法,而本质上这个move方法,他是相当于更新蛇的式样,添加头,减少尾部(如果有食物,就再添加)
同时设置键盘监听,更新direction,而这个通过set方法进行传递,再有addHead方法根据坐标实现。(需要注意的是,蛇当向上走时,此时不能直接向下走,因此要增加判断条件)
然后每过一次timer,调用Frame.repaint()方法,以此达到移动效果。
public void move() {
if(isLiving) {
//获取蛇头并添加
Node head = body.getFirst();
addHead(head);
//删除最后节点
body.removeLast();
//判断是否撞墙
head=body.getFirst();
if(head.getX()<0||head.getX()>=40||head.getY()<0||head.getY()>=40)
isLiving=false;
//判断蛇是否碰得到自己的身体
for(int i=1;i<body.size();i++)
{
Node node=body.get(i);
if(node.equal(head)) //可以写一个 equals override方法
isLiving=false;
}
}
}
总结
各个类如何协作,如何让蛇动起来,swing类如何使用,这是贪吃蛇完成的关键。