最近有小伙伴问我瞄准线遇到各种形状该怎么处理?如何实现反复横跳的瞄准线?最近刚好在《Cocos Creator游戏开发实战》中看到物理系统有一个射线检测,于是,基于这个射线检测,写了一个反复横跳的瞄准线效果。一起往下看吧!文章底部获取完整项目!

国际惯例,先上最终效果!

在讲解之前我们需要一些向量的知识,简单的介绍一些吧!

向量的加法,OA + AB = OB

向量的点乘,表示一个向量在另一个向量上的投影,是个标量,有正负之分。向量夹角小于 90度 为正数,等于 90度 为 零,大于 90度 为负数。

向量的叉乘,结果为向量,正好垂直于两个向量构成的平面(右手系),也称为法向量。这里暂时没用到,顺便提一下。

接下来进入正题,已知入射向量(单位向量),法向量(单位向量),如何得出反射向量?

我们将反射向量平移至入射向量起点,延长法向量与其相交,这个延长线的长度,刚好是 入射向量在法向量上的投影的相反数的两倍 。再根据投影和向量加法可以推出反射向量的计算公式。

清楚了么?不清楚也没关系,记得最后的公式就可以了,接下来进入 cocos creator 操作环节。

既然是物理系统中的碰撞检测,我们在编辑器里添加的是物理系统中的碰撞器,而不是引擎的碰撞器,不要选错了哦。

不动的刚体类型设为 static ,添加完所有的物理碰撞器后如下所示。

用到物理引擎自然要把物理引擎打开。

cc.director.getPhysicsManager().enabled = true;

如何进行射线检测的?通过起始点、入射方向和剩余线段的长度获取射线检测的结果。如果检测到碰撞体,就画入射线段,并计算反射方向,再次进行射线检测;如果未检测到碰撞体,就把剩余线段画完。主要代码如下:

/**
* @description 计算射线
* @param startLocation 起始位置 世界坐标系
* @param vector_dir 单位方向向量
*/
private drawRayCast(startLocation: cc.Vec2, vector_dir: cc.Vec2) {
// 剩余长度
const left_length = AIM_LINE_MAX_LENGTH - this._cur_length;
if (left_length <= 0) return;
// 计算线的终点位置
const endLocation = startLocation.add(vector_dir.mul(left_length));
// 射线测试
const results = cc.director.getPhysicsManager().rayCast(startLocation, endLocation, cc.RayCastType.Closest);
if (results.length > 0) {
const result = results[0];
// 指定射线与穿过的碰撞体在哪一点相交。
const point = result.point;
// 画入射线段
this.drawAimLine(startLocation, point);
// 计算长度
const line_length = point.sub(startLocation).mag();
// 计算已画长度
this._cur_length += line_length;
// 指定碰撞体在相交点的表面的法线单位向量。
const vector_n = result.normal;
// 入射单位向量
const vector_i = vector_dir;
// 反射单位向量
const vector_r = vector_i.sub(vector_n.mul(2 * vector_i.dot(vector_n)));
// 接着计算下一段
this.drawRayCast(point, vector_r);
} else {
// 画剩余线段
this.drawAimLine(startLocation, endLocation);
}
}

如何画瞄准线小圈圈?通过结束位置和起始位置计算数量和间隔向量,画出一个个小圆圈。参考代码如下。

/**
* @description 画瞄准线
* @param startLocation 起始位置 世界坐标系
* @param endLocation 结束位置 世界坐标系
*/
private drawAimLine(startLocation: cc.Vec2, endLocation: cc.Vec2) {
// 转换坐标
const graphic_startLocation = this.graphic_line.node.convertToNodeSpaceAR(startLocation);
this.graphic_line.moveTo(graphic_startLocation.x, graphic_startLocation.y);
// 画小圆圆
// 间隔
const delta = 20;
// 方向
const vector_dir = endLocation.sub(startLocation);
// 数量
const total_count = Math.round(vector_dir.mag() / delta);
// 每次间隔向量
vector_dir.normalizeSelf().mulSelf(delta);
for (let index = 0; index < total_count; index++) {
graphic_startLocation.addSelf(vector_dir)
this.graphic_line.circle(graphic_startLocation.x, graphic_startLocation.y, 2);
}
}


完整代码


反复横跳的瞄准线!从向量计算说起!基于射线检测的实现!Cocos Creator!的更多相关文章

  1. Vue--子组件互相传值,子组件来回传值,传值反复横跳

    Vue--子组件传值,子组件来回传值,子组件传值反复横跳 我不不仅要子组件之间直接传值,我还要传过去再传回来,传回来再传过去,子组件直接反复横跳 解决问题 给组件传值,并不知道改值的校验结果 同一个组 ...

  2. Cocos Creator实现左右跳游戏

    ​1. 玩法说明 游戏开始后,点击屏幕左右两侧,机器人朝左上方或右上方跳一步,如果下一步有石块,成功得1分,否则游戏结束. 2. 模块介绍 游戏场景分为2个:主页场景(home).游戏场景(game) ...

  3. Cocos Creator实现左右跳游戏,提供完整游戏代码工程

    ​1. 玩法说明 游戏开始后,点击屏幕左右两侧,机器人朝左上方或右上方跳一步,如果下一步有石块,成功得1分,否则游戏结束. 2. 模块介绍 游戏场景分为2个:主页场景(home).游戏场景(game) ...

  4. 【BZOJ3670】动物园(KMP算法)

    [BZOJ3670]动物园(KMP算法) 题面 BZOJ 题解 神TM阅读理解题 看完题目之后 想暴力: 搞个倍增数组来跳\(next\) 每次暴跳\(next\) 复杂度\(O(Tnlogn)\) ...

  5. [BZOJ3680][JSOI2004]平衡点 / 吊打XXX

    BZOJ Luogu (洛谷和BZOJ上的数据范围不同,可能需要稍微调一调参数) sol 这题的参数调得我心累 模拟退火的模型可以形象地理解为:不断降温的小球在一个凹凸不平的平面上反复横跳,根据万有引 ...

  6. bzoj 1488: [HNOI2009]图的同构

    Description 求两两互不同构的含n个点的简单图有多少种. 简单图是关联一对顶点的无向边不多于一条的不含自环的图. a图与b图被认为是同构的是指a图的顶点经过一定的重新标号以后,a图的顶点集和 ...

  7. UOJ #236. 【IOI2016】railroad

    Description Anna 在一个游乐园工作.她负责建造一个新的过山车铁路.她已经设计了影响过山车速度的 nn 个特殊的路段(方便起见标记为 00 到 n−1n−1).现在 Anna 必须要把这 ...

  8. WC2019冬眠记

    Day0 报道日就当做Day0吧. 上午起床比较晚,起来就开始整理东西准备搬到广二的高中部去,搬了两趟,因为没吃早饭,头就很晕,吓得我赶快把之前发的士力架给吃了. 上午李姐姐和我们聊了聊\(THUWC ...

  9. HNOI2019做题笔记

    代码比较长所以直接去LOJ看吧- 鱼(计算几何.向量) 比较套路的内容:枚举\(D\),对于其他所有点按照\(D\)极角排序,按照极角序枚举\(A\),这样垂直于\(AD\)的线也会以极角序旋转,可以 ...

随机推荐

  1. 浅谈js获取客户端IP

    JS前端获取客户端IP的方法基本都是通过三方接口: 常用的方法1: <script src="http://pv.sohu.com/cityjson?ie=utf-8"> ...

  2. C# 获取 与 修改 web.config中的值(修改Xml文件)

    定义web.config 中 appSettings 节点 <appSettings> <add key="domainExist" value="fa ...

  3. unittest详解(六) 断言

    我们在执行测试用例时,怎么来判断这条用例是否通过呢?唯一的办法就是拿实际结果和预期结果进行比较,如果一致用例就是通过的,否则用例就是失败的.在python中这种比较的方法就叫做断言,unittest框 ...

  4. hive单用户多点模式配置

    简介 单用户多点模式也称远程服务模式,用户非java客户端访问元数据库,在服务端启动MetaStoreServer,客户端利用Thrift协议通过MetaStoreServer访问元数据库. mysq ...

  5. sqli-labs(1)

    0x01字符注入 今天是第一天的学习sqli-labs Lesson1:字符型注入 首先测试一下 ' 发现报错  然后 ''发现 不报错 这种大概率就是字符注入了 接下来我们进行列查询  查询语句 h ...

  6. 【个推CTO谈数据智能】之我们理解的数据中台

    引言 在本系列的前面两篇文章(<数据智能时代来临:本质及技术体系要求>和<多维度分析系统的选型方法>)之中,我们概括性地阐述了对于数据智能的理解,并根据工作中团队涉及到的多维度 ...

  7. LeetCode 第 3 题:无重复字符的最长子串(滑动窗口)

    LeetCode 第 3 题:无重复字符的最长子串 (滑动窗口) 方法:滑动窗口 滑动窗口模板问题:右指针先走,满足了一定条件以后,左指针向前走,直到不满足条件. 特点:左右指针的方向是一致的,并且是 ...

  8. Java 里volatile关键字是什么意思啊?如何使用呢?

    一旦一个并发共享变量(类的成员变量.静态成员变量)被 volatile 关键字修饰就具备了可见性(即一个线程修改了一个变量的值对于另一个线程来说是立即可见的)和有序性(即禁止进行指令重排序),实质是在 ...

  9. Java连接MQTT服务-tcp方式

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  10. 一、linux下nginx1.7.8+php5.6.3的环境配置

    部分参考:http://www.cnblogs.com/simpman/p/4151662.html http://blog.zyan.cc/nginx_php_v6 1.利用linux系统自带的yu ...