政安晨【示例演绎虚拟世界开发】(六):从制作一个对战小游戏开始(Cocos Creator 《击败老大》)(第三段)

在上一篇文章中,我们已经将游戏的场景基本搭建完毕,接下来我们就可以为游戏编写代码并实现相关的核心逻辑了。

政安晨的个人主页:政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏: AI虚拟世界大讲堂

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!


使用计时器

在游戏开始后,敌人的招式图片会随机变化

为了实现这一效果,我们可以每隔一段时间随机地显示三个招式的任意一个,并隐藏其余两个,从而实现招式不停变化的效果。

在Cocos Creator中,如果想要每隔一段时间触发一些行为,则可以使用计时器函数来实现

我们可以通过计时器在固定的时间间隔重复执行某个行为,只需要在计时器的回调中将enemy_skill子节点进行随机显示与隐藏即可。

在资源管理器的scripts文件夹下创建Game脚本,然后将脚本挂载到Canvas节点上:

接着对Game脚本进行编写,代码如下:

import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;@ccclass('Game')
export class Game extends Component {@property({ type: Node})private enemySkillNode: Node = null; // 绑定 enemy_skill 节点// 声明属性 children 的 cc 类型为 Node 数组@property({ type: [Node] })private children: Node[] = [];private enemyAttackType = 0; // 敌人招式 0: 弓箭, 1: 流星锤, 2:盾牌private timer = null; // 计时器start() {// 启动计时器, 每 0.1s 执行一次this.timer = setInterval(() => {this.randEnemyAttack();}, 100);}// 敌人的随机招式randEnemyAttack() {this.enemyAttackType = Math.floor(Math.random() * 3); // 给敌人随机招式0~2let allchildren = this.node.children; // 获取enemySkillNode下的所有子节点allchildren.forEach(childNode => {// 如果节点名字与随机招式的编号一致则显示, 否则将节点进行隐藏if (childNode.name == this.enemyAttackType.toString()) {childNode.active = true;}else{childNode.active = false;}});}update(deltaTime: number) {}
}

脚本编写完成后,在属性检查器中将enemy_skill节点绑定到脚本上:

之后预览运行,此时敌人的招式图标已经可以随机变化了:

为了理解上面的代码,咱们这里再补充一下箭头函数的说明:

TypeScript是一种JavaScript的超集,在JavaScript的基础上添加了静态类型、类、模块等特性。箭头函数是TypeScript中的一种函数定义方式,它使用了箭头“=>”来表示函数的定义。

箭头函数的语法格式为:(参数列表) => 表达式或语句

其中,参数列表可以为空也可以包含一个或多个参数,多个参数之间使用逗号分隔。

表达式或语句可以是单个表达式或多个语句,如果是单个表达式,可以省略大括号{}和return关键字,直接返回表达式的结果。如果是多个语句,需要使用大括号{}将语句块包裹起来,并使用return关键字返回结果。

箭头函数的特点是可以继承当前上下文的this关键字,而不会创建一个新的this。这意味着在箭头函数中,this的值与包含它的函数相同。

以下是几个箭头函数的示例:

  1. 空参数的箭头函数: () => console.log("Hello, world!");

  2. 单个参数的箭头函数: (name) => console.log("Hello, " + name);

  3. 多个参数的箭头函数: (name, age) => console.log("Hello, " + name + ". You are " + age + " years old.");

  4. 箭头函数返回单个表达式的结果: (a, b) => a + b;

  5. 箭头函数返回多个语句的结果: (a, b) => { let sum = a + b; console.log(sum); return sum; }

箭头函数的使用使得函数的定义更加简洁和清晰,并且在处理this关键字的问题上更加方便。因此,在TypeScript中,箭头函数被广泛应用于编写可读性更高的代码。

好,现在咱们接着上面的例子:

在上面的代码中我们使用了计时器setInterval的方法,该方法会按照固定的周期(单位为毫秒)不停地调用randEnemyAttack函数,直到clearInterval被调用。同时,由setInterval返回的id值可以作为clearInterval的参数,因此我们事先定义了timer变量对其进行存储,以便后续进行相关处理。

使用Button组件

现在敌人已经可以进行随机出招了,接下来就需要为游戏添加相应的点击交互效果了。

在游戏中,我们希望在玩家点击三个技能中的任意一个后,由系统选定该招式为我方出招,同时使用选定的招式与敌人当前的招式进行比拼。

为了实现这一效果,我们需要在玩家点击任意一个招式时,触发事先编写的逻辑代码。在通常情况下,我们可以通过Button组件来实现这种交互效果

同时,为了给Button添加相应的响应函数事件,我们还需要在Game脚本中添加如下代码

(在Game脚本中增加如下代码,在类里添加,小伙伴们自己做一下)

    @property({ type: Label})private hintLabel: Label = null; // 绑定 hint 节点// 出招按钮响应函数attack (event, customEventData){if (! this.timer){return;}clearInterval(this.timer);this.timer = null;let pkRes = 0; //0: 平, 1:赢, -1:输let attackType = event.target.name; // 获取目标节点的nameif (attackType == 0){if (this.enemyAttackType == 0) {pkRes = 0;}else if (this.enemyAttackType == 1) {pkRes = 1;} else if (this.enemyAttackType == 2) {pkRes = -1;}} else if (attackType == 1) {if (this.enemyAttackType == 0){pkRes = -1;}else if (this.enemyAttackType == 1) {pkRes = 0;}else if (this.enemyAttackType == 2) {pkRes = 1;}}else if (attackType == 2) {if (this.enemyAttackType == 0){pkRes = 1;}else if (this.enemyAttackType == 1) {pkRes = -1;}else if (this.enemyAttackType == 2) {pkRes = 0;}}if (pkRes == -1) {this.hintLabel.string = '失败';}else if (pkRes == 1) {this.hintLabel.string = '胜利';}else{this.hintLabel.string = '平局';}}

代码添加完成后,在属性检查器中将hint节点绑定到脚本上。

之后需要依次为技能图标添加Button组件。

此处以弓箭图标为例,在层级管理器中选中弓箭图标节点,选择【添加组件】→【UI】→【Button】命令,即可为节点添加Button组件,如下图所示。

Button组件的相关属性如下表所示。

ClickEvents添加参数1后可以在展开项中看到下表所示的属性:

接着将组件的【Transition】属性修改为【SCALE】,同时为【ClickEvents】绑定【Game】脚本中的【attack】函数,并将【CustomEventData】的值修改为代表弓箭图标的编号【0】,如下图所示。

添加“重新开始”功能

现在我们的游戏已经可以玩起来了,不过每次结束比拼后就不可以继续进行游戏了,因此需要为游戏的【重新开始】按钮实现对应的逻辑功能。可以直接使用loadScene函数对Game场景进行加载,实现“重新开局”的效果。

为Game脚本添加如下代码:

    // 重新加载场景restart(){director.loadScene('Game');}

为场景右上角的【重新开始】按钮绑定restart函数,即可实现重新开始的功能了。这里需要注意的是,使用loadScene加载的场景名是区分大小写的,如果加载的场景名不一致或者不存在,则无法进行加载。


咱们这个游戏先告一段落,简单讲解了一下思路,接下来咱们用真正可以使用的例子继续学习。

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

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

相关文章

基于NB-IoT的西红柿基地温湿度监测系统

总体硬件架构 在西红柿种植园内,我们为每株作物分配RFID标签,以便在每次照顾作物后记录其生长状况、施肥和灌溉等信息。这些数据将上传至云端,便于用户在线实时监控作物生长情况。 为了确保温湿度的精确控制,我们在作物棚内每隔3米…

appium2的一些配置

appium-desktop不再维护之后,需要使用appium2。 1、安装appium2 命令行输入npm i -g appium。安装之后输入appium或者appium-server即可启动appium 2、安装安卓/ios的驱动 安卓:appium driver install uiautomator2 iOS:appium driver i…

算法沉淀——贪心算法一(leetcode真题剖析)

算法沉淀——贪心算法一 01.柠檬水找零02.将数组和减半的最少操作次数03.最大数04.摆动序列 贪心算法(Greedy Algorithm)是一种基于贪心策略的优化算法,它通常用于求解最优化问题,每一步都选择当前状态下的最优解,以期…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TapGesture)

支持单击、双击和多次点击事件的识别。 说明: 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 接口 TapGesture(value?: { count?: number, fingers?: number }) 参数: 参数名称参数类型必填参…

sql多表运用 12.3

肖SIR__数据库之多表运用__12.3 数据库之多表运用 CREATE table dept(dept1 VARCHAR(6),dept_name VARCHAR(20)) default charsetutf8; INSERT into dept VALUES (101,财务); INSERT into dept VALUES (102,销售); INSERT into dept VALUES (103,IT技术); INSERT into dep…

前端工具网站合集(持续更新)

综合类网站 那些免费的砖 统计推荐免费工具网站 那些免费的砖 - 优雅地白嫖各种免费资源 (thosefree.com)https://www.thosefree.com/ CSS样式网站 毒蘑菇-配色 CSS 配色,阴影网站 一个好用的配色网站! 毒蘑菇 - 配色 (dumogu.top)https://color.dumogu.top/ …

如何使用Minitab计算MSA数据

1.1 步骤一 将数据复制进Minitab数据区 1.2 步骤二 按图示选择 1.3 步骤三 按图示选择,测量数据那列根据自己填入的数据而定 1.4 数据 评价中的重要指标为可区分类别数(通常需大于10),合计量具R&R(通常需小于10&am…

alibabacloud学习笔记07(小滴课堂)

讲解Sentinel自定义异常降级-新旧版本差异 讲解新版Sentinel自定义异常数据开发实战 如果我们都使用原生的报错,我们就无法得到具体的报错信息。 所以我们要自定义异常返回的数据提示: 实现BlockExceptionHandler并且重写handle方法: 使用F…

Jupyter如何开启Debug调试功能

由于需要对算子做远程调试功能,需要在jupyter中开启远程断点调试功能,特此记录。 本文写作时用到的系统是Ubuntu22,Python的版本是3.8. 首先,创建虚拟环境。 python -m venv venv source venv/bin/activate接着,安装…

【教程】无法验证app需要互联网连接以验证是否信任开发者

摘要 本文将探讨在使用苹果App时遇到无法验证开发者的情况,以及用户可以采取的解决方案。通过检查网络连接、重新操作、验证描述文件等方式来解决无法验证开发者的问题。同时,还介绍了开发者信任设置的步骤,以及使用appuploader工具进行安装…

Vue点击切换组件颜色

例如我有一个这样的组件&#xff0c;我希望在点击组件之后由蓝色变成橙色 先把原来的代码附上(简化掉了叉号&#xff09;&#xff1a; <div v-for"(item, index) in words" :key"index" class"scrollbar-demo-item"><span>{{ item …

python入门必会的助手函数:dir()函数

今天我们来看一个非常重要的函数&#xff1a;dir() 中文说明&#xff1a;不带参数时&#xff0c;返回当前范围内的变量、方法和定义的类型列表&#xff1b;带参数时&#xff0c;返回参数的属性、方法列表。如果参数包含方法__dir__()&#xff0c;该方法将被调用。如果参数不包…

IntelliJ IDEA 下载安装及配置使用教程

一、IDEA下载 1、打开游览器输入IntelliJ IDEA – the Leading Java and Kotlin IDE (jetbrains.com) 2、点击Download&#xff0c;进入IDEA下载界面 3、 有两个版本&#xff0c;一个是Ultimate 版本为旗舰版&#xff0c;需要付费&#xff0c;包括完整的功能&#xff0c;下载后…

【JSON2WEB】08 Amis的事件和校验

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…

部署DNS解析服务

一、安装软件&#xff0c;关闭防火墙&#xff0c;启动服务 1.yum install -y bind bind-utils bind-chroot 2.systemctl stop firewalld && setenforce 0 3.systemctl start named 二、工作目录 /var/named/chroot/etc #存放主配置文件 /var/named/chroot/var/n…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:LongPressGesture)

用于触发长按手势事件&#xff0c;触发长按手势的最少手指数为1&#xff0c;最短长按时间为500毫秒。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 LongPressGesture(value?: { fingers?: num…

Vue3:OptionsAPI 与 CompositionAPI的比较

1、Vue2 Vue2的API设计是Options&#xff08;配置&#xff09;风格的。 Options API 的弊端 Options类型的 API&#xff0c;数据、方法、计算属性等&#xff0c;是分散在&#xff1a;data、methods、computed中的&#xff0c;若想新增或者修改一个需求&#xff0c;就需要分别…

【Leetcode每日一题】 前缀和 - 和为 K 的子数组(难度⭐)(29)

1. 题目解析 题目链接&#xff1a;560. 和为 K 的子数组 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给数组是否存在连续子数组和为指定值&#xff0c;存在返回连续子数组个数即可&#xff0c;不存在返回0即…

C++入门全集(5):内存管理

前言 一、内存区域划分 二、C的内存管理方式 2.1 对内置类型 2.2 对自定义类型 三、new和delete的底层实现 四、new和delete的原理 五、定位new 六、malloc/free和new/delete 前言 在C中&#xff0c;内存管理是不可避免的一门必修课。C对内存的自由度使其获得了更高的…

单片机的boot升级和双备份升级

同时boot升级还会有一个策略来防止单片机变成砖&#xff1a;就是boot的升级程序写在boot中&#xff0c;这个部分的的升级程序是不会改动的&#xff0c;如果检测到升级失败&#xff0c;会一直等待&#xff0c;直到升级正确的程序