尝试搭建webgl游戏引擎-简单的点击事件

上一篇是:尝试搭建webgl游戏引擎-渲染管线

本篇记录一下简单的点击事件

要做游戏,交互肯定是必不可少的。

最简单的交互就是点击物体,然后做出相应的反馈。
本篇简单实现了一下球形碰撞盒的射线检测。

场景点击

因为webgl是基于canvas的。
canvas又是htmlElement。
htmlElement就支持addEventListener添加相关交互事件。
这里注册的是mousedown,mouseup,mousemove相关的鼠标事件。
添加一个input的类,用来管理鼠标事件。
实现了一个eventmanager的事件管理类。
然后其它节点可以通过eventmanager来注册事件。
input里注册了装饰了鼠标事件为touch事件,然后向外发送事件。

要实现场景的点击就非常简单了,只需要向input类注册touch事件即可。

产生射线

射线是一个有起点和终点的线段。(当然也可以没有终点)
在屏幕任何位置点击后,就会创建一个从以摄像机位置为起点,经过屏幕位置到世界坐标的折算位置,然后向屏幕内射去。
运算代码是:

 if (startPoint instanceof Vec2) {
            const camera = Director.instance.curCamera!;
            const r = 2 * camera.near * Math.tan(Math.PI * (camera as any).fovY / 360) / Director.instance.size.h;
            const y = startPoint.y * r;
            const x = startPoint.x * r;
            this.startPoint.set(x, y, camera.container!.worldPosition.z - camera.near);
            Vec3.sub(this.direction, this.startPoint, camera.container!.worldPosition);
            this.startPoint.set(camera.container!.worldPosition);
} 

射线和球的碰撞

要判断一条线是否和球相交非常简单。
只需要判断球心到线的距离是否小于等于自己的半径即可。
如果小于或者等于,则相交。则产生碰撞。

但是实现起来还是要费点工夫
首先需要获得摄像机指向球心的向量A。
然后和射线点乘,获得在射线上的投影距离。
然后投影距离乘以归一化的射线向量,得到投影到射线上的向量B。
然后A减去B就得到了垂直矢量,求其模就行了。
示意图

总结

球形射线检测还是比较简单,但是如果有很多个物体,还是需要考虑到性能的。
那是之后需要研究的内容了,比如4叉树。

下一篇研究一下正方体碰撞。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值