判断精灵是否旋转360度 - Cocos2d

发布于 2024-11-05 05:52:51 字数 2705 浏览 0 评论 0原文

我有一个通过触摸旋转的精灵。我需要能够确定它是否已旋转 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];
    }

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你与清晨阳光 2024-11-12 05:52:51

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 中跟踪旋转方向。所以你再次需要你的 Touches 方法的类变量

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;

希望这有帮助

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文