等于 边 a 的长度,同样 鼠标y - 鱼儿 y 等于 边 b 的长度。

    知道角度之后,我们旋转这个角度就是了,但是我们会发现,是鱼尾巴在跟着鼠标跑,这就很尴尬了。

    这个时候我们应该旋转一个 180 度,而对应的数值就是 Math.PI

    原理跟前面的一样,只不过多了2行对于角度旋转优化的代码。

    当你完成之后,你可以注释这俩行看一看,当你鼠标在快速画圈圈的时候,鱼儿旋转方向会异常。

    • 添加角度属性与设置旋转
    1. // 鱼妈妈
    2. class FishMonther{
    3. x: number = cvs_width / 2; // 坐标轴 x
    4. y: number = cvs_height / 2 ; // 坐标轴 y
    5. bigEye = new Image(); // 眼睛
    6. bigBody = new Image(); // 身体
    7. BigTail = new Image(); // 尾巴
    8. constructor(){
    9. this.bigEye.src = 'assets/img/bigEye0.png';
    10. this.bigBody.src = 'assets/img/bigSwim0.png';
    11. }
    12. draw(){
    13. this.x = utils.lerpDistance(mouse_x, this.x , .9)
    14. this.y = utils.lerpDistance(mouse_y, this.y , .9)
    15. let instance_X = mouse_x - this.x; // 边 a
    16. let instance_Y = mouse_y - this.y; // 边 b
    17. let ag = Math.atan2(instance_Y, instance_X) + Math.PI // [-PI, PI]
    18. this.angle = utils.lerpAngle(ag, this.angle, .9)
    19. ctx_one.save();
    20. ctx_one.translate(this.x, this.y); // 定义相对定位的坐标中心点
    21. ctx_one.rotate(this.angle);
    22. ctx_one.scale(.7, .7);
    23. ctx_one.drawImage(this.bigEye, -this.bigEye.width / 2, -this.bigEye.height / 2); // 居中,所以向左移动宽度的一半,向上移动宽度的一半
    24. ctx_one.drawImage(this.bigBody, -this.bigBody.width / 2, -this.bigBody.height / 2);
    25. ctx_one.drawImage(this.BigTail, -this.BigTail.width / 2 + 30, -this.BigTail.height / 2); // 这里的尾巴,往右移动30像素,让它在身体的后面。
    26. ctx_one.restore();
    27. }

    其实这些跟图形算法有关,感兴趣的可以自己深究下去,从学习 C++ 开始,然后去学习了解下 OpenCV,当然学之前你可能需要恶补数学知识了。