Cocos2d 的定时事件

发布于 2024-12-22 12:58:56 字数 321 浏览 1 评论 0原文

我正在寻求建议,也许还有一些例子。我试图弄清楚如何创建一个CCSprite,并让玩家在创建它后尽可能接近int aCertainAmountOfTime来触摸它。我希望玩家的分数由他们击中该物品的 1 秒标记的接近程度来确定,太早或太晚的分数较低。

通过创建某种时间表更新或勾选来最好地解决这个问题吗?我从来没有这样做过,我对它的逻辑有点困惑。我理解这个需求,但不知道如何实现。

我知道这个问题很模糊,但我有点迷失,任何建议将不胜感激。有人可以分享一个基本示例,说明计划更新标记何时相关以及代码的外观吗?

感谢您处理我的歧义=D

I'm looking for advice, and maybe a few examples. I'm trying to figure out how to create a CCSprite and have the player touch it as close to int aCertainAmountOfTime after it was created as possible. I want the player's score to be determined by how close to the 1 second mark they hit the item, with a lower score for being too early or too late.

Would this be best solved by creating some sort of schedule update, or a tick? I've never done that, and I'm a bit confused about the logic of it. I understand the need, but not how to implement it.

I know this question is vague, but I'm a little bit lost, and any advice would be appreciated. Can someone share a basic example of when a scheduled update tick would be relevant, and how the code would look?

Thanks for dealing with my ambiguity =D

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

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

发布评论

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

评论(4

怀念你的温柔 2024-12-29 12:58:57

我将通过创建 sprite 的子类来实现这一点,例如 MySprite ,其中包含一个浮动计数器作为私有成员实例。

然后在你的主循环中,

-(void) nextFrame:(ccTime) dt {

[mysprite tick:dt]

if( mysprite.isExpired ) {
  //stuff here
}

在你的触摸方法中,当你触摸精灵时,你可以

float score = mysprite.score;

实现tick和属性isExpired,并且分数非常简单

-(void) tick:(ccTime) dt {
  counter += dt; //increment the private counter
}

@property(只读,非原子)BOOL isExpired;

-(BOOL) isExpired {
return counter > TIME_LIMIT ? YES : NO;
}

和@property(只读,非原子)浮点分数只是根据经过的时间返回您的计算机分数

i would do that by creating a subclass of sprite , say MySprite with a float counter inside as a private member instance.

then in your main loop say

-(void) nextFrame:(ccTime) dt {

[mysprite tick:dt]

if( mysprite.isExpired ) {
  //stuff here
}

in your touch method, when you thouch the sprite you can get

float score = mysprite.score;

implementing tick and properties isExpired and score is pretty straightforward

-(void) tick:(ccTime) dt {
  counter += dt; //increment the private counter
}

@property (readonly, nonatomic) BOOL isExpired;

-(BOOL) isExpired {
return counter > TIME_LIMIT ? YES : NO;
}

and @property (readonly, nonatomic) float score simply return your computer score based on time elapsed

怪我闹别瞎闹 2024-12-29 12:58:57

创建一个 CCNode 子类。我们将其称为自定义。在 Custom 中,将有一个 CCSprite 实例(称为 mySprite)和一个 float 属性(称为 myTimer)。到目前为止,我们得到了这样的信息:

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface Custom : CCNode {
    CCSprite *mySprite;
    float myTimer;
}
@property(readwrite)float myTimer;
@end

很好。记得在Custominit函数中初始化myTimer。该值将为0.0

现在转到您的游戏场景。在这里我们将制定一个时间表。转到游戏场景的 init 函数并输入:

[self schedule:@selector(updateCustomTimers:)interval:0.1];

当然,您必须在游戏场景类中创建一个 updateCustomTimers 方法。好,现在您所要做的就是迭代您拥有的每个 Custom 实例并增加它们的计时器:

-(void)updateCustomTimers {
    for (Custom *myCustomInstance in arrayOfCustomInstances) {
        myCustomInstance.myTimer += 0.1;
    }
}

请注意,arrayOfCustomInstances 是一个 NSMutableArray ,它是应该保存游戏场景中的所有 Custom 实例。因此,每当您创建新的 Custom 实例时,请将其也添加到数组中。

现在,您可以为游戏中的每个精灵(包装在自定义类中)更新单独的计时器。从这里开始评分计算应该很容易(您可以使用 myTimer float 属性访问您获得的任何 Custom 实例的计时器)。

Create a CCNode subclass. We'll call it Custom. Within Custom, there will be a CCSprite instance (called mySprite) and a float property (called myTimer). So far we got something like this then:

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface Custom : CCNode {
    CCSprite *mySprite;
    float myTimer;
}
@property(readwrite)float myTimer;
@end

Good. Remember to initialize myTimer in the init function of Custom. The value would be 0.0.

Now go to your game scene. Here we will set a schedule. Go to the init function of your game scene and put:

[self schedule:@selector(updateCustomTimers:)interval:0.1];

Naturally, you will have to create a updateCustomTimers method in your game scene class. Good, now all you have to do is iterate through every Custom instance you have and increase their timers:

-(void)updateCustomTimers {
    for (Custom *myCustomInstance in arrayOfCustomInstances) {
        myCustomInstance.myTimer += 0.1;
    }
}

Note that arrayOfCustomInstances is an NSMutableArray which is supposed to hold all instances of Custom in your game scene. So whenever you create a new Custom instance, add it also to the array.

Now you have a way to update individual timers for every single sprite (wraped in a custom class) in your game. The scoring calculation should be easy from here (you can access the timer of any Custom instance you got by using the myTimer float property).

花海 2024-12-29 12:58:56

我的解决方案非常简单,您只需将其添加到 CCSprite 类的 init 方法中:

[self scheduleUpdate];

然后 update 只计算自创建以来的时间(lifeTime 是在类的 @interface 中声明的 float ivar):

-(void) udpate:(ccTime)delta
{
   lifeTime += delta;
}

当用户触摸sprite,只需从 lifeTime 中减去 1 即可得到相对于 1 秒的时间差:

-(void) playerTouchedMe
{
   int diff = lifeTime - 1.0f;
}

如果 diff 为负数,则玩家触摸得太早了这么多秒。如果 diff 为正,则玩家触碰的时间太晚了这么多秒。为了获得绝对差异,您可以使用 fabsf,即基本上它只是删除标志(如果有):

int absoluteDiff = fabsf(diff);

完成。

My solution is quite simple, you only need to add this to your CCSprite class' init method:

[self scheduleUpdate];

Then update just counts the time since it was created (lifeTime is a float ivar declared in the class' @interface):

-(void) udpate:(ccTime)delta
{
   lifeTime += delta;
}

When the user touches the sprite, just subtract 1 from lifeTime to get the time difference relative to 1 second:

-(void) playerTouchedMe
{
   int diff = lifeTime - 1.0f;
}

If diff is negative, the player touched too early by this many seconds. If diff is positive, the player touched too late by this many seconds. And to get the absolute difference you'd use fabsf, ie basically it just removes the sign (if any):

int absoluteDiff = fabsf(diff);

Done.

满天都是小星星 2024-12-29 12:58:56

根据您的解释,我认为安排更新来处理此问题有点矫枉过正,而且毫无意义。

您可以通过组合 CCSprite 和 NSDate 来创建对象,以保存其放置在场景上的时间(可能在 -(void)onEnter 上),添加触摸检测( CCTouchDispatcher 的 addTargetedDelegate )并比较触摸日期和创建日期之间的差异与你的时间量。

如果您需要代码示例,请告诉我,我稍后会添加。这是用手机写的。

编辑:添加缺失的代码

@interface TimedObject : CCNode <CCTargetedTouchDelegate> {
    CCSprite    *sprite_;
    NSDate      *spawnDate_;
    NSUInteger  amountOfTime_;
}

-(id)initWithSprite:(CCSprite *)sprite andTime:(NSUInteger)amountOfTime;

@end

@implementation TimedObject

-(id)initWithSprite:(CCSprite *)sprite {
    if (self = [super init]) {
        sprite_ = sprite;
        [sprite_ setPosition:ccp(sprite_.contentSize.width * 0.5, sprite_.contentSize.height * 0.5)];
        [self addChild:sprite_];

        [self setContentSize:sprite_.contentSize];

        amountOfTime_ = amountOfTime;
    }
}

-(void)onEnter {
    [super onEnter];

    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

    spawnDate_ = [[NSDate date] retain];
}

-(void)onExit {
    [super onExit];

    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
    [spawnDate_ release];
    spawnDate_ = nil;
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint touchLocation = [touch locationInView:touch.view];
    touchLocation = [self convertToNodeSpace:touchLocation];

    CGRect touchArea;
    touchArea.origin = CGPointZero;
    touchArea.size = self.contentSize;

    if(CGRectContainsPoint(touchArea, touchLocation)) {
        // Tapped inside

        NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:spawnDate_];

        // Check here and handle
        if (interval > amountOfTime) {
            // over
        }
        else {

        }

        return YES;
    }

    return NO;
}

@end

From what you explained, I think that scheduling an update to handle this would be overkill and kind of pointless.

You could create your object by composing CCSprite and a NSDate to hold the time it was placed on the scene (probably on -(void)onEnter ), add touch detection ( CCTouchDispatcher's addTargetedDelegate) and comparing the difference between the touch date and the creation date with your amount of time.

If you need code example let me know and I'll add it later. This is written from a phone.

Edit: Adding missing code

@interface TimedObject : CCNode <CCTargetedTouchDelegate> {
    CCSprite    *sprite_;
    NSDate      *spawnDate_;
    NSUInteger  amountOfTime_;
}

-(id)initWithSprite:(CCSprite *)sprite andTime:(NSUInteger)amountOfTime;

@end

@implementation TimedObject

-(id)initWithSprite:(CCSprite *)sprite {
    if (self = [super init]) {
        sprite_ = sprite;
        [sprite_ setPosition:ccp(sprite_.contentSize.width * 0.5, sprite_.contentSize.height * 0.5)];
        [self addChild:sprite_];

        [self setContentSize:sprite_.contentSize];

        amountOfTime_ = amountOfTime;
    }
}

-(void)onEnter {
    [super onEnter];

    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

    spawnDate_ = [[NSDate date] retain];
}

-(void)onExit {
    [super onExit];

    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
    [spawnDate_ release];
    spawnDate_ = nil;
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint touchLocation = [touch locationInView:touch.view];
    touchLocation = [self convertToNodeSpace:touchLocation];

    CGRect touchArea;
    touchArea.origin = CGPointZero;
    touchArea.size = self.contentSize;

    if(CGRectContainsPoint(touchArea, touchLocation)) {
        // Tapped inside

        NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:spawnDate_];

        // Check here and handle
        if (interval > amountOfTime) {
            // over
        }
        else {

        }

        return YES;
    }

    return NO;
}

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