Hello,I'm Shendi 闲来无事写个贪吃蛇耍耍
思路呢大概就是
一个窗体(JFrame)
三个图片(JLabel) 背景 食物 蛇
使用一个二维数组代表场景地图...
图片效果
源码在最文章最后,这里就片面的描述一下(伪代码 一个类)
public class Snake {
//伪代码 纯手码 需要看结果请去获取源码 有问题请留言
//首先,我们需要定义场景 一个二维数组 表示x y轴
int[][] scene;
//定义窗体
JFrame frame;
//定义 蛇 背景 食物
JLabel snake,grid,food;
//蛇身体的数量 以及蛇头位置 我这里直接用个变量了
int x,y;
int snakeNum = 1;
//定义蛇的方向 默认为左 0左 1右 2上 3下
int action=0;
//定义游戏状态 true为运行中 false为未运行
boolean isStart;
public Snake() {
//先初始化窗体
frame = new JFrame("标题");
frame.setBounds(10,10,600,400);//固定为 600宽 400高
//清除布局
frame.setLayout(null);
//初始化场景 就定义蛇的身体为20长 20宽
scene = new int[20][30];//20代表y 为高 30代表x
//给场景边缘初始化为石头? 就定义为3(蛇头2 食物1 蛇身呢就定义为大于3的)默认数组中数字为0
//竖排
for (var i = 0;i < 20;i++) {
scene[i][0] = 3; scene[i][29] = 3;
}
//横排
for (var i = 1;i < 29;i++) {
scene[0][i] = 3; scene[19][i] = 3;
}
//蛇的位置 蛇身体从4开始计 第二节为5 第三节6...以此类推,这样做是为了区分蛇身体
//避免两个身体在一起造成的识别错误
scene[10][15] = 2;
scene[10][16] = 4;
//初始化蛇头坐标
x=15; y=10;
//定义背景 根据不同操作系统/屏幕大小 的原因,有些大小需要微调.
//我这就出现了创建的JLabel比JFrame默认要大
grid = new JLabel();//背景与窗体一样大
//绘制格子 自行绘制 这里不描述了
...
//定义食物 食物固定为20 20 食物被吃掉=食物更换位置
food = new JLabel();
food.setBounds(-20,-20,20,20);//刚一开始让食物不见
//定义蛇 大小与窗口一样大 变的只是绘制的图片
snake = new JLabel();
snake.setBounds(0,0,600,400);
//需要的东西都创建好后 现在就将物体添加进JFrame
//先添加的层级最高 所以背景为最后添加
frame.add(snake); ..add(food); ..add(grid);
//给窗体添加监听 监听开始按键
frame.addKeyListener() {
...keyPr...(KeyEvent e) {
//判断按键是什么 我这用Enter 回车键来开始游戏 r键重置游戏
if (e.getKeyCode == KeyEvent.VK_ENTER) {
//已经开始游戏则不做操作 没有则开始游戏
if (!isStart) {
//开始游戏
start();
}
} else if (...==...VK_R) {
//重置就是将角色位置 场景等恢复默认 详情看源码...
reset();
}
}
}
//显示窗体
frame.setVisible(true);
}
//开始游戏
prviate void start() {
//把食物随机放到地图里 自己去随机 这里我瞎设置位置
scene[5][5] = 1;
food.setLocation(80,80);
//给frame添加监听 上下左右按键
//这里伪代码不严谨 可以去看我的源代码 但大致就是这个意思
frame...{
if ...上 {
action=2;
} else if 下 {
action=3;
} else if 左 {
action=0;
} else if 右 {
action=1;
}
}
//实时刷新游戏 这里我用Timer定时器 你也可以采用while循环+睡眠的方式
Timer t = new Timer();
//加入任务 0秒后开始 每隔200毫秒执行一次
t.sche..(new TimerTask...{
...run() {
//获取方向 进行移动一格 这里只用更改场景的位置和坐标
if 方向左 {
//判断左边是个什么东西 如果为0则代表没东西 3撞墙 1吃到食物
//撞墙则GameOver 也就是将此计时器关闭 吃到东西则给蛇身体+1
if (为撞墙) {this.cancel;return;}
if (为吃到食物) {
snakeNum++;
//刷新食物位置 也要随机 但是还要判断食物是否生成到蛇身上
//生成到蛇身上则重新生成
while (位置的值是不是等于蛇身或者蛇头);
food.setLocation(...);
scene[..][..] = 1;
}
//蛇头移动过去 并将之前的蛇头位置处理 改为-1吧 后面绘制蛇头可以知道往哪绘制
//为左边就是 x轴-1 右边就是x + 1 上边就是 y - 1 下边 y + 1 这里只列出左边
scene[y][x-1] = 2;
scene[y][x] = -1;
//将x/y改变 根据方向
x--;
} else 右边 else 上 else 下
//重新绘制蛇 我在源码里是格外做了个函数
//蛇头 根据指定x y绘制长 20 宽 20
...
//蛇身 蛇身绘制就需要一定脑子了 因为我做的算法是
//根据蛇头位置来找第一个蛇身(-1) 然后再找第二个(这次只从其他三方向找)
//先绘制第一个蛇身 定义一个蛇身标志数
int num = -1;
//定义当前绘制蛇身的坐标
int xBody = x;
int yBody = y;
//找到第一个蛇身 从上下左右四方向
if (scene[y][x-1] == -1) 绘制 改变蛇身坐标 xBody--;
else if (scene[y][x+1] == -1) 绘制 xBody++;
else if (scene[y-1][x] == -1) 绘制 yBody--;
else if (scene[y+1][x] == -1) 绘制 yBody++;
//给数改成4 因为第一节的蛇标志数是4 但是因为先移动的是蛇头...蛇头原来位置为-1
//所以我们要将标志位为4的蛇身移动到原来蛇头位置 然后5移动到4,6移动到5...
num = 4;
//在场景中设置
scene[yBody][xBody] = num;
for (int i = 0;i < snakeNum;i++) {
//这里也是一样的了 直接判断
if (scene[y][x-1] == -1) 绘制 改变蛇身坐标 xBody--;
else if (scene[y][x+1] == -1) 绘制 xBody++;
else if (scene[y-1][x] == -1) 绘制 yBody--;
else if (scene[y+1][x] == -1) 绘制 yBody++;
num++;
//在场景中设置
scene[yBody][xBody] = num;
//over 一个还算可以的贪吃蛇就弄好了 一定不要错过源码 文章最下方↓
}
}
},0,200);
}
public static void main(String[] args) {
//初始化执行构造
new Snake();
}
}
关注获取更多干货
CSDN地址:https://download.csdn.net/download/qq_41806966/12304511
GitHub地址:https://github.com/1711680493/Application/tree/master/GluttonousSnake