确定Sprite是否旋转360度 - Cocos2d

时间:2011-05-05 22:19:49

标签: iphone cocos2d-iphone rotation

我有一个随触摸旋转的精灵。我需要能够确定它是否已旋转360度3次。有什么方法可以说出来吗?

这是我到目前为止所拥有的

#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];
    }

有人可以帮忙吗?提前致谢

1 个答案:

答案 0 :(得分:2)

cocos2d可以旋转超过360.但如果你左右移动,那么它比检查sprite.rotation == 1080更复杂一点。如果旋转发生在touchesMoved方法上,那么你应该做的是你应该记录你的最高旋转(右旋可能)和最低旋转(反过来)然后差异应该大于360 * 3。所以将2个类变量添加到G图层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

touchesMoved方法的最后,检查您的条件:

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

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

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

    // your condition is satisfied
}

我没有对此进行过测试,所以它可能是错误的......但它值得一试

编辑:

除非旋转发生在同一方向,否则上面的代码将无效。它不适用于你的右,左,右条件。我想一种方法是在touchesMoved中跟踪你的旋转方向。所以你再次需要班级变量

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

你的触摸方法:

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

touchesMoved结束时,您将拥有以下内容:

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;

希望这会有所帮助