zoukankan      html  css  js  c++  java
  • 如何让一个sprite绕一个点旋转,同时又可以实现指定旋转角度并慢慢停下的效果

    如何让一个sprite绕一个点旋转,同时又可以实现指定旋转角度并慢慢停下的效果

    首先列出sprite围绕一个点旋转的公式,这个可以自己推导,假设sprite的起始位置为(x1,y1),围绕旋转的中心点为(x0,y0),那么sprite旋转的坐标公式为:

    sprite.x = (x1-x0)*Math.cos(angle) - (y1-y0)*Math.sin(angle) + x0;
    sprite.y = (y1-y0)*Math.cos(angle) + (x1-x0)*Math.sin(angle) + y0;

    当然也有其他的公式,这里以这个为例。

    有了旋转公式接下来就是速度慢慢停下来的公式,假如最终停止的角度为endA,初始旋转速度为10度,初始角度为startA(所有角度相对Y轴顺时针计算,如90度就是与x轴平行),初始旋转位置为(x0,y0),那么旋转慢慢停下来怎么计算呢,我们给旋转角度添加一个负加速度,sprite旋转的速度为speed,其旋转速度speed每帧都减去这个加速度,直到旋转停止,也就是speed = 0;如下:

    loop(){
      sprite.rotation += speed;
      speed -= a;
      if(speed <= 0){
         stop();        
      }      
    }

    这里只有一个值是不确定的就是加速度a,只要求出加速度a的公式就可以指定停止位置了。a怎么计算呢,首先有个位移公式为a = (vt*vt - v0*v0)/2s,v0是初始速度,很显然这里的vt = 0,s是位移,在这里表示总共旋转多少度,假设转一圈再停止到endA,那么s = 360 + endA - startA,这里要注意弧度与角度的转换,2*Math.PI=360,弧度p的角度为p1 = p*180/Math.PI,角度p的弧度为p2 = p*Math.PI/180,注意三角函数全部使用弧度,很好!到这里看下a的公式:

    a = -speed0 * speed0/(2*(360 + endA - startA));

    实现飞镖投到到转盘并跟随装盘旋转到指定位置的效果迎刃而解,下面是部分关键代码

    飞镖射中转盘后:

    if(this.dartSpr.scaleY <= 0.2){
                    this.isTarget = true;
                    // this.tempSpeed = -0.1;
                    let sangle = Math.atan((this.dartSpr.x - this.dialCenterX)/(this.dialCenterY - this.dartSpr.y));
                    //求需要旋转的角度 注意弧度转角度
                    let tangle = 360 + this.targetAngle - sangle*180/Math.PI;;
                    let aspeed = this.tempRotation * this.tempRotation/(2*tangle);
                    this.tempSpeed = -1*aspeed;
                }

    loop:

    private frameLoop(){
            if(!this.isGameStart) return;
            this.dialSpr.rotation += this.tempRotation;
    
            if(this.isTarget){
                this.targetPoint = new egret.Point(this.dartSpr.x,this.dartSpr.y);
                let tempx = this.targetPoint.x - this.dialCenterX;
                let tempy = this.targetPoint.y - this.dialCenterY;
                let angle = this.tempRotation*Math.PI/180;
                this.dartSpr.x = tempx*Math.cos(angle) - tempy*Math.sin(angle) + this.dialCenterX;
                this.dartSpr.y = tempy*Math.cos(angle) + tempx*Math.sin(angle) + this.dialCenterY;
            }
            this.tempRotation += this.tempSpeed;
            if(this.tempRotation <= 0){
                this.tempRotation = 0;
            }
        }

    其中每次都会把上次的sprite的位置重新赋值给targetPoint,是为了实现持续的旋转,注意保持转盘与sprite的角速度一致。

    如果可以,我愿意重新回到高中,去研究研究那个加速度以及曲线行驶的历史事迹,然后毕业不考大学,直接去搬砖,至少我知道怎么把砖以抛物线的轨迹扔到指定的位置,到时所有搬砖的都会对我刮目相看。

    咦。。走神了!我的这个分享是用的ts,egret编辑器,效果就不展示了。

    如果对同行能有帮助,这比搬砖强多了!

  • 相关阅读:
    IOS:APP网络状态的检测
    IOS:个人笔记|UI__使用Plist文件来进行数据的读取
    IntelliJ IDEA中项目import与open的区别
    打开电脑分屏
    微服务
    自增主键和UUID
    雪花算法
    使用navicat连接阿里云上mysql
    【vue】报错This dependency was not found
    跨域问题
  • 原文地址:https://www.cnblogs.com/wangzisheng/p/9144556.html
Copyright © 2011-2022 走看看