【问题标题】:How can I create a count down timer for cocos2d?如何为 cocos2d 创建倒数计时器?
【发布时间】:2010-10-01 14:17:45
【问题描述】:

我正在使用 cocos2d 开发一个 2D iPhone 游戏。我需要一个倒数计时器。如何在 cocos2d 中创建倒计时?

【问题讨论】:

    标签: iphone objective-c cocos2d-iphone


    【解决方案1】:

    没有足够的代表支持汤姆,但他是绝对正确的。在这个问题的背景下, NSTimer 是错误的解决方案。 Cocos2d 框架提供了一个调度程序,该调度程序与其他游戏功能(如暂停/恢复)集成(并且很可能在后台使用 NSTimer)。

    来自上述链接的示例:

    -(id) init
    {
        if( ! [super init] )
            return nil;
    
        // schedule timer
        [self schedule: @selector(tick:)];
        [self schedule: @selector(tick2:) interval:0.5];
    
        return self;
    }
    
    -(void) tick: (CCTime) dt
    {
        // bla bla bla
    }
    
    -(void) tick2: (CCTime) dt
    {
        // bla bla bla
    }
    

    【讨论】:

    • 并且类似地使用 [self unschedule:@selector(tick2:)] 在 tick2: 当你希望它停止重复时。
    • [自我计划:@selector(tick:)];当我尝试在我的代码中执行此操作时...我的应用程序找不到时间表...这是哪个类的功能...?
    • @mihir CCLayer 我相信,通常作为超类
    【解决方案2】:

    http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:best_practices

    • 尝试使用 Cocoa 的 NSTimer。而是使用 cocos2d 自己的调度器。
    • 如果您使用 cocos2d 调度程序,您将拥有:
      • 自动暂停/恢复。
      • Layer(Scene、Sprite、CocosNode)进入舞台后自动开启定时器,离开舞台后自动关闭。
      • 您的目标/选择器将以增量时间调用...

    【讨论】:

      【解决方案3】:

      在 cocos 2d 中有默认的定时器更新部分。

      试试这个:

      [self schedule:@selector(update:)];
      - (void)update:(ccTime)dt {
      }
      

      【讨论】:

        【解决方案4】:

        对于那些想要使用 NSTimer 而不是“schedule”方法的人,您可以创建一个如下所示的类:

        ZIMCountdownTicker.h

        #import <Foundation/Foundation.h>
        
        extern NSString * const ZIMCountdownTickerTickAction;
        extern NSString * const ZIMCountdownTickerResetAction;
        
        @protocol ZIMCountdownTickerProtocol;
        
        /*!
         @class             ZIMCountdownTicker
         @discussion        This class creates a countdown ticker.
         @updated           2011-03-05
         */
        @interface ZIMCountdownTicker : NSObject {
        
            @private
                NSTimer *_timer;
                id<ZIMCountdownTickerProtocol> _delegate;
                NSTimeInterval _interval;
                double _period;
                double _value;
        
        }
        
        /*!
         @method                initWithDelegate:withTimeInterval:forTimePeriod:
         @discussion            This method instantiate an instance of this class with the specified parameters.
         @param delegate        A reference to a class that has implemented ZIMCountdownTickerProtocol.
         @param interval        The time interval in seconds to be used when running the countdown ticker.
         @param period          The time period in seconds for which countdown ticker will run.
         @updated               2011-03-05
         */
        - (id) initWithDelegate: (id<ZIMCountdownTickerProtocol>)delegate withTimeInterval: (NSTimeInterval)interval forTimePeriod: (double)period;
        /*!
         @method                start
         @discussion            This method will start the countdown ticker.
         @updated               2011-03-05
         */
        - (void) start;
        /*!
         @method                stop
         @discussion            This method will stop the countdown ticker.
         @updated               2011-03-05
         */
        - (void) stop;
        /*!
         @method                reset
         @discussion            This method will reset the countdown ticker.
         @updated               2011-03-06
         */
        - (void) reset;
        /*!
         @method                value
         @discussion            This method will return the countdown ticker's current value; however, using this method will cause
                            the ticker to stop.
         @return                The countdown ticker's current value.
         @updated               2011-03-05
         */
        - (double) value;
        
        @end
        
        @protocol ZIMCountdownTickerProtocol <NSObject>
        
        @optional
        /*!
         @method                countdownTicker:didUpdateValue:withAction:
         @discussion            This method will notify the delegate with the current value.
         @param ticker          A reference to tiggering ticker.
         @param value           The current value.
         @param action          The action that tiggered this method.
         @updated               2011-03-05
         */
        - (void) countdownTicker: (ZIMCountdownTicker *)ticker didUpdateValue: (double)value withAction: (NSString *)action;
        /*!
         @method                countdownTickerDidFinish:
         @discussion            This method will notify the delegate that the countdown ticker finished.
         @param ticker          A reference to tiggering ticker.
         @updated               2011-03-05
         */
        - (void) countdownTickerDidFinish: (ZIMCountdownTicker *)ticker;
        
        @end
        

        ZIMCountdownTicker.m

        // Ziminji Classes
        #import "ZIMCountdownTicker.h"
        
        NSString * const ZIMCountdownTickerTickAction = @"ticker.tick";
        NSString * const ZIMCountdownTickerResetAction = @"ticker.reset";
        
        /*!
         @category          ZIMCountdownTicker (Private)
         @discussion        This category defines the prototypes for this class's private methods.
         @updated           2011-03-05
         */
        @interface ZIMCountdownTicker (Private)
            /*!
             @method            countdown:
             @discussion        This method is called by the timer to decrement the counter's value and will send
                            the delegate the updated value.
             @param timer       The timer currently in use.
         @updated           2011-03-06
            */
            - (void) countdown: (NSTimer *)timer;
        @end
        
        @implementation ZIMCountdownTicker
        
        - (id) initWithDelegate: (id<ZIMCountdownTickerProtocol>)delegate withTimeInterval (NSTimeInterval)interval forTimePeriod: (double)period {
            if (self = [super init]) {
                _delegate = delegate;
                _interval = interval;
                _period = period;
                _value = period;
                _timer = nil;
            }
            return self;
        }
        
        - (void) start {
            if (_timer == nil) {
                _timer = [NSTimer scheduledTimerWithTimeInterval: _interval target: self selector: @selector(countdown:) userInfo: nil repeats: YES];
            }
        }
        
        - (void) stop {
            if (_timer != nil) {
                [_timer invalidate];
                _timer = nil;
            }
        }
        
        - (void) reset {
            [self stop];
            _value = _period;
            if ((_delegate != nil) && [_delegate respondsToSelector: @selector(countdownTicker:didUpdateValue:withAction:)]) {
                [_delegate countdownTicker: self didUpdateValue: _value withAction: ZIMCountdownTickerResetAction];
            }
        }
        
        - (double) value {
            [self stop];
            return _value;
        }
        
        - (void) countdown: (NSTimer *)timer {
            _value -= 1;
            if ((_delegate != nil) && [_delegate respondsToSelector: @selector(countdownTicker:didUpdateValue:withAction:)]) {
                [_delegate countdownTicker: self didUpdateValue: _value withAction: ZIMCountdownTickerTickAction];
            }
            if (_value <= 0) {
                [self stop];
                if ((_delegate != nil) && [_delegate respondsToSelector: @selector(countdownTickerDidFinish:)]) {
                    [_delegate countdownTickerDidFinish: self];
                }
            }
        }
        
        - (void) dealloc {
            if (_delegate != nil) {
                [_delegate release];
            }
            if (_timer != nil) {
                [_timer invalidate];
            }
            [super dealloc];
        }
        
        @end
        

        【讨论】:

          【解决方案5】:

          看看 NSTimer,它很可能提供任何需要的计时器功能。

          NSTimer class reference

          【讨论】:

            【解决方案6】:
            -(id) init
            {
                if( ! [super init] )
                    return nil;
            
                // schedule timer
                [self schedule: @selector(tick:)];
                [self schedule: @selector(tick2:) interval:0.5];
            
                return self;
            }
            
            -(void) tick: (ccTime) dt
            {
                //some function here
            }
            
            -(void) tick2: (ccTime) dt
            {
                //some function here
            }
            

            【讨论】:

            • 这是使用cocos2d的错误方式,你需要照别人说的做,使用[self schedule:]的东西。最大的原因是使用 NSTimer 不支持 cocos2d 的 pause、start、stop 命令,而 schedule 会。
            • 需要再说一遍:不要使用NSTimer!这是错误的。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-07-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-13
            • 1970-01-01
            相关资源
            最近更新 更多