0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

玩嗨OpenHarmony:基于OpenHarmony的贪吃蛇小游戏

共熵服务中心 来源:未知 2022-11-28 20:50 次阅读
51CTO 开源基础软件社区 #夏日挑战赛# 《OpenHarmony基于JS实现的贪吃蛇

1. 项目简介

贪吃蛇是一款非常经典的小游戏,概念起源于1976年由美国一家街机游戏Blockade(参见下图),后来经过无数次迭代,在1998年,成为诺基亚手机预装的小游戏,相信也能激起很多人的回忆。这次,我将在OpenHarmony操作系统基础上通过JS来实现贪吃蛇。

最终,我必须承认,自己做的贪吃蛇,却被自己菜哭了,自己写的贪吃蛇自己都不会玩(ps:我曾经可是在不会死亡的情况下完了好长时间>_<)。实现的效果如下:

基本实现思路
贪吃蛇的基本操作规则是:玩家操控一条细长的直线(俗称蛇或虫,起始可能是一个点),它会不停前进,玩家只能操控蛇的头部朝向(上下左右),蛇身体后面的部分会跟随头部移动的轨迹。头一路拾起触碰到之食物(或称作“豆”/“果”),并要避免触碰到自身或者其他障碍物(包括游戏界面的边界墙壁)。每次贪吃蛇吃掉一件食物,它的身体便增长一节。吃掉一些食物后会使蛇的移动速度逐渐加快,让游戏的难度渐渐变大。
要实现以上的要求,有几个关键点需要考虑:
  • 要有个游戏的容器空间设计
  • 定义蛇的身体

  • 要随机生成食物

  • 要人工控制蛇的移动

  • 吃掉食物身体变长

  • 撞到障碍物(包括自身)会死亡,游戏重启或结束

下面就针对以上情况来分别描述。

参数属性:

名称类型备注
resultnumber分数
conWnumber容器宽度
conHnumber容器高度
snakeBodynumber蛇身体单位
hnumber网格的y长度
wnumber网格的x长度
gridArray网格地图
foodobject食物
timeIdnumber定时器id
levelnumber游戏难度级别
desObject蛇的四个方向
isStartBoolean判断是否开始
snakeObject
currDesobject当前蛇前进的方向
isEndPBoolean判断游戏是否结

函数咯列表:

名称参数备注
init初始化函数
onShow框架生命周期钩子函数
isEndnewHead : object判断游戏是否结束
setIsEnd设置游戏结束相关数据
randomFood随机生成食物
addHeaddes : object增加新头
movedes : object蛇的移动
intervalMoved :object蛇自动移动
isCuurDesvalue:object ,x1:string,x2:string定时器id
clickButm:object操作蛇的移动的点击事件
reInit重新开始游戏
容器初始化

在onShow钩子函数那里获取到游戏容器的宽高,其实我是不想在这里获取的,但没办法,好像getBoundingClientRect()需要挂载后才能拿到值,在这之前的钩子函数中都拿不到具体的属性值。

拿到容器宽高后,根据蛇的身体长度(就是每个小圆点)来确定要划分多少个格子,形成一个坐标轴,后面食物,蛇的移动都根据这坐标轴来确定。

  onShow(){ // 第一次初始化
this.conH = this.$refs["con"].getBoundingClientRect().height ;
this.conW = this.$refs["con"].getBoundingClientRect().width ;
this.h = Math.floor(this.conH / this.snakeBody);
this.w = Math.floor(this.conW / this.snakeBody);
for (var i = 0; i < this.w; i++) { //绘制网格
this.grid.push([])
for (var j = 0; j < this.h; j++) {
this.grid[i].push({
x: i,
y: j
});
}
}
this.init(); //初始化函数


}

用一个数组实现,数组索引0为蛇的尾巴,索引length-1为头。

 init(){
const snakePos = [ //蛇的初始化的身体
{
x : 0,
y : 0,
flag : 'b',
id : Math.random()
},
{
x : 1,
y : 0,
flag : 'b',
id : Math.random()
},
{
x : 2,
y : 0,
flag : 'h',
id : Math.random()
}
];
this.snake.snakePos = snakePos; //把初始化的身体赋给蛇
this.randomFood(); //随机生成食物
}
食物

食物随机生成,位置在网格中任意位置,但不能生成在蛇的身体位置中。

 randomFood(){ //随机生成食物
while(true){
let x = Math.floor(Math.random() * this.conW);
let y = Math.floor(Math.random() * this.conH);
x = x - (x % this.snakeBody); //x,y化为和蛇身体倍数的坐标
y = y - (y % this.snakeBody);
let is = this.snake.snakePos.find((item)=>{
return item.x == x && item.y == y;
})
this.food.x = x;
this.food.y = y;
if(!is) { //当食物的位置不为蛇不和蛇的位置重叠就跳出结束死循环
break;
}
}
}
蛇的移动

蛇的移动是通过对数组的push和shift实现,蛇有移动的方向,根据方向来修改新增蛇头的x和y的值。移动图如下:

des:{//蛇的方向
"-20":{ // 向上移动一位
x:0,
y:-1,
flag: ''
},
"20":{//向下
x:0,
y:1,
flag: ''
},
"10":{ //右
x:1,
y:0,
flag: ''
},
"-10":{ //左
x:-1,
y:0,
flag: ''
}
},
addHead(des){
//添加蛇头 des为蛇的方向,一共有四个方向上下左右,每次移动是都会传一个方向过来
const oHead = this.snake.snakePos[this.snake.snakePos.length -1];
const newHead ={
x : oHead.x + des.x,
y : oHead.y + des.y,
flag : 'h',
id : Math.random()
}
this.isEnd(newHead);
this.snake.snakePos.push(newHead);


oHead.flag = 'b';
},
move(des){ // 蛇移动时,原头变身体,原尾巴去掉,也就是push一个头,shift一个尾巴
this.addHead(des);
this.snake.snakePos.shift();


},
蛇的死亡判定

当蛇头的x >= 地图的x最大值 || x < 0 || 蛇头的Y >= 地图的Y最大值 || Y < 0 || 蛇头的(x,y) == 蛇身体任意一个 (x,y)。

isEnd(newHead){//判定蛇是是否死亡
if(newHead.x >= this.w || newHead.x < 0 || newHead.y >= this.h || newHead.y < 0){
this.setIsEnd();
}


let is = this.snake.snakePos.find((item)=>{ //循环查询是否撞到自己
return item.x == newHead.x && item.y == newHead.y;
})
if(is){
this.setIsEnd(); //结束游戏
}
},
setIsEnd(){
clearInterval(this.timeId); //清除蛇的移动定时器
this.isEndP = true; //这个属性是用来是否显示游戏结果界面
}
操作蛇的移动

-20,20,10,-10,原本是一开用来判定是否当前移动的方向是否和原来的方向冲突,后来发现还是用坐标轴香,也就懒得改了。

    intervalMove(d){ // 自动跑
if(!this.isStart) return;//判定是否开始
clearInterval(this.timeId); //清除以前的定时时器
this.timeId = setInterval(()=>{
const head = this.snake.snakePos[this.snake.snakePos.length - 1];
this.move(d);
if(this.snakeBody * head.x == this.food.x && this.food.y == this.snakeBody * head.y ){ //蛇吃到食物
this.addHead(d); //新增蛇头,这个不去除尾巴
this.randomFood(); //再次重新生成食物
this.result++; //分数
}
},1000/this.level); //this.level级别,决定蛇移动的速度
},
isCuurDes(value = '',x1,x2){
// 判断当前蛇的方向,x1 为新方向,x2为以前的方向,主要是判断点击的按钮是否左右,上下冲突
if((+x1 + +x2) == 0 ) return false; //这里+x1,+x2 是用来把字符串转成数字
if(this.isEndP) return;//当游戏结束无法再修改方向
this.currDes = value; //存下方向
return true;
},
clickBut(m){// 点击按钮
const value = m.target.dataSet.value;
switch(value){
case "-20":{ //上
//判断方向是否相反,如果相反则不切换方向
this.isCuurDes(this.des[value],this.des[value].y,this.currDes.y)
&& this.intervalMove(this.des[value]);
break;
}
case "20":{// 下
this.isCuurDes(this.des[value],this.des[value].y,this.currDes.y)
&& this.intervalMove(this.des[value]);
break;
}
case "-10":{ //左
this.isCuurDes(this.des[value],this.des[value].x,this.currDes.x)
&& this.intervalMove(this.des[value]);
break;
}
case "10":{ // 右
this.isCuurDes(this.des[value],this.des[value].x,this.currDes.x)
&& this.intervalMove(this.des[value]);
break;
}
case "1": { //开始或暂停
if(this.isEndP) return
this.isStart = !this.isStart;
if(this.isStart && !this.isEndP){
this.intervalMove(this.currDes);
}else{
clearInterval(this.timeId);
}
break;
}
}
}
本文完
写在最后
我们最近正带着大家玩嗨OpenHarmony。如果你有好玩的东东,欢迎投稿,让我们一起嗨起来!有点子,有想法,有Demo,立刻联系我们:
合作邮箱:zzliang@atomsource.org




原文标题:玩嗨OpenHarmony:基于OpenHarmony的贪吃蛇小游戏

文章出处:【微信公众号:开源技术服务中心】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 开源技术
    +关注

    关注

    0

    文章

    386

    浏览量

    7835
  • OpenHarmony
    +关注

    关注

    23

    文章

    3328

    浏览量

    15172

原文标题:玩嗨OpenHarmony:基于OpenHarmony的贪吃蛇小游戏

文章出处:【微信号:开源技术服务中心,微信公众号:共熵服务中心】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    OpenHarmony南向开发实例:【游戏手柄】

    基于TS扩展的声明式开发范式编程语言,以及OpenHarmony的分布式能力实现的一个手柄游戏
    的头像 发表于 04-17 10:21 413次阅读
    <b class='flag-5'>OpenHarmony</b>南向开发实例:【<b class='flag-5'>游戏</b>手柄】

    浅谈兼容 OpenHarmony 的 Flutter

    OpenHarmony SIG 组织在 Gitee 开源了兼容 OpenHarmony 的 Flutter。该组织主要用于孵化 OpenHarmony 相关的开源生态项目。     ▲ 仓库地址
    的头像 发表于 02-02 15:22 253次阅读
    浅谈兼容 <b class='flag-5'>OpenHarmony</b> 的 Flutter

    基于51单片机的贪吃蛇设计

    电子发烧友网站提供《基于51单片机的贪吃蛇设计.rar》资料免费下载
    发表于 01-12 09:53 2次下载

    基于51单片机的贪吃蛇设计

    电子发烧友网站提供《基于51单片机的贪吃蛇设计.rar》资料免费下载
    发表于 01-03 10:26 0次下载

    基于51单片机的贪吃蛇游戏设计

    基于51单片机的贪吃蛇游戏设计(仿真+实物)
    发表于 01-02 09:38 2次下载

    OpenHarmony技术大会 | OpenHarmony技术俱乐部分论坛嘉宾金句

    点击蓝字 ╳ 关注我们 开源项目 OpenHarmony 是每个人的 OpenHarmony 原文标题:OpenHarmony技术大会 | OpenHarmony技术俱乐部分论坛嘉宾金
    的头像 发表于 11-10 20:25 266次阅读

    基于51单片机的贪吃蛇游戏设计

    电子发烧友网站提供《基于51单片机的贪吃蛇游戏设计.pdf》资料免费下载
    发表于 10-25 10:38 2次下载
    基于51单片机的<b class='flag-5'>贪吃蛇</b><b class='flag-5'>游戏</b>设计

    Unity中国、Cocos为OpenHarmony游戏生态插上腾飞的翅膀

    2023年是OpenHarmony游戏生态百花齐放的一年!为了扩展OpenHarmony游戏生态,OpenHarmony在基金会成立了
    发表于 10-23 16:15

    开鸿智谷亮相OpenHarmony Meetup深圳站!

    开源项目OpenHarmony是每个人的OpenHarmonyOpenHarmony正当时”OpenHarmonyMeetup2023城市巡回活动,旨在通过meetup线下交流形式,
    的头像 发表于 10-18 08:30 426次阅读
    开鸿智谷亮相<b class='flag-5'>OpenHarmony</b> Meetup深圳站!

    基于FPGA的贪吃蛇小游戏实现案例

    手机游戏时代始于 1997 年,当时诺基亚在 6110 机型上发布了第一款名为〈贪吃蛇〉的手机游戏。这可能是有史以来最受欢迎的手机游戏之一,全球有超过 3.5 亿部手机提供这款
    发表于 09-08 09:32 750次阅读
    基于FPGA的<b class='flag-5'>贪吃蛇</b><b class='flag-5'>小游戏</b>实现案例

    如何利用星火一号开发板制作贪吃蛇小游戏

    刚拿到星火一号板子想搞事情,逛论坛发现 @zym_0208 发布了一个贪吃蛇的demo,于是下载下来玩了一下发现有些许bug,于是我在他的基础上修改了一半,且把逻辑优化了一下
    的头像 发表于 08-28 17:04 744次阅读

    OpenHarmony轻量系统书籍推荐《OpenHarmony轻量设备开发理论与实战》

    最近大家问的智能家居套件方面有没有可以参考的资料,这里给大家统一回复一下 推荐大家可以看这本书 《OpenHarmony轻量设备开发理论与实战》 本书系统地讲授OpenHarmony 轻量系统 设备
    的头像 发表于 07-20 12:43 675次阅读

    通过C语言设计的贪吃蛇游戏(控制台终端)

    当前通过控制台终端实现一个贪吃蛇小游戏,实现游戏的绘制、更新、控制等功能。
    的头像 发表于 06-30 09:53 518次阅读
    通过C语言设计的<b class='flag-5'>贪吃蛇</b><b class='flag-5'>游戏</b>(控制台终端)

    micro:bit贪吃蛇游戏开源分享

    电子发烧友网站提供《micro:bit贪吃蛇游戏开源分享.zip》资料免费下载
    发表于 06-13 10:58 2次下载
    micro:bit<b class='flag-5'>贪吃蛇</b><b class='flag-5'>游戏</b>开源分享

    基于JAVA的J2ME的手机游戏(贪吃蛇)开发设计

    的通信等功能,而且能够开发各种手机游戏。本文在介绍J2ME及其体系结构的基础上,以贪吃蛇游戏为实例,描述了借助J2ME的MIDlet类库开发手机游戏的过程。
    发表于 06-09 16:04 0次下载