代码之家  ›  专栏  ›  技术社区  ›  San

如何在cocos2d中检测抖动事件?

  •  1
  • San  · 技术社区  · 14 年前

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

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

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

    1 回复  |  直到 14 年前
        1
  •  2
  •   CodeSmile Paul Beusterien    14 年前

    也许下面的代码可以帮助你。不久前我发现了它(不记得在哪里)并把它清理干净了。您可以调整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];