Finger sprite rotation in Cocos2d

I need help determining the sprite rotation with my finger. The sprite rotates perfectly, but the first time it touches a finger, it somehow rotates a few degrees by itself.

Also, rotation only works when the finger rotates around the center of the sprite.

I try to simulate a bicycle wheel and have a sprite sprite and a sprite pedal in my childhood sprite sprite. I want the bike wheel to spin when I touch the pedal and turn it. So far I have not succeeded. Right now I'm trying to figure out how to get rid of the initial gear shift.

Here is the complete code

#import "BicycleScene.h" @implementation BicycleScene +(id) scene { // 'scene' is an autorelease object. CCScene *scene = [CCScene node]; // 'layer' is an autorelease object. BicycleScene *layer = [BicycleScene node]; // add layer as a child to scene [scene addChild: layer]; // return the scene return scene; } -(id) init { if ((self=[super init])) { CGSize winSize = [[CCDirector sharedDirector] winSize]; //place the bicycle sprite bicycleSprite = [CCSprite spriteWithFile:@"bike_gear.png"]; bicycleSprite.position = ccp(bicycleSprite.contentSize.width/2 + 100, winSize.height/2); [self addChild:bicycleSprite z:1]; //place the pedal sprite pedalSprite = [CCSprite spriteWithFile:@"bike_pedal.png"]; [bicycleSprite addChild:pedalSprite z:1]; pedalSprite.position = ccp(150, 15); //enable touch self.isTouchEnabled = YES; [self schedule:@selector(gameLoop:) interval:.1/100]; } return self; } -(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ NSLog(@"Touch begun"); } -(void)gameLoop:(ccTime) dt{ bicycleSprite.rotation = cocosAngle; } -(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ NSLog(@"Touch moved"); UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:[touch view]]; CGPoint previousLocation = [touch previousLocationInView:[touch view]]; CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location]; CGPoint previousTouchingPoint = [[CCDirector sharedDirector] convertToGL:previousLocation]; CGPoint vector = ccpSub(touchingPoint, bicycleSprite.position); CGFloat rotateAngle = -ccpToAngle(vector); previousAngle = cocosAngle; cocosAngle = CC_RADIANS_TO_DEGREES( rotateAngle); //bicycleSprite.rotation = cocosAngle; } @end 

I am a little confused if the line:

 CGPoint vector = ccpSub(touchingPoint, bicycleSprite.position); 

should be:

 CGPoint vector = ccpSub(touchingPoint, previousTouchingPoint ); 

I tried too, but it didn’t work.

I also uploaded my full xcodeproj to 4shared for those who want to look here: http://www.4shared.com/file/5BaeW4oe/Healthy.html

+3
source share
2 answers
 @interface MainScene : CCLayer { CCSprite *dial; CGFloat dialRotation; } + (id)scene; @end --------------------------------- @implementation MainScene + (id)scene { CCScene *scene = [CCScene node]; CCLayer *layer = [MainScene node]; [scene addChild:layer]; return scene; } - (id)init { if((self = [super init])) { CCLOG(@"MainScene init"); CGSize size = [[CCDirector sharedDirector]winSize]; dial = [CCSprite spriteWithFile:@"dial.png"]; dial.position = ccp(size.width/2,dial.contentSize.height/2); [self addChild:dial]; self.isTouchEnabled = YES; [self scheduleUpdate]; } return self; } - (void)dealloc { [super dealloc]; } - (void)update:(ccTime)delta { dial.rotation = dialRotation; } - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { } - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 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, dial.position); CGFloat firstRotateAngle = -ccpToAngle(firstVector); CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle); CGPoint vector = ccpSub(touchingPoint, dial.position); CGFloat rotateAngle = -ccpToAngle(vector); CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle); //keep adding the difference of the two angles to the dial rotation dialRotation += currentTouch - previousTouch; } - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { } 

EDIT: Sorry, I can't make this stay in code mode. But this is a solution, and it must be easily implemented in code. Hooray!

+9
source

In ccTouchesBegan use the same code as your ccTouchesMoved to determine the angle, then go to that corner using CCRotateTo . You will need some manipulation of the user moving his finger while CCRotateTo active, possibly stopping the current action and letting go of another to move to a new angle.

0
source

Source: https://habr.com/ru/post/984387/


All Articles