【100个Cocos实例】还记得这个指哪打哪的游戏吗?

引言

Cocos中简易实现炉石目标选择箭头效果

23年1月24日0时 ,由网易代理的暴雪系列游戏 在国内正式终止运营

炉石传说 ,一个陪伴了笔者4年 的游戏,传说、竞技场12胜历历在目。

转眼停服 已经快1年 ,有小道消息 称炉石即将回归国服,勾起满满的回忆。

咱们搞技术的,不会表达,做个类似的简易的目标选择效果看看!

本文将介绍一下Cocos中简易实现炉石目标选择箭头效果

本文源工程可在文末阅读原文获取,小伙伴们自行前往。

1.目标选择效果

通常在游戏开发 中,战斗或者其他场景 ,需要玩家去操作选择需要攻击的目标、需要移动到的点

为了表现更明显的效果 ,会采用箭头指示的形式。

箭头一般从起点出发指向终点 ,期间还可以做一些动画 ,使得效果生动一点。

这里面有哪些知识点?

2.需求分析

原版附带箭头的形变 ,通过模型实现,我们暂时做个简易版本 的,后续有时间再实现个3d版本。

要在Cocos中简易实现 炉石目标选择箭头效果,可能需要以下知识点

  • 获取鼠标点击位置、实时获取鼠标位置。
  • 箭头的跟随和指向。
  • 箭头长度的控制。
  • 箭头身体部位做一些简易的动画。

下面一起来简易实现炉石目标选择箭头效果。

3.简易实现炉石目标选择箭头效果

1.环境

引擎版本:Cocos Creator 3.8.1

编程语言:TypeScript

2.资源准备

从网络上找来熟悉的资源 。简单拼接一下,由于箭头可以控制长短 ,我们分成2部分

  • 箭头部分
  • 身体部分

为了让身体的每一格排列整齐,我们添加一个垂直布局

关于箭头长短的控制 ,我们使用Mask组件和UITransform组件实现。

下面一起来写代码。

3.编写代码

首先 我们创建一个HeartStoneArrow组件并且添加到节点上。

typescript 复制代码
import { _decorator, Component, EventMouse, find, misc, Node, NodeEventType, UI, UITransform, v2, v3, Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('HeartStoneArrow')
export class HeartStoneArrow extends Component {
    arrow: Node;
    body: Node;
    bodyTrans: UITransform;
    criticalValue: number;
}

然后start()方法中进行初始化。

typescript 复制代码
start() {
    const canvas = find("Canvas");
    this.arrow = canvas.getChildByPath("HeartStoneArrow/arrow");
    this.arrow.active = false;
    this.body = canvas.getChildByPath("HeartStoneArrow/body");
    this.bodyTrans = this.body.getComponent(UITransform);
    const len = this.body.children[0].children.length;
    const lastChildren = this.body.children[0].children[len - 1];
    this.criticalValue = lastChildren.position.y + lastChildren.getComponent(UITransform).height;
    let startPos = null;
}

鼠标的点击位置通过NodeEventType.MOUSE_DOWN事件的getUILocation()获取。

typescript 复制代码
canvas.on(NodeEventType.MOUSE_DOWN, (event: EventMouse) => {
    const pos = event.getUILocation();
    startPos = v3(pos.x, pos.y, 0);
    this.body.worldPosition = startPos;
    this.arrow.worldPosition = startPos;
}, this);

效果如下:

然后在NodeEventType.MOUSE_DOWN事件中更新箭头的位置和朝向 、更新身体的长度和朝向

typescript 复制代码
canvas.on(NodeEventType.MOUSE_MOVE, (event: EventMouse) => {
    if (startPos != null) {
        if (!this.arrow.active) {
            this.arrow.active = true;
        }
        const pos = event.getUILocation();
        this.arrow.worldPosition = v3(pos.x, pos.y, 0);
        this.body.angle = this.calculateAngle(v2(0, 1), v2(pos.x - startPos.x, pos.y - startPos.y))
        this.arrow.angle = this.body.angle;
        this.bodyTrans.height = (Vec3.distance(this.arrow.worldPosition, startPos) - 50) / this.node.scale.y;
    }
}, this);

其中朝向的计算运用到了求2个向量的夹角

typescript 复制代码
calculateAngle(vectorA: Vec2, vectorB: Vec2) {
    // 使用 Math.atan2 获取带方向的角度(弧度)
    const angleRad = Math.atan2(vectorB.y, vectorB.x) - Math.atan2(vectorA.y, vectorA.x);
    // 将弧度转换为角度
    const degrees = misc.radiansToDegrees(angleRad);
    // 确保角度在 [0, 360) 范围内
    return (degrees + 360) % 360;
}

箭头的长度通过修改Mask组件所在的节点的UITransform组件的高度,长度的计算用Vec3.distance计算。

typescript 复制代码
this.bodyTrans.height = (Vec3.distance(this.arrow.worldPosition, startPos) - 50) / this.node.scale.y;

效果如下:

最后 箭头的简易动画效果我们在update中实现,不断更新y坐标,并且循环

typescript 复制代码
protected update(dt: number): void {
    for (let i = 0; i < this.body.children[0].children.length; i++) {
        this.body.children[0].children[i].position = this.body.children[0].children[i].position.add3f(0, 10, 0);
        if (this.body.children[0].children[i].position.y >= this.criticalValue) {
            this.body.children[0].children[i].position = v3();
        }
    }
}

效果如下:

就这样我们的代码编写完毕,下面看看效果。

5.效果演示

结语

向好游戏和青春致敬!

本文源工程 可通过私信HeartStoneArrow获取。

在哪里 可以看到如此清晰的思路,快跟上我的节奏!关注我 ,和我一起了解 游戏行业最新动态,学习游戏开发技巧。

我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助, 也希望通过您能帮助到大家。

AD:笔者线上的小游戏《贪吃蛇掌机经典》《重力迷宫球》《填色之旅》大家可以自行点击搜索体验。

实不相瞒,想要个在看 !请把该文章分享给你觉得有需要的其他小伙伴。谢谢!

推荐专栏:

100个Cocos实例

8年主程手把手打造Cocos独立游戏开发框架

和8年游戏主程一起学习设计模式

从零开始开发贪吃蛇小游戏到上线系列

知识付费专栏

相关推荐
qiyi.sky3 分钟前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
煸橙干儿~~7 分钟前
分析JS Crash(进程崩溃)
java·前端·javascript
安冬的码畜日常16 分钟前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n043 分钟前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。1 小时前
案例-任务清单
前端·javascript·css
zqx_72 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己2 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称3 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色3 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2343 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js