Jonathan
Jonathan

Reputation: 2383

Determine if Sprite Rotated 360 Degrees - Cocos2d

I have a sprite that rotates with touch. I need to be able to determine if it has rotated 360 degrees 3 times. Is there any way to tell?

Here is what I have so far

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "GameScene.h"



@interface G : CCLayer {

    CCSprite *g;

    CGFloat gRotation;
}

@end

------------------------------------------
#import "G.h"


@implementation G

-(id) init
{
    if ((self = [super init]))
    {
        CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);

        g = [CCSprite spriteWithFile:@"g.png"];

        [self addChild:g z:-1];
    }
    return self;
}

- (void)update:(ccTime)delta
{
    g.rotation = gRotation;
}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

}

- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    CGPoint firstLocation = [touch previousLocationInView:[touch view]];
    CGPoint location = [touch locationInView:[touch view]];

    CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
    CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];

    CGPoint firstVector = ccpSub(firstTouchingPoint, g.position);
    CGFloat firstRotateAngle = -ccpToAngle(firstVector);
    CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);

    CGPoint vector = ccpSub(touchingPoint, g.position);
    CGFloat rotateAngle = -ccpToAngle(vector);
    CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);

    gRotation += currentTouch - previousTouch;
}

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{

}

- (void) dealloc
{
    CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);

    [super dealloc];
}

@end

GameScene

#import "GameScene.h"
#import "MainMenu.h"
#import "G.h"


@implementation GameScene

+(CCScene *) scene
{
    CCScene *scene = [CCScene node];
    GameScene *layer = [GameScene node];

    [scene addChild: layer];
    return scene;
}

-(void) tapG: (id) sender
{

    G *gView;
    gView = [[G alloc] init];
    gView.position = ccp(100, 100);

    [self.parent addChild:gView z:1001];

    [gView scheduleUpdate];

    [gView release];
}
-(id) init
{
    if ((self = [super init]))
    {
tG = [CCMenuItemImage itemFromNormalImage:@"tp.png" selectedImage:@"tp.png"  disabledImage:@"tpaperd.png" target:self selector:@selector(tapG:)];

        gt = [CCMenu menuWithItems:tG, nil];
        gt.position = ccp(210, 80);
        [gt alignItemsHorizontallyWithPadding:10];

        [self addChild:gt z:0];

    }
    return self;
}
- (void) dealloc
    {
        CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);

        [super dealloc];
    }

Can anyone help? Thanks in advance

Upvotes: 0

Views: 990

Answers (1)

KDaker
KDaker

Reputation: 5909

cocos2d can take rotations more than 360. but if your going left and right then its a bit more complicated than just checking if sprite.rotation == 1080. if the rotation is happening on your touchesMoved method then what you should do is that you should record your highest rotation (rotation in right maybe) and lowest rotation (the other way) and then the difference should be bigger than 360*3. so add 2 class vars to your G layer float maxRot,minRot;

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    maxRot = mySprite.rotation; // here you set the ivars to defaults. 
    minRot = mySprite.rotation; // im setting them to your sprite initial rotation
}                               // incase it is not 0

at the end of your touchesMoved method you check for your conditions:

if (mySprite.rotation > maxRot)
   maxRot = mySprite.rotation;

else if (mysprite.rotation < minRot)
   minRot = mySprite.rotation;

if ((maxRot - minRot) >= (360*3)) {

    // your condition is satisfied
}

i havent tested this so it could be just wrong.. but its worth a shot

EDIT:

the code above will not work unless the rotations are happening in the same direction.. it wont work for your right, left, right condition. I guess one way is to track the direction of your rotation in touchesMoved. so again youll need class vars

int numOfRots;
float previousRot, currentRot, accumRot;
BOOL isPositive, isPreviousPositive;

your touches methods:

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    previousRot = mySprite.rotation; 
    currentRot = mySprite.rotation;
    accumRot = 0;
    numOfRots = 0;
    isPositive = NO;
    isPreviousPositive = NO;
}

at the end of touchesMoved you will have the following:

currentRot = mySprite.rotation;

if (currentRot > previousRot)
    isPositive = YES;
else
    isPositive = NO;

if (isPositive != isPreviousPositive) {

    // now we have a change in direction, reset the vars
    accumRot = 0;
}

if (isPositive) {

   accumRot += abs(currentRot - previousRot);
}

else {

   accumRot += abs(previousRot - currentRot); 
}


if (accumRot >= 360) {

    //now we have one rotation in any direction.
    numOfRots++;        
    //need to reset accumRot to check for another rot
    accumRot = 0;


    if (numOfRots == 3) {

        //BINGO!!! now you have 3 full rotations
    }
}

previousRot = currentRot;
isPreviousPositive = isPositive;

hope this helps

Upvotes: 2

Related Questions