Cocos2d-x学习:根据贝塞尔曲线进行抛物线移动补充,三角形顶点坐标获取某个角的角度

Himi的让CCSprite根据贝塞尔曲线进行抛物线移动

其Blog原文:http://xiaominghimi.blog.51cto.com/2614927/665781

    //  抛物线运动并同时旋转    -Himi   
    //mSprite:需要做抛物线的精灵  
    //startPoint:起始位置  
    //endPoint:中止位置  
    //startA:起始角度  
    //endA:中止角度  
    //dirTime:起始位置到中止位置的所需时间  
    - (void) moveWithParabola:(CCSprite*)mSprite startP:(CGPoint)startPoint endP:(CGPoint)endPoint startA:(float)startAngle endA:(float)endAngle dirTime:(float)time{   
        float sx = startPoint.x;  
        float sy = startPoint.y;   
        float ex =endPoint.x+50;  
        float ey =endPoint.y+150;   
        int h = [mSprite contentSize].height*0.5;  
        //设置精灵的起始角度  
        sprite.rotation=startAngle;  
        ccBezierConfig bezier; // 创建贝塞尔曲线  
        bezier.controlPoint_1 = ccp(sx, sy); // 起始点  
        bezier.controlPoint_2 = ccp(sx+(ex-sx)*0.5, sy+(ey-sy)*0.5+200); //控制点  
        bezier.endPosition = ccp(endPoint.x-30, endPoint.y+h); // 结束位置     
        CCBezierTo *actionMove = [CCBezierTo actionWithDuration:time bezier:bezier];   
        //创建精灵旋转的动作  
        CCRotateTo *actionRotate =[CCRotateTo actionWithDuration:time angle:endAngle];  
        //将两个动作封装成一个同时播放进行的动作  
        CCAction * action = [CCSpawn actions:actionMove, actionRotate, nil];   
        [mSprite runAction:action];  
    } 

如我们的移动对象是一根箭,如何能够获得旋转的角度。


根据三角形顶点坐标获取某个角的角度

使用向量夹角公式
cos<夹角> = 两向量之积 / 两向量模的乘积
<夹角> = arccos( 两向量之积 / 两向量模的乘积 )

- (double)getAngle:(CGPoint) pSrc p1:(CGPoint) p1 p2:(CGPoint) p2
{
    double angle = 0.0f; // 夹角
    
    // 向量Vector a的(x, y)坐标
    double va_x = p1.x - pSrc.x;
    double va_y = p1.y - pSrc.y;
    
    // 向量b的(x, y)坐标
    double vb_x = p2.x - pSrc.x;
    double vb_y = p2.y - pSrc.y;
    
    double productValue = (va_x * vb_x) + (va_y * vb_y);  // 向量的乘积
    double va_val = sqrt(va_x * va_x + va_y * va_y);  // 向量a的模
    double vb_val = sqrt(vb_x * vb_x + vb_y * vb_y);  // 向量b的模
    double cosValue = productValue / (va_val * vb_val);      // 余弦公式
    
    // acos的输入参数范围必须在[-1, 1]之间,否则会"domain error"
    // 对输入参数作校验和处理
    if(cosValue < -1 && cosValue > -2)
        cosValue = -1;
    else if(cosValue > 1 && cosValue < 2)
        cosValue = 1;
    
    // acos返回的是弧度值,转换为角度值
    angle = acos(cosValue) * 180 / M_PI;
    
    return angle;
}


调用的例子

- (void)fireFrom:(CGPoint)ptFrom To:(CGPoint)ptTo
{
    [self setPosition:ptFrom];    
    
    float ag1 = [self getAngle:ptFrom p1:ccp(ptFrom.x+200,ptFrom.y) p2:ptTo];
    float startag = ag1*(ptTo.y>ptFrom.y ? -1:1);
    float endag = startag-20*(ptTo.y>ptFrom.y ? -1:-1)*(ptTo.xptTo.x?1:-1)/2;

    self.position = ptFrom;
    [self setVisible:YES];
    
    [self moveWithParabola:self startP:ptFrom endP:ptTo startA:starta endA:enda dirTime:2.0f];
}


你可能感兴趣的:(cocos2d-x)