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

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

原文地址:https://www.cnblogs.com/wangzisheng/p/9144556.html

时间: 2024-10-08 03:37:46

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

在平面中,一个点绕任意点旋转θ度后的点的坐标

假设对图片上任意点(x,y),绕一个坐标点(rx0,ry0)逆时针旋转a角度后的新的坐标设为(x0, y0),有公式: x0= (x - rx0)*cos(a) - (y - ry0)*sin(a) + rx0 ; y0= (x - rx0)*sin(a) + (y - ry0)*cos(a) + ry0 ;

unity2d 实现物体跟随鼠标绕一个点旋转效果

在2D游戏中,类似泡泡龙炮台发射.敌人飞机永远指向PLAYER.愤怒小鸟弹弓发射等效果,都需要用到物体跟随鼠标绕一个点旋转的效果,在unity中实现代码很简单,但是在理解上有一定障碍,因为unity是3D界面,他的旋转并不是2D世界中那么简单. 实现这种效果,可以使用两种方法,一种是采用角度计算,一种是采用向量运算: 1,角度运算容易理解,但是代码较为繁琐,可以参考 点击打开链接, 2,向量运算实现 1),向量运算简单复习 向量指具有大小和方向的几何对象,可以形象化地表示为带箭头的线段. 也就是

unity3d实现一个放大缩小视角左右旋转视角的效果

using UnityEngine;using System.Collections; //摄像机跟随public class FollowPlayer : MonoBehaviour { private Transform player;//角色    private  Vector3 offsetPosition;//位置便宜    private bool isRotating=false;//是否有在滑动 public float distance;//向量长度    public fl

iOS游戏框架Sprite Kit基础教程第1章编写第一个Sprite Kit程序

iOS游戏框架Sprite Kit基础教程第1章编写第一个Sprite Kit程序 程序是为了实现特定目标或解决特定问题而用计算机语言编写的命令序列的集合.本章将以编写第一个Sprite Kit程序为主线,为开发者讲解什么是Sprite Kit.苹果账号的注册.Xcode的下载和安装.编写程序.调试等内容.选自iOS游戏框架Sprite Kit基础教程Swift版上册大学霸 1.1  Sprite Kit介绍 从iOS 7开始添加了Sprite Kit.本节将为开发者讲解什么是Sprite Ki

绕任意轴旋转的矩阵推导总结

前言 常用的几何变换中旋转是较为复杂的一种,最近看<Physically Based Rendering, Second Edition: From Theory To Implementation>一书涉及绕任意轴旋转的实现,也给出了大体思路,但具体的推导过程及最后的旋转矩阵并未直接地给出,故根据参考Animated CGEM: Rotation About an Arbitrary Axis总结(欢迎指正). (一)基础 1.点乘与叉乘 点乘(dot)亦称作内积或数量积,如图,a·b =

定点绕定轴旋转

通过两个已知点,绕定轴旋转360次,每次旋转一度,获得360个点,一次相连,可以获得一个近似圆.网上找的公式基本都是左手坐标系下的选择公式,故而进行了多次坐标转换 1.3.2版本 public static List<Vector3d> Translate(List<Vector3> list) { List<Vector3d> zuoshou = new List<Vector3d>();//存左手坐标系下的各点坐标 List<Vector3d>

c语言:写一个函数建立一个有3名学生数据的单向动态链表

写一个函数建立一个有3名学生数据的单向动态链表. 解:程序: #include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct Student) struct Student { long num; float score; struct Student *next; }; int n; struct Student *creat(void)//定义函数返回一个指向链表头的指针 { struct Student *head

访问一个绝对地址把一个整型数强制转换 (typecast)为一个指针是合法的

在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66.编译器是一个纯粹的ANSI编译器.写代码去完成这一任务. 解析:这一问题测试你是否知道为了访问一个绝对地址把一个整型数强制转换(typecast)为一个指针是合法的.这一问题的实现方式随着个人风格不同而不同.典型的代码如下: 一个较晦涩的方法是: 建议你在面试时使用第一种方案.答案:

一个客户端和一个服务器端聊天

*发送线程 import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner; public class SendThread extends Thread { private Socket socket; public SendThread(Socket socket){ this.socket = socket; } @Override publi