3

I am making a reaction game, where you can destroy enemys and earn points. Now I would like to have combo points if you destroy them fast and if there is a specific time gap the combo multiplier should go to zero again.

I would like to multiple the points like this: 2 * 2 = 4 * 2 = 8 * 2 = 16 * 2... (you get 2 points if you destroy an enemy).

I add the points here:

if (CGRectIntersectsRect(enemy.frame, player.frame)) {
        points = points + 1;
        [enemy removeFromParent];
    }

I could always multiply the current points with 2, but I want to reset the combo multiplier if there is specific amount of time without getting points.

I hope someone can help me. (code in objective c please)

ccdev
  • 87
  • 6
  • You could probably go with something like this : first, define what you consider as "fast". Eg, track the time when last enemy is destroyed, and if a delay between the next destroyed enemy is smaller than x milliseconds, increase the bonus multiplier. The second part would be checking how much time has passed since last destroyed enemy, and based on that, decrease the multiplier. – Whirlwind Jan 24 '16 at 23:41

2 Answers2

1

It seems no more complicated than recording the time the last enemy was destroyed and then in the update: method deciding if the combo has elapsed as no more enemies were hit in whatever timeout period you allow.

I am not familiar with Sprite kit, but the update appears to pass the current time; excellent. You will need to record the following:

  • timeout (time): The current timeout. This will reduce as the game progresses, making it harder.
  • lastEnemyKillTime (time): the time the last enemy was killed.
  • comboPoints (integer): How many points the user gets per hit. This will increase as the combo extends.
  • points (integer): The current score.

So, something like this:

@interface MyClass ()
{
    NSTimeInterval _timeout;
    NSTimeInterval _lastEnemyKillTime;
    BOOL _comboFactor;
    NSUInteger _points;

}
@end

I guess Sprite Kit uses an init: method; use it to initialize the variables:

- (id)init
{
    self = [super init];
    if (self != nil) {
        _timeout = 1.0;
        _lastEnemyKillTime = 0.0;
        _points = 0;
        _comboPoints = 1;
    }
}

The update: method would be something like:

- (void)update:(NSTimeInterval)currentTime
{
    BOOL withinTimeout = currentTime - _lastEnemyKillTime <= _timeout;
    if (CGRectIntersectsRect(enemy.frame, player.frame)) {
        _inCombo = withinTimeout;
        if (_inCombo)
            _comboPoints *= 2;
        _points += _comboPoint;
        _lastEnemyKillTime = currentTime;
        [enemy removeFromParent];
    } else if (_comboPoints > 1 && !withinTimeout) {
        _lastEnemyKillTime = 0.0;
        _comboPoints = 1;
    }
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • Thank you ! Can you give me this code in objective c ? – ccdev Jan 24 '16 at 23:45
  • 1
    @ccdev That is Objective-C :) – trojanfoe Jan 24 '16 at 23:46
  • @ccdev I have updated my answer; it wasn't quite what you asked for. – trojanfoe Jan 24 '16 at 23:57
  • @ trojanfoe I have 3 questions: 1. what means: BOOL withinTimeout = currentTime - _lastEnemyKillTime <= _timeout; ? I am not familiar with these kind of operators. 2. Where can i set the the interval i want ? 3. why is there only a removefromparent in the "else" and not in the "if". Sorry for all these beginner questions.. – ccdev Jan 24 '16 at 23:59
  • @ccdev 1) It will make `withinTimeout = YES` if the current frame is within your timeout period. The `<=` operator returns a boolean result. It's used later to make decisions. 2) In the `init:` method, but you will also change it as time progresses to make the game harder in the `update:` method, though it's not clear to me exactly how that will be done. 3) It's done in the `if` part, not the `else` part. – trojanfoe Jan 25 '16 at 00:02
  • it doesn't work. "BOOL withinTimeout = currentTime - _lastEnemyKillTime <= _timeout;" never gets true. – ccdev Jan 25 '16 at 01:03
  • Okay i got it know. I played a bit with the code and did it finally, thanks – ccdev Jan 25 '16 at 01:40
0

You need to keep track on the last enemy casual timestamp and the factor. When the next kill is processed, you check the timestamp, if it is below threshold, you raise the factor. The time of the current kill replaces the timestamp.

You could create a FightRecorder class as singleton, if you don't have a better place yet (services or sth).

NSDate *newKillTime = new NSDate;

FightRecorder recorder = [FightRecorder instance];
if([newKillTime timeIntervalSinceDate:recorder.lastKillTime] < SCORE_BOUNDS_IN_SEC) {
    recorder.factor++; // could also be a method
    points = points + [recorder calculateScore];  // do your score math here
}
else {
    [recorder reset];  // set the inner state of the fight recorder to no-bonus
}

recorder.lastKillTime = newKillTime; // record the date for the next kill
thst
  • 4,592
  • 1
  • 26
  • 40