1
\$\begingroup\$

I'll make my player respawn after 1 of his lives is taken, but I want him to be invincible for 2 or 3 seconds and not instadie again because he will be in the way of enemy bullets.

for (int i = 0; i < MAX_BULLETS; i++) if (enemyB[i]) {
    if(globalTime % 2 == 0)
        enemyB[i]->y -= enemyB[i]->dx;
    if (player->alive && (enemyB[i]->x > player->x && enemyB[i]->x < player->x + 97 && enemyB[i]->y == player->y-15))
    {
        if (player->invincible == false) {
            player->life -= 25;
            player->hbSprite++;
        }
        if (player->life <= 0) {
            player->invincible = true;
            player->lives--;
            player->life = 100;
            player->lifeSprite++;
            player->hbSprite = 0;
            if (player->lives <= 0) {
                player->alive = 0;
                player->hbSprite = 4;
                player->lifeSprite = 3;
            }
        }
        removenemyB(i);
    }
}

When I set player->invicible = true he's not taking dmg , but I need him to do that only for 2 or 3 seconds , help pls.

\$\endgroup\$
  • \$\begingroup\$ Well you need to create some sort of timer (at least manually keep track of how much time has elapsed since you set invincible to true) - What have you tried doing so far? \$\endgroup\$ – UnholySheep Jan 4 '17 at 18:19
  • \$\begingroup\$ Nothing really , I don't really understood the sdl_ticks(); function .. I think I can use it..maybe? \$\endgroup\$ – FIREHIVE Jan 4 '17 at 18:27
  • \$\begingroup\$ That would be one option (although probably not the best one). You could also try using SDL_AddTimer. \$\endgroup\$ – UnholySheep Jan 4 '17 at 18:31
  • \$\begingroup\$ By the way a quick google search showed this tutorial which seems to do the same thing you need (also using SDL_GetTicks(), so maybe I was wrong and it is a good solution) \$\endgroup\$ – UnholySheep Jan 4 '17 at 18:33
1
\$\begingroup\$

Given that you are working with SDL2, SDL_GetTicks() is the most straightforward solution. SDL_AddTimer is also an option, but you would have to deal with a bit of multi-threading, unnecessary repeated executions, and callback functions.

I see that you have a globalTime variable, which I am inclined to incorporate as part of my answer, but I don't have enough context with the code you've provided to be sure how that variable is updated.

That being said, replace setting invincibility with the game time that the player will no longer be invincible:

// ...
if (player->life <= 0) {
    player->endInvincibleTime = SDL_GetTicks() + 3000; // 3 seconds
// ...

// endInvincibleTime is Uint32 type

This amounts to setting a marker at some fixed point in the future. Game time will eventually pass it, permanently.

Then, instead of checking for invincibility, just check if game time has passed endInvincibleTime:

// ...
if (player->endInvincibleTime < SDL_GetTicks()) {
    player->life -= 25;
    player->hbSprite++;
}
// ...

SDL_GetTicks returns an unsigned 32 bit integer, meaning that from the moment SDL_Init is called its timer starts counting milliseconds and it is able to count up to 49 days worth of milliseconds.


Note that I am suggesting here that you use SDL_GetTicks as your game duration/timing system directly, but that is only for the sake of example. There are other ways of tracking time. For example using different timing libraries , or in STL. They more-or-less amount to better precision and/or more reliable response time. Here's some more reading on C timers Always be wary of integer overflow/wrap-around. Especially when using unsigned integers.

\$\endgroup\$
  • \$\begingroup\$ A better name for endInvincibleTime might be respawnTime as that is what the player is doing. \$\endgroup\$ – TOM__ Jan 4 '17 at 20:35
  • \$\begingroup\$ This should work. It's good to inform people of the existence of other methods but if the asking user is already using the SDL library SDL_GetTicks is the recommended method, and millisecond precision is enough for what he is doing. \$\endgroup\$ – Hatoru Hansou Jan 5 '17 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.