微信小游戏之三消(二)主要游戏控制方法

设计一个 game class。负责了游戏的核心控制逻辑,包括游戏状态管理、方块和道具的生成与效果处理,以及游戏的重新开始和复活流程。通过这些方法,脚本实现了游戏的基本玩法和用户交互。

主要游戏控制方法

  • gameStart():开始游戏,恢复所有方块状态,初始化分数管理器,设置地图。

  • mapSet(num):初始化地图,生成随机的方块布局。

  • checkNeedFall():检查是否需要下落的防抖方法。

  • onFall():方块下落的逻辑。

  • gameOver():游戏结束的逻辑,添加复活页面。

  • askRevive():处理复活请求,显示复活页面。

  • onReviveButton():复活按钮的点击事件。

  • showReviveSuccess():显示复活成功的页面。

  • onReviveCertainBtn():处理确定复活的按钮点击事件。

  • restart():重新开始游戏。

道具相关方法

  • onUserTouched(iid, jid, itemType, color, warning, pos):存储用户点击的方块信息,用于生成道具。

  • generatePropItem(type):根据类型生成道具。

  • checkGenerateProp(chain):检查并生成连锁道具效果。

  • onItem(type, color, pos):处理道具效果,如分数翻倍、炸弹消除等。

预制体实例化方法

  • generatePool():生成对象池,用于方块的实例化和回收。

  • instantiateBlock(self, data, parent, itemType, pos):实例化单个方块,初始化方块组件。

  • recoveryAllBlocks():回收所有方块节点,用于游戏重新开始或结束。

gameStart 方法是游戏开始时调用的核心逻辑,用于初始化游戏环境并启动游戏循环。以下是 gameStart 方法的逻辑分析:


/*** gameStart 方法用于启动游戏,初始化游戏环境和状态。*/
gameStart() {// 回收所有方块,准备重新开始游戏this.recoveryAllBlocks().then(() => {// 初始化分数管理器this._score.init(this);// 初始化游戏地图,设置方块布局this.mapSet(this.rowNum).then((result) => {// 游戏状态改变,更新游戏状态为开始状态(状态1)this._status = 1;});});
},

详细步骤:

  • 回收方块 (recoveryAllBlocks): 将之前游戏中使用的所有方块回收到对象池,以便重新利用,减少实例化开销。

  • 初始化分数 (_score.init): 初始化或重置分数管理器,为新游戏开始做准备。

  • 设置地图 (mapSet): 创建一个新的地图,随机生成方块,并设置它们在地图上的位置。这个方法还负责设置特殊方块类型,如道具方块。

  • 异步等待: 由于 mapSet 是异步的,使用 then 来确保在地图准备好之后再继续。

  • 状态更新: 设置 _status 为 1,这通常会在游戏循环和用户界面中用来检查游戏是否已经开始。

mapSet 方法的目的是为游戏创建一个初始状态的地图,其中包括随机分布的方块和道具,为游戏开始做好准备。通过使用 PromisesetTimeout,它能够处理异步的动画延迟,确保方块以动画形式逐一出现在游戏地图上。

// mapSet 方法用于初始化游戏地图,设置方块的布局和类型
mapSet(num) {// 初始化地图为一个 num x num 的二维数组this.map = new Array();// 保存当前对象的引用let self = this;// 生成随机数来确定特殊方块的位置let a = Math.floor(Math.random() * num);let b = Math.floor(Math.random() * num);let c = Math.floor(1 + Math.random() * (num - 1)) - 1;// 确保 c 不等于 a,以便有区分的道具位置if (a == c) c++;let d = Math.floor(Math.random() * num);// 返回一个 Promise 对象,以便在地图设置完毕后执行异步操作return new Promise((resolve, reject) => {// 遍历地图的每一行for (let i = 0; i < num; i++) {// 初始化当前行的数组this.map[i] = new Array();// 遍历地图的每一列for (let j = 0; j < num; j++) {// 根据随机坐标确定方块的类型(0为普通方块,1和2为不同类型的道具方块)let itemType = (i == a && j == b) ? 1 : (i == c && j == d) ? 2 : 0;// 调用 instantiateBlock 方法来创建方块实例self.map[i][j] = self.instantiateBlock(self, {x: j, // 列位置y: i, // 行位置width: self.blockWidth, // 根据地图宽度计算的方块宽度startTime: (i + j + 1) * self._controller.config.json.startAnimationTime / num * 2 // 计算动画开始时间}, self.blocksContainer, itemType);}}// 初始化检查管理器,准备进行方块检查this.checkMgr.init(this);// 设置一个延迟,以便于所有方块动画完成后再执行检查setTimeout(() => {// 解析 Promise,表示地图设置完成resolve('200 OK');// 执行检查函数,检查方块布局和消除情况self.checkMgr.check(self);}, self._controller.config.json.startAnimationTime * num / 2);});
}

详细步骤:

  1. 初始化地图数组:创建一个二维数组 this.map 来存储游戏地图的布局。

  2. 定义局部变量:保存对当前类的引用,以便在匿名函数中使用。

  3. 随机生成位置:生成随机坐标点,用于确定特殊方块的初始位置。

  4. 返回 Promise:使 mapSet 方法支持异步操作,以便在地图初始化完成后执行其他任务。

  5. 遍历地图位置:通过两层嵌套循环遍历地图的每一行和每一列。

  6. 确定方块类型:根据随机生成的坐标点,为每个方块分配类型(普通或道具)。

  7. 实例化方块:为每个位置创建方块实例,设置其属性,并添加到游戏地图中。

  8. 初始化检查管理器:在所有方块生成后,准备进行方块的消除检查。

  9. 设置延迟执行:使用 setTimeout 延迟执行检查函数,确保方块动画完成后再进行检查。

  10. 解析 Promise:在延迟时间结束后,解析 Promise 并执行方块检查,完成地图的初始化。

checkNeedFall 方法实现了一个防抖机制,确保方块下落的逻辑不会过于频繁地被触发,从而提高游戏性能并优化用户体验

// checkNeedFall 方法用于检查是否需要执行方块的下落动作
checkNeedFall() {// 如果 checkNeedFallTimer 已经存在,说明之前的检查尚未完成,需要清除定时器if (this.checkNeedFallTimer) {clearTimeout(this.checkNeedFallTimer);}// 设置一个新的定时器,以实现防抖功能// 防抖逻辑:在一定时间间隔(例如300毫秒)内,即使多次触发也不会连续执行下落逻辑this.checkNeedFallTimer = setTimeout(() => {// 检查游戏状态是否允许方块下落(状态为5时允许)if (this._status == 5) {// 如果状态允许,将游戏状态更新为下落状态(状态4)this._status = 4;// 调用 onFall 方法执行方块下落的逻辑this.onFall();}// 设置定时器的时间间隔为 300 毫秒,以实现防抖效果}, 300 / 1// (cc.game.getFrameRate() / 60) // 这里被注释掉的代码可能是为了适应不同的帧率);
}

详细步骤:

  1. 清除已有定时器:如果 checkNeedFallTimer 已经设置,使用 clearTimeout 清除它,避免之前的延迟操作影响当前逻辑。

  2. 定义局部变量:this 关键字引用当前对象,用于访问类的属性和方法。

  3. 设置新定时器:使用 setTimeout 创建一个新的定时器,延迟执行下落检查逻辑。

  4. 防抖逻辑:定时器的延迟时间设置为 300 毫秒,这意味着在这段时间内,无论触发多少次 checkNeedFall 方法,onFall 方法都只会执行一次。

  5. 检查游戏状态:在定时器的回调函数中,检查 _status 是否等于 5,即是否处于可以下落的状态。

  6. 更新状态为下落:如果条件满足,将 _status 更新为 4,表示方块即将开始下落。

  7. 执行下落逻辑:调用 onFall 方法,执行方块下落的逻辑。

  8. 定时器时间间隔:定时器的时间间隔可以根据游戏的帧率进行调整,以确保不同设备上都能正常工作。

onFall 方法实现了方块下落的逻辑,包括处理空格、生成新方块、执行下落动画,以及在适当的时候更新游戏状态


// onFall 方法用于处理方块下落的逻辑
onFall() {// 检查是否可以生成道具,并在完成后继续执行下落逻辑this.checkGenerateProp(this._score.chain).then(() => {let self = this; // 保存当前对象的引用let canFall = 0; // 用于记录连续空格的数量// 从每一列的最下面开始往上判断,是否有空格for (let j = this.rowNum - 1; j >= 0; j--) {canFall = 0; // 重置连续空格计数器// 从底部开始向上遍历每一列的方块for (let i = this.rowNum - 1; i >= 0; i--) {// 如果当前位置的方块状态为已消失(状态2),则进行下落处理if (this.map[i][j].getComponent('cell')._status == 2) {// 将消失的方块回收到对象池中this.blockPool.put(this.map[i][j]);// 更新地图数组,标记当前位置为空this.map[i][j] = null;canFall++; // 增加连续空格计数} else {// 如果上方有连续空格,则让当前方块下落if (canFall != 0) {// 交换当前方块与上方空格的方块this.map[i + canFall][j] = this.map[i][j];this.map[i][j] = null;// 让上方的方块下落this.map[i + canFall][j].getComponent('cell').playFallAction(canFall, {x: j,y: i + canFall,});}}}// 如果当前列有连续空格,生成新方块并让它们下落for (var k = 0; k < canFall; k++) {// 在地图数组中放置新方块的位置this.map[k][j] = this.instantiateBlock(this, {x: j,y: k,width: this.blockWidth,startTime: null}, this.blocksContainer, '', {x: j,y: -canFall + k});// 让新生成的方块执行下落动作this.map[k][j].getComponent('cell').playFallAction(canFall, null);}}// 在所有下落动作完成后,设置一个延迟,再次检查游戏状态setTimeout(() => {// 初始化检查管理器,准备进行方块检查this.checkMgr.init(this);// 执行检查函数,检查方块布局和消除情况this.checkMgr.check(this);// 更新游戏状态为可玩this._status = 1;}, 250); // 设置延迟时间,以便于动画效果完成后再执行检查});
}

详细步骤:

  1. 检查生成道具:调用 checkGenerateProp 方法检查是否可以生成道具,并等待其完成后继续。

  2. 保存引用:保存当前对象的引用,以便在匿名函数中使用。

  3. 初始化空格计数器:canFall 用于记录连续的空格数量。

  4. 遍历列:从地图的最底部开始,向上遍历每一列。

  5. 重置空格计数器:在遍历每一列时重置 canFall

  6. 遍历行:在每一列内部,从底部向上遍历每一行。

  7. 方块下落处理:

    • 如果当前方块已经消失(状态为2),则将其回收并标记地图数组中相应位置为空。

    • 如果上方有空格,让当前方块下落。

  8. 生成新方块:如果有连续空格,生成新方块并让它们下落。

  9. 执行下落动作:调用 playFallAction 方法让方块执行下落动画。

  10. 设置延迟:在所有下落动作完成后,使用 setTimeout 设置延迟。

  11. 再次检查状态:延迟结束后,初始化检查管理器并执行检查函数,更新游戏状态。

更多详细代码逻辑请看:微信小游戏之三消(二)主要游戏控制方法代码逻辑分享 (qq.com)icon-default.png?t=N7T8https://mp.weixin.qq.com/s?__biz=MzI0NTE3ODY5Mg==&mid=2247483770&idx=1&sn=721d6cb02baf8d2345870e924598e094&chksm=e953c951de24404768866f4c01a3e97f4cda185fe4f4a1cba84c8b98fc76303de832f66c3ebb&token=1281952290&lang=zh_CN#rd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java学习Day16:基础篇6

1.静态和非静态 2.调用静态和非静态的过程 注&#xff1a;在Java中&#xff0c;同类中&#xff0c;确实可以使用类的对象来调用静态方法&#xff0c;尽管这不是推荐的做法。静态方法属于类本身&#xff0c;而不是类的任何特定实例。因此&#xff0c;理论上讲&#xff0c;你应该…

设备树作业7月29日

demo.c #include <linux/init.h> #include <linux/module.h> #include <linux/of.h>struct device_node* node; struct property* property; /* mynode0x12345678{ //mynode节点名字mystring "hello DC24031";//字符串属性myint <0x12 0x34 …

【iOS】—— KVO与KVC

KVO与KVC 1. KVOKVO底层实现分析如何验证上面的说法&#xff1a;NSKVONotifyin_Person内部结构didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法 回答问题&#xff1a; 2. KVC简介&#xff1a;key和keyPath的区别key&#xff1a…

“支付”到“智付” 数字人民币场景加速落地

在全球化浪潮的推动下&#xff0c;跨境电商如雨后春笋般涌现&#xff0c;它们跨越国界&#xff0c;将商品和服务直接送达消费者手中。然而&#xff0c;当外国的跨境电商希望进入中国市场时&#xff0c;他们面临着一个共同的挑战&#xff1a;如何合法合规地从中国用户手中收取款…

探索 Electron:如何进行网址收藏并无缝收录网页图片内容?

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

EtherNet/IP转CAN协议转化网关(功能与配置)

怎么样把EtherNet/IP和CAN两个协议连接起来?有很多朋友想要了解这个问题&#xff0c;那么作者在这里统一说明一下。其实有一个不错的设备产品可以很轻易地解决这个问题&#xff0c;名为JM-EIP-ECAT网关。接下来作者就从该设备的功能及配置详细说明一下。 一&#xff0c;设备主…

Angular 遍历列表时的key

在Angular中&#xff0c;你可以使用keyvalue管道来遍历对象的键。这里是一个简单的例子&#xff0c;展示了如何在Angular模板中使用它&#xff1a; <div *ngFor"let key of myObject | keyvalue:key">Key: {{ key }} - Value: {{ myObject[key] }} </div&g…

springboot中hutool-core依赖的使用

springboot中hutool-core依赖的使用 依赖安装1、StrUtil.isBlank() 依赖安装 <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><ver…

在Android开发中,如何优化onCreate()和onResume()方法以提高应用性能?

在Android开发中&#xff0c;onCreate()和onResume()方法是活动生命周期中非常重要的两个回调方法&#xff0c;它们分别在活动创建和重新获得焦点时被调用。为了提高应用的性能&#xff0c;以下是一些优化这两个方法的策略&#xff1a; 对于onCreate()方法的优化&#xff1a; …

聊聊基于Alink库的主成分分析(PCA)

概述 主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09;是一种常用的数据降维和特征提取技术&#xff0c;用于将高维数据转换为低维的特征空间。其目标是通过线性变换将原始特征转化为一组新的互相无关的变量&#xff0c;这些新变量称为主成分&…

TinyMCE一些问题

1.element 在el-dialog中使用tinymce导致富文本弹窗在el-dialog后面的问题 原因是富文本的弹窗层级太低了 在APP.vue中添加样式即可解决 /* 富文本菜单 */ .tox-tinymce-aux {z-index: 9999 !important; }2.element 在el-dialog中点击富文本的功能栏报错 由于 aria-hidden 属…

Midjourney、Sora和硅谷机密-《分析模式》漫谈15

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的Preface&#xff08;前言&#xff09;有这么一句&#xff1a; Kent Beck, Ward Cunningham, and Jim Coplein encouraged me to get involved with the commu…

虚假的互联网信息?不妨从IT的角度理解【景观社会】

博主前言&#xff1a;“我思故我在”&#xff0c;笛卡尔的这一哲学命题&#xff0c;大抵上次还比较熟络的时光还是高中亦或复习考研政治的岁月里。这是一个光怪陆离的社会——或者说网络社会&#xff0c;形形色色的消息充斥在脑海之时&#xff0c;你是否还能认识真正的自己&…

YOLOV8-源码解读-SPP-SPPF

先给出YOLOV8中一键三连卷积模块 def autopad(k, pNone, d1): # kernel, padding, dilation"""Pad to same shape outputs."""if d > 1:k d * (k - 1) 1 if isinstance(k, int) else [d * (x - 1) 1 for x in k] # actual kernel-sizeif…

全国区块链职业技能大赛样题第9套智能合约+数据库表设计

后端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746050 前端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746216 智能合约+数据库表设计:https://blog.csdn.net/Qhx20040819/article/details/140746646 nice.sql /* Navicat MySQ…

分布式事务解决方案(一) 2PC、3PC、TCC、Sega

目录 1.绪论 2.2PC 2.1 基本原理 2.1.1 组成 2.1.2 步骤 1.prepare阶段 2.commit阶段 2.2 2PC 存在的问题 2.2.1 阻塞问题 2.2.2 单点故障问题 1. 事务协调器宕机 2.部分数据不一致问题 2.资源管理器宕机 3. 事务协调器和资源管理管理器同时宕机 2.2 实现 2.2.1…

怎么将几个pdf合成为一个pdf?pdf合成为一个的常用方法

在现代的职场和学术环境中&#xff0c;如何将多个独立的PDF文档合并成一个统一的文件已经成为提高工作效率、优化文档管理和促进信息共享的重要手段。PDF格式以其卓越的跨平台兼容性、强大的数据保护能力以及清晰易读的版面设计&#xff0c;在全球范围内得到了广泛的应用和认可…

2-45 基于matlab的递归最小二乘法(RLS)对声音信号去噪

基于matlab的递归最小二乘法&#xff08;RLS&#xff09;对声音信号去噪,并对消噪前后的信号进行FFT分析&#xff0c;对比消噪前后的效果。可替换自己的声音信号进行分析。程序已调通&#xff0c;可直接运行。 2-45 递归最小二乘法&#xff08;RLS&#xff09; FFT分析 - 小红书…

系统移植(七)u-boot移植 ④ trusted版本

文章目录 一、U-boot源码适配&#xff08;一&#xff09;执行make stm32mp15_trusted_defconfig命令进行配置&#xff0c;生成.config文件&#xff08;二&#xff09;执行make menuconfig命令&#xff0c;对u-boot源码进行重新配置1. 对u-boot源码进行配置&#xff0c;移除pmic…