Cocos2d中用手指旋转精灵

发布于 2024-10-21 16:54:08 字数 2583 浏览 5 评论 0原文

我需要帮助用手指计算精灵的旋转。精灵旋转得很好,但在我手指第一次触摸时,它不知何故自行旋转了几度。

此外,只有当手指围绕精灵中心旋转时,旋转才起作用。

我正在尝试模拟自行车车轮,并有一个齿轮精灵和一个踏板精灵作为齿轮精灵的子级。我希望当我触摸踏板并旋转它时自行车车轮也旋转。我还没到那一步。现在我正在尝试找出如何消除齿轮的初始变速。

这是完整的代码,

#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

如果该行:

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

实际上应该是:

CGPoint vector = ccpSub(touchingPoint, previousTouchingPoint );

我有点困惑,我也尝试过,但它不起作用。

我还将完整的 xcodeproj 上传到 4shared,供任何想在这里查看的人使用: http: //www.4shared.com/file/5BaeW4oe/Healthy.html

I need help figuring out the rotation of a sprite with my finger. The sprite is rotating fine but on the initial touch of my finger it somehow rotates by a few degrees by itself.

Also the rotations only work when the finger is rotated around the center of the sprite.

I am trying to simulate the bicycle wheel and have a gear sprite and a pedal sprite as a child of the gear sprite. I want the bicycle wheel to rotate as I touch the pedal and rotate it. I haven't got that far yet. Right now I am trying to figure out how to get rid of the initial shift the gear makes.

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 slightly confused if the line:

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

should actually be:

CGPoint vector = ccpSub(touchingPoint, previousTouchingPoint );

I tried that as well but it didn't work.

I have also uploaded my complete xcodeproj to 4shared for anyone who wants to take a look here: http://www.4shared.com/file/5BaeW4oe/Healthy.html

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

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

发布评论

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

评论(2

下雨或天晴 2024-10-28 16:54:08
@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
{

}

编辑:很抱歉我无法让它保持在代码模式。但这就是解决方案,并且应该很容易在您的代码中实现。干杯!

@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: I am sorry I can't get this to stay in code mode. But this is the solution and it should be easy to implement in your code. cheers!

当爱已成负担 2024-10-28 16:54:08

ccTouchesBegan 中,使用与 ccTouchesMoved 中相同的代码来确定角度,然后使用 CCRotateTo 移动到该角度。您需要在 CCRotateTo 处于活动状态时对用户移动手指进行一些处理,可能会停止当前操作并启动另一个操作以移动到新角度。

In ccTouchesBegan, use the same code as what you've got in ccTouchesMoved to determine the angle, then move to that angle using CCRotateTo. You will need some handling of the user moving his finger while CCRotateTo is active, perhaps stopping the current action and kicking off another one to move to the new angle.

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