贪吃蛇小项目(已更)
作为软件学院的学生,主要攻读Java后端开发,前端知识有些欠缺,因此对此次的贪吃蛇项目(JS)一拖再拖,但是对于鸿蒙贪吃蛇还是很有兴趣,因此综合官方资料和各个大佬的博客等文章分享,成功做了此次流程,不是很全面,但是基本上能够实现。
Copy一下代码,一小时内也能运行,适合新手接触鸿蒙,想做一个有意思的小项目的朋友们。欢迎大家点赞收藏,支持~
项目运行
如图

系统:Win11 DevEco Studio 3.0.0.800
正式开始
一、创建项目
1.选择JS模板

2.项目名、包名

3.目录如下
创建完成

二、编程
1.导入图片作为控件按钮

2.编写前端页面
2.1 HTML
先定义好标签、、内容与资源,编写完成后查看效果如何
代码带入后(先登录),点击侧边栏 Previewer

效果如下,看一眼杂乱无章的样子,不过运行主要是确保样式和资源进行了加载:

2.2 CSS
编写CSS代码
需要先调整样式,在需要调整的样式后加对应的类名class=‘’‘’,通过类名进行css的调用
设置好类名后,在index.css文件中根据类名编写css
再次测试,发现有了变化,不过按钮过大,需要处理

2.3 优化按钮
根据人体美学设计,设置好按键。在html中用div给按键打一个包,再定义一个新属性即可。
css添加部分新代码
再次测试,如图
由此可见,外壳做的差不多了,游戏初具雏形,就差小蛇和食物了。重点也就要来了。
3.编写JS代码
3.1 设计思路
3.1.1 通过点击按钮实现贪吃蛇的移动,需要点击事件
鼠标点击事件是对应的方法,通过传参不同来区分不同的方向。
3.1.2 食物
随机生成。
if食物位置与蛇身体重合,则重新生成
3.1.3 蛇身初始化
通过for循环,将x,y坐标push进数组,作为蛇身体每格的位置(这里进行了固定位置生成,并将蛇身长度定为5格为初始长度)
3.1.4 蛇的运动
蛇的移动是对每一帧进行重制,吃到水果就把头部加长,没吃到就去掉尾部,并将头部方向指向下一个位置记录到数组头部,等待下次刷新帧。
3.1.5 游戏结束和重启
碰壁、相反方向移动,形成了环结束游戏
游戏结束后重新点击移动按键,即可重新开始游戏
3.2 UML图等
流程图

类图

逻辑图解

3.3 JS代码及注释
export default {
data: {
title: "",
snakeSize: 30,
w: 600,
h: 600,
score: 0,
snake : [],
ctx: null,
food: null,
direction: '',
gameOver: false,
tail: {
x: 0,
y: 0
},
interval : null
},
onInit() {
this.title = this.$t('strings.world');
},
onShow() {
const canvas = this.$refs.canvasref;
this.ctx = canvas.getContext("2d");
this.direction = 'down';
this.drawSnake()
this.createFood()
this.paint()
},
drawArea() {
var ctx = this.ctx
ctx.fillStyle = '#61c7e6';
ctx.fillRect(0, 0, this.w, this.h);
ctx.strokeStyle = '#00000';
ctx.lineWidth = 5;
ctx.strokeRect(0, 0, this.w, this.h);
this.ctx = ctx
},
drawSnake() {
var len = 5;
var snake = [];
for (var i = len - 1; i >= 0; i--) {
snake.push({
x: 0,
y: i
});
}
this.snake = snake;
},
bodySnake(x, y) {
var ctx = this.ctx;
ctx.fillStyle = '#99cc33';
ctx.fillRect(x * this.snakeSize, y * this.snakeSize, this.snakeSize, this.snakeSize);
ctx.strokeStyle = '#063970';
ctx.strokeRect(x * this.snakeSize, y * this.snakeSize, this.snakeSize, this.snakeSize);
this.ctx = ctx;
},
cookie(x, y) {
var ctx = this.ctx;
ctx.fillStyle = '#ff0033';
ctx.fillRect(x * this.snakeSize, y * this.snakeSize, this.snakeSize, this.snakeSize);
this.ctx = ctx;
},
createFood() {
this.food = {
x: Math.floor((Math.random() * 20) + 1),
y: Math.floor((Math.random() * 20) + 1)
}
for (var i = 0; i > this.snake.length; i++) {
var snakeX = this.snake[i].x;
var snakeY = this.snake[i].y;
if (this.food.x === snakeX && this.food.y === snakeY || this.food.y === snakeY && this.food.x === snakeX) {
this.food.x = Math.floor((Math.random() * 20) + 1);
this.food.y = Math.floor((Math.random() * 20) + 1);
}
}
},
checkCollision(x, y, array) {
for(var i = 0; i < array.length; i++) {
if(array[i].x === x && array[i].y === y)
return true;
}
return false;
},
onStartGame(direct){
this.gameOver = false
if (direct == 1) {
this.direction = 'up'
} else if (direct == 2) {
this.direction = 'left'
} else if (direct == 3) {
this.direction = 'down'
} else if (direct == 4) {
this.direction = 'right'
}
this.paint()
if (this.interval == null) {
this.interval = setInterval(this.paint, 250);
}
},
paint() {
this.drawArea()
var snakeX = this.snake[0].x;
var snakeY = this.snake[0].y;
if (this.direction == 'right') {
snakeX++;
}
else if (this.direction == 'left') {
snakeX--;
}
else if (this.direction == 'up') {
snakeY--;
} else if (this.direction == 'down') {
snakeY++;
}
if (snakeX == -1 || snakeX == this.w / this.snakeSize || snakeY == -1 || snakeY == this.h / this.snakeSize || this.checkCollision(snakeX, snakeY, this.snake)) {
clearInterval(this.interval);
this.interval = null
this.restart()
return;
}
if(snakeX == this.food.x && snakeY == this.food.y) {
this.tail = {x: snakeX, y: snakeY};
this.score = this.score+5;
this.createFood();
} else {
this.tail = this.snake.pop();
this.tail.x = snakeX;
this.tail.y = snakeY;
}
this.snake.unshift(this.tail);
for(var i = 0; i < this.snake.length; i++) {
this.bodySnake(this.snake[i].x, this.snake[i].y);
}
this.cookie(this.food.x, this.food.y);
},
restart() {
this.drawArea()
this.drawSnake()
this.createFood()
this.gameOver = true
this.score = 0
},
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
4.简单测试

虚拟机运行

总结
感谢大家能够读到这里,第一次写JS的代码,和Java确实不太一样,本帖子也没对JS代码详细解释,只有一些必要的注释,里面有很多嵌套调用,文字加图片的格式还是很难解释清楚。对此我们加了类图和流程图,以及逻辑图,便于大家理解。不足之处还望理解。
引用
HarmonyOS开发者/重铸经典,如何在HarmonyOS手机上还原贪吃蛇游戏
源码修改后附上(= ̄ω ̄=)喵了个咪
get!٩( ‘ω’ )و
赞,期待楼主后续
有趣,期待后续。
感谢支持,已更
感谢支持,已更新