摘要
瞄准线分三种:无效果直射、遇墙反射、遇墙与球体反射。今天 KUOKUO 用一次函数与绘图组件来实现第二种:遇墙反射。
正文
版本说明
使用 CocosCreator 的 2.2.1 版本演示。

一次函数
相信大家都知道一次函数 y = k·x + b,如下图,它就是条直线。

只要确认了 k 与 b,就确认了这条直线。b 的值是如何求的呢?x = 0 时对应的 y 值。所以 b 的值体现在 y 轴上。那么它如何应用于瞄准线呢?
层级
如下层级,有一个带有绘图组件的节点 Draw Mgr。(画布是 720 * 1280)。

实现原理
我们以绘图节点为中心建立 X-Y 坐标系。左边界是 -360,右边界是 360。
let POS = cc.Enum({ LEFT: -360, RIGHT: 360, WIDTH: 720, });
|

如图,我们先通过第一次与边界相交来求得 b 的增量。观察中心的点位与边界点位,b 的值总是边界 y 值加上增量值。
let d_b = (k > 0 ? POS.RIGHT : POS.LEFT) * k;
|
长度削减
我们先指定长度。然后在一个死循环里,不断的判断预计达到的边界长度是否是小于剩余长度的。如果是够长的,进行削减。如果不够长了,我们要判断两种情况,是一开始就不够长还是反弹到最后不够长,用一个 isReBound 标志判断。
drawLine (pos) { this.draw.clear(); let lineLength = 1200; let k = pos.y / pos.x; let point = cc.v2(0, 0); this.draw.moveTo(0, 0); let b = 0; let x, y; let d_b = (k > 0 ? POS.RIGHT : POS.LEFT) * k; let isRebound = false; while (true) { x = k > 0 ? POS.RIGHT : POS.LEFT; y = k * x + b; let l = cc.v2(x, y).sub(point).mag(); if (l < lineLength) { isRebound = true; lineLength -= l; this.draw.lineTo(x, y); point.x = x; point.y = y; b = y + d_b; k *= -1; } else { if (isRebound) { let l_k = lineLength / l; let r_x = POS.WIDTH * l_k; x = k > 0 ? POS.LEFT + r_x : POS.RIGHT - r_x; y = k * x + b; } else { let l_k = lineLength / l; let r_x = POS.WIDTH / 2 * l_k; x = k > 0 ? r_x : -r_x; y = k * x; if (x > -0.05 && x < 0.05); y = lineLength; } this.draw.lineTo(x, y); break; } } this.draw.stroke(); },
|
在最中心时,由于过于接近 0 会导致瞄准线不可见,所以限制了 -0.05 到 0.05。
清除线
clearLine () { this.draw.clear(); },
|
触摸监听与坐标转化
脚本绑定于 Canvas,手指触摸时基于 Canvas 节点转化坐标,但是 Draw Mgr 节点的坐标不是 0,0 所以要做差。
start () { this.node.on(cc.Node.EventType.TOUCH_START, (e) => { let pos = this.node.convertToNodeSpaceAR(e.getLocation()); pos.x -= this.draw.node.x; pos.y -= this.draw.node.y; this.drawLine(pos); }, this); this.node.on(cc.Node.EventType.TOUCH_MOVE, (e) => { let pos = this.node.convertToNodeSpaceAR(e.getLocation()); pos.x -= this.draw.node.x; pos.y -= this.draw.node.y; this.drawLine(pos); }, this); this.node.on(cc.Node.EventType.TOUCH_END, (e) => { this.clearLine(); }, this); },
|
最后效果

结语
其实不难,学会了吧!
O(∩_∩)O~~
源码在我的微信公众号回复关键词【瞄准线】即可获得
微信公众号
