如何检测cocos2d中的摇动事件?

时间:2010-06-30 02:59:33

标签: ipad cocos2d-iphone

我想在iPad的cocos2d中检测摇动。

我发现了一篇很有前途的文章并试图实现它,但失败了。 http://www.softvelopment.com/index.php/blogs/2010/03/19/3-adding-shake-recongnition-to-cocos2d-iphone-library-

具体来说,我不确定应该把听众放在哪里。而且,有没有其他好的方法可以使用cocos2d让iPad检测震动?

1 个答案:

答案 0 :(得分:2)

也许以下代码可以帮助您。我找了一会儿(不记得在哪里)并清理干净了。您可以调整didAccelerate中的值,目前为0.8和0.2,以定义它对抖动的敏感程度以及您必须保持设备能够再次摇晃的稳定程度。

标题

@protocol ShakeHelperDelegate
-(void) onShake;
@end

@interface ShakeHelper : NSObject <UIAccelerometerDelegate>
{
    BOOL histeresisExcited;
    UIAcceleration* lastAcceleration;

    NSObject<ShakeHelperDelegate>* delegate;
}

+(id) shakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del;
-(id) initShakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del;

@end

实施

#import "ShakeHelper.h"


@interface ShakeHelper (Private)
@end

@implementation ShakeHelper

// Ensures the shake is strong enough on at least two axes before declaring it a shake.
// "Strong enough" means "greater than a client-supplied threshold" in G's.
static BOOL AccelerationIsShaking(UIAcceleration* last, UIAcceleration* current, double threshold) 
{
    double
    deltaX = fabs(last.x - current.x),
    deltaY = fabs(last.y - current.y),
    deltaZ = fabs(last.z - current.z);

    return
    (deltaX > threshold && deltaY > threshold) ||
    (deltaX > threshold && deltaZ > threshold) ||
    (deltaY > threshold && deltaZ > threshold);
}

+(id) shakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del
{
    return [[[self alloc] initShakeHelperWithDelegate:del] autorelease];
}

-(id) initShakeHelperWithDelegate:(NSObject<ShakeHelperDelegate>*)del
{
    if ((self = [super init]))
    {
        delegate = del;
        [UIAccelerometer sharedAccelerometer].delegate = self;
    }

    return self;
}

-(void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration 
{
    if (lastAcceleration)
    {
        if (!histeresisExcited && AccelerationIsShaking(lastAcceleration, acceleration, 0.8)) 
        {
            histeresisExcited = YES;

            [delegate onShake];
        }
        else if (histeresisExcited && !AccelerationIsShaking(lastAcceleration, acceleration, 0.2))
        {
            histeresisExcited = NO;
        }
    }

    [lastAcceleration release];
    lastAcceleration = [acceleration retain];
}

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

    [UIAccelerometer sharedAccelerometer].delegate = nil;
    [lastAcceleration release];
    [super dealloc];
}

@end

你这样使用它:

[ShakeHelper shakeHelperWithDelegate:self];

显然,self对象需要实现ShakeHelperDelegate协议。只要检测到震动,就会将onShake消息发送给委托对象。