前几天心血来潮想用Egret实现一个类似捕鱼达人的小demo,没想到我菜得“创业未半”就已经卡住了,创建好游戏界面后发现连炮台方向跟随鼠标都没法实现,经过上班摸鱼的思考,终于在今天想明白了。
效果描述
实现原理
- 获得鼠标在舞台上的点击坐标
- 获得位图锚点坐标(一般是将中心作为锚点)
- 通过位图锚点坐标与点击坐标计算得出两者之间的向量,需要注意的是向量也是一个坐标
- 利用向量以及Math.atan2()正切函数计算得出所需旋转的角度(结果可能与预期有点区别,需要根据实际情况做出调整)
关键知识及API:
锚点:
锚点是用来确定显示对象的位置和旋转中心的点,它通常是相对于显示对象本身的局部坐标系中的一个点。
全局坐标系:
全局的坐标系,以左上角为原点,水平右方向为x正半轴,垂直向下方向为y正半轴
局部坐标系:
每个显示对象的坐标系,在不做出更改的情况下的同样是以为左上角(原始锚点)为原点,更改锚点后则以更改后的锚点作为原点,坐标轴方向和全局一样。
localToGlobal()
Egret的显示对象类(例如 egret.DisplayObject)中的一个方法,用于将显示对象的局部坐标系中的坐标转换为全局坐标系中的坐标。语法如下:
localToGlobal(localX:number, localY:number, resultPoint?:Point):Point
localX 和 localY 是相对于当前显示对象的局部坐标系中的坐标,resultPoint 是可选参数,表示转换后的全局坐标系中的坐标。如果不指定该参数,则会创建一个新的 Point对象来存储转换后的坐标。
该方法返回一个 Point对象,表示转换后的全局坐标系中的坐标。
关键代码:
//先把位图的锚点更改成位图的中心作为旋转中心
this.PlayerShip.anchorOffsetX = this.PlayerShip.width / 2
this.PlayerShip.anchorOffsetY = this.PlayerShip.height / 2
/*
经过localToGlobal的转换后,位图的锚点坐标变成了全局坐标系坐标而不再是位图资源的坐标系坐标,
这样能直接俄哟弄个两个点来进行向量的计算
这里需要注意的是,这个只需要在加载位图时设置一次就行,不需要放在点击事件里更新,
如果放在点击时间里点击一次更新一次,就会导致效果出错
因为锚点是用来确定显示对象的位置和旋转中心的点,它通常是相对于显示对象本身的局部坐标系中的一个点。当显示对象发生旋转时,它的局部坐标系也会随之旋转,因此锚点的位置也会发生变化。
*/
this.localPoint = this.PlayerShip.localToGlobal(this.PlayerShip.anchorOffsetX,this.PlayerShip.anchorOffsetY)
//计算向量
const distanceX: number = this.localPoint.x-event.stageX
const distanceY: number = this.localPoint.y-event.stageY
//利用向量及反正切函数计算所需角度
let targetAngle: number = Math.atan2(distanceY, distanceX) * 180 / Math.PI
//将计算出来的偏移角度经过一系列处理,得出正确的位图的偏移角度
this.PlayerShip.rotation = targetAngle-90 //这里的就是我难以解释需要根据实际情况做出调整的地方
基本的逻辑大概就这样,这应该只是实现的一种方式,应该还有其他的方式实现,如果对Egret有兴趣的话,欢迎和我一起讨论。