如何让一个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编辑器,效果就不展示了。

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

 

posted @ 2018-06-06 13:00  保持当下  阅读(1079)  评论(0编辑  收藏  举报