使用touch

编程入门 行业动态 更新时间:2024-10-27 04:30:14
本文介绍了使用touch - Cocos2D / Box2D在贝塞尔曲线路径上旋转Sprite的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个箭头,我用触摸旋转。我想知道是否可以在一条曲线上旋转箭头?我做了一些研究,我认为它被称为bezier路径?使用这个代码甚至可以在bezier路径上旋转精灵,如果是这样,我甚至可以使用它?

I have an arrow that I rotate with touch. I was wondering if it was possible to rotate the arrow on a curved line? I've done some research and I think it is called a bezier path? Is it even possible to rotate a sprite on a bezier path using this code and if so how would I even incorporate it?

UITouch *touch = [touches anyObject]; //acquire the previous touch location CGPoint firstLocation = [touch previousLocationInView:[touch view]]; CGPoint location = [touch locationInView:[touch view]]; //preform all the same basic rig on both the current touch and previous touch CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location]; CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation]; CGPoint firstVector = ccpSub(firstTouchingPoint, _arrow.position); CGFloat firstRotateAngle = -ccpToAngle(firstVector); CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle); CGPoint vector = ccpSub(touchingPoint, _arrow.position); CGFloat rotateAngle = -ccpToAngle(vector); CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle); //keep adding the difference of the two angles to the dial rotation arrowRotation += currentTouch - previousTouch;

例如,

球坐在地面上和在它上的箭头。当您触摸屏幕并移动箭头时,箭头在半圈轴上移动。

I have a ball sitting on the ground and an arrow right above it. When you touch the screen and move the arrow, the arrow moves on a half circle axis.

曲线看起来像这样并且箭头将在轴上旋转。

The curve would look like this Half Circle and the arrow would be rotating on the axis.

请让我知道如果我需要更清楚。我真的需要一些帮助。

Please let me know if I need to be more clear. I really need some help with this.

推荐答案

面对同样的问题几天。此答案中的大部分链接都已损坏,因此我找到了材料此处和此处并提供此代码。像魔术一样工作。希望它会帮助别人。

Have faced with same problem couple of days. Most of links in this answer is broken, so I have found material here and here and made this code. Works like magic. Hope it will help someone.

小说明:我有对象(自)女巫用手指绕另一个对象(self.target)旋转,一些动画精灵像自我运动的指南,围绕self.target通过bezier函数旋转。 algoritm是相当快,我永久初始化100多个指南,它工作没有CPU超载。

Small description: I have object (self) witch rotates by finger around another object (self.target), and i have some animated sprites like guides of self movement, which rotates around self.target by bezier function. algoritm is quite fast, i have permanent initialization of 100+ guides and it works without CPU overload.

/** Each bezier curve is an array with 8 floats, x1, y1, x2, y2, x3, y3, x4, y4., where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points. @note adapted for xCode by Valentine Konov valentine\@konov.su 2013 @return a array of objects that represent bezier curves which approximate the circular arc centered at the origin. @param startAngle to endAngle (radians) with the specified radius. */ -(NSArray*)createArcWithRadius:(float)radius_ withStartAngle:(float)startAngle_ withEndAngle:(float)endAngle_; { // OMLog(@"radius:%.2f startAngle:%.2f endAngle:%.2f",radius_,startAngle_,endAngle_); // normalize startAngle, endAngle to [-2PI, 2PI] float twoPI = M_PI * 2; float startAngle = startAngle_; float endAngle = endAngle_; // float startAngle = fmodf(startAngle_,twoPI); // float endAngle = fmodf(endAngle_,twoPI); // Compute the sequence of arc curves, up to PI/2 at a time. Total arc angle // is less than 2PI. NSMutableArray* curves = [NSMutableArray array]; float piOverTwo = M_PI / 2.0; float sgn = (startAngle < endAngle) ? 1 : -1; float a1 = startAngle; for (float totalAngle = fminf(twoPI, fabsf(endAngle - startAngle)); totalAngle > 0.00001f /*FLT_EPSILON*/; nil) { float a2 = a1 + sgn * min(totalAngle, piOverTwo); [curves addObject: [self createSmallArc:radius_ a1:a1 a2:a2]]; totalAngle -= fabsf(a2 - a1); a1 = a2; } return curves; } /** Cubic bezier approximation of a circular arc centered at the origin, This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378. @note adapted for xCode by Valentine Konov valentine\@konov.su 2013 @param from (radians) a1 to a2, where a2-a1 < pi/2 @return an array with 8 floats, x1, y1, x2, y2, x3, y3, x4, y4. where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points. */ -(NSArray*)createSmallArc:(float)r a1:(float)a1 a2:(float)a2 { // Compute all four points for an arc that subtends the same total angle // but is centered on the X-axis float a = (a2 - a1) / 2.0; // float x4 = r * cosf(a); float y4 = r * sinf(a); float x1 = x4; float y1 = -y4; float k = 0.5522847498; float f = k * tan(a); float x2 = x1 + f * y4; float y2 = y1 + f * x4; float x3 = x2; float y3 = -y2; // Find the arc points actual locations by computing x1,y1 and x4,y4 // and rotating the control points by a + a1 float ar = a + a1; float cos_ar = cosf(ar); float sin_ar = sinf(ar); return [NSArray arrayWithObjects: // [NSNumber numberWithFloat:(r * cosf(a1))], //startPoint.x [NSNumber numberWithFloat:(r * sinf(a1))], //startPoint.y [NSNumber numberWithFloat:(x2 * cos_ar - y2 * sin_ar)], //ctrlPoint1.x [NSNumber numberWithFloat:(x2 * sin_ar + y2 * cos_ar)], //ctrlPoint1.y [NSNumber numberWithFloat:(x3 * cos_ar - y3 * sin_ar)], //ctrlPoint2.x [NSNumber numberWithFloat:(x3 * sin_ar + y3 * cos_ar)], //ctrlPoint2.y [NSNumber numberWithFloat:(r * cosf(a2))], //endPoint.x [NSNumber numberWithFloat:(r * sinf(a2))], //endPoint.y nil]; } /** Bezier approximation example @note adapted for xCode by Valentine Konov valentine\@konov.su 2013 @param inSprite_ is sprite, angle_ signed angle radiants @return CCSequence of [CCSpawns of (CCBezierTo and CCRotateBy)] */ -(id)calcBezierCircle:(CCSprite*)inSprite_ withAngle:(float)angle_ { double speed = 100; //points per second CGPoint positionOffset = ccpSub(((CCNode*)self.target).position, self.position); //((CCNode*)self.target).position is circle center double startAngle = [self calcAngle:inSprite_.position ownerRelated:false]; while (startAngle<0) startAngle += 2*M_PI; while (startAngle>=2*M_PI) startAngle -= 2*M_PI; double endAngle = startAngle + angle_; float radius = [self calcRadius]; NSArray* curves = [self createArcWithRadius:radius withStartAngle:startAngle withEndAngle:endAngle]; NSMutableArray* bezierActions = [NSMutableArray array]; for (NSArray* curve in curves) { CGPoint startPoint = ccpAdd(ccp([[curve objectAtIndex:0] floatValue], [[curve objectAtIndex:1] floatValue]), positionOffset); CGPoint controlPoint1 = ccpAdd(ccp([[curve objectAtIndex:2] floatValue], [[curve objectAtIndex:3] floatValue]), positionOffset); CGPoint controlPoint2 = ccpAdd(ccp([[curve objectAtIndex:4] floatValue], [[curve objectAtIndex:5] floatValue]), positionOffset); CGPoint endPoint = ccpAdd(ccp([[curve objectAtIndex:6] floatValue], [[curve objectAtIndex:7] floatValue]), positionOffset); ccBezierConfig bezier; bezier.controlPoint_1 = controlPoint1; bezier.controlPoint_2 = controlPoint2; bezier.endPosition =endPoint; float bezierAngle = ccpAngleSigned(ccpSub(startPoint, positionOffset), ccpSub(endPoint, positionOffset)); float bezierDuration = radius*fabsf(bezierAngle)/speed; id bezierTo = [CCBezierTo actionWithDuration:bezierDuration bezier:bezier]; id rotateBy = [CCRotateBy actionWithDuration:bezierDuration angle:CC_RADIANS_TO_DEGREES(-bezierAngle)]; CCAction * bezierToAndRotateBy = [CCSpawn actions:bezierTo, rotateBy, nil]; [bezierActions addObject:bezierToAndRotateBy]; } if ([bezierActions count]<1) { return nil; } return [CCSequence actionWithArray:bezierActions]; } /** Calculates angle @param position_ current position of sprite on sircle, ownerRelated boolean, wich is startPoint is {1,0} or owner.position @return angle (radiant) */ -(float)calcAngle:(CGPoint)position_ ownerRelated:(bool)ownerRelated { if (ownerRelated) { CGPoint v1 = ccpSub(((CCNode*)self.target).position, self.position); CGPoint v2 = ccpSub(ccpSub(((CCNode*)self.target).position, self.position),position_); return ccpAngleSigned(v1, v2); } else { CGPoint v1 = ccp([self calcRadius], 0.0f); CGPoint v2 = ccpSub(position_,ccpSub(((CCNode*)self.target).position, self.position)); return ccpAngleSigned(v1, v2); } } /** Calculates radius @return radius */ -(float)calcRadius; { return sqrt(pow(self.position.x-((CCSprite*)self.target).position.x, 2)+pow(self.position.y-((CCSprite*)self.target).position.y, 2)); }

更多推荐

使用touch

本文发布于:2023-06-05 01:11:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/508794.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:touch

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!