Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Delay using Clock  (Read 19589 times)

0 Members and 1 Guest are viewing this topic.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« on: May 08, 2011, 11:49:23 am »
Hey everybody

I've finished my game (almost) and I have one obstacle left. Now if i can fix this everything will work as it is the key to my spawn engine. The goal is to add a ring sprite to the vector every time the clock reaches the delay time constant.

First part at the top of main():
Code: [Select]
// Initialise counter for ring spawn delay

sf::Clock Clock;
float Time = Clock.GetElapsedTime();
Clock.Reset();


Second part whilst App is running and player alive:
Code: [Select]
// Spawn Rings

if (Time == DELAY_TIME)
{

// Add ring sprite to the ringSpawn vector

ringVec.push_back(Ring);

// Give that ring a random y co ordiante

spawnIterator->SetX(0);
spawnIterator->SetY(rand_Y);

// Increment iterator

spawnIterator++;

// Reset the clock

Clock.Reset();


}


Can you see what's going wrong? Xcode produces no errors and I've followed everything in the tutorial.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Delay using Clock
« Reply #1 on: May 08, 2011, 11:52:33 am »
You should use "Time >= DELAY_TIME", you will most likely never have a strict equality between Time and DELAY_TIME.
Laurent Gomila - SFML developer

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #2 on: May 08, 2011, 12:38:42 pm »
Thanks for that laurent. I think maybe the problem is somewhere else as I just adjusted the code and to my surprise still no success. I sent my time to cout and i got the figure
Code: [Select]
9.53674e-07

Any reason why that might be?

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
Delay using Clock
« Reply #3 on: May 08, 2011, 03:48:28 pm »
You aren't incrementing Time anywhere, by the looks of it.
In you main loop, somewhere, you need:
Code: [Select]

   Time += Clock.GetElapsedTime();

Hope that fixes it.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #4 on: May 08, 2011, 07:02:58 pm »
I thought clock self increments as time goes on after the last reset? I did not know I had to manually increment it myself :/

Just out of interest where abouts do you suggest I increment it in my code?

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #5 on: May 08, 2011, 07:11:46 pm »
I just tried placing that code above the spawn part and now I've got some crazy error. At first my compiler went crazy when I tried using the arrow keys to move like normal, and now after removing the code my background is offset by a couple pixels despite being set at (0, 0).

Curse you tntexplosivesltd!!!

 - Simon

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #6 on: May 08, 2011, 07:30:26 pm »
Ok so I got the whole set up working alright but I've still got the background problem for bo reason. It was working fine until I f***ed it up a couple of debug's ago...

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #7 on: May 08, 2011, 08:20:10 pm »
Hey everybody

Ok so now I've got three problems:

1) My background is still shifted. I changed the color when app calls clear() and It's actually showing me that part of the screen is not covered. Yet none of those numbers have changed.

2) I had to change the code that tntexplosivesltd gave me and now when I send it to cout it increments by 0.000000001 not by 1 second as the sfml tutorials say?

3) As soon as my time variable gets to the set delay time and the spawn code executes the program crashes and comes up with an error I've never seen before. Also when the program crashes I have to kill it through the compiler which I NEVER have to do, so my only guess is I'm doing something highly illegal? Heres the code:

Code: [Select]
// Initialise counter for ring spawn delay

sf::Clock Clock;
float time = 0;
float ElapsedTime = Clock.GetElapsedTime();
Clock.Reset();


and

Code: [Select]
// Spawn Rings

time += ElapsedTime;

if (time >= DELAY_TIME)
{

// Add ring sprite to the ringSpawn vector

ringVec.push_back(Ring);

// Give that ring a random y co ordiante

spawnIterator->SetX(0);
spawnIterator->SetY(rand_Y);

// Increment iterator

spawnIterator++;

// Reset the clock

Clock.Reset();


}


Also to see the crash screenshot heres the Link - I know laurent hates when I post big screenshots on here :)

 - Simon

p.s. reaaally sorry bou the multiple posts. I guess that's my first reaction after I get scared  :shock:

Mjonir

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Delay using Clock
« Reply #8 on: May 08, 2011, 08:50:36 pm »
Why are you resetting the clock all the time exactly? It looks like what you want to do is get the current time, why not just use the clock instead of another variable?

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #9 on: May 08, 2011, 09:03:41 pm »
I'm not. I call reset in main() once and then whilst the app is running (the scond part of code) I reset it after each time a ring is spawned

tntexplosivesltd

  • Full Member
  • ***
  • Posts: 163
    • View Profile
Delay using Clock
« Reply #10 on: May 08, 2011, 10:47:34 pm »
Yes, you are right that the clocks increments ITSELF after the last time it was reset.
There is a tiny problem in the way you are testing whether the correct amount of time has passed.
You code looks like this:
Code: [Select]

    // Spawn Rings
         
      time +=   ElapsedTime;
     
      if (time >= DELAY_TIME)
      {
         
         // Add ring sprite to the ringSpawn vector
         
         ringVec.push_back(Ring);
         
         // Give that ring a random y co ordiante
         
         spawnIterator->SetX(0);
         spawnIterator->SetY(rand_Y);
         
         // Increment iterator
         
         spawnIterator++;
         
         // Reset the clock
         
         Clock.Reset();
         
         
      }

The problem is that when you first start the game, the elapsed time is very very small.
Instead of that, change your code to this:
Code: [Select]

    // Spawn Rings
         
      time +=   Clock.GetElapsedTime();
     
      if (time >= DELAY_TIME)
      {
         
         // Add ring sprite to the ringSpawn vector
         
         ringVec.push_back(Ring);
         
         // Give that ring a random y co ordiante
         
         spawnIterator->SetX(0);
         spawnIterator->SetY(rand_Y);
         
         // Increment iterator
         
         spawnIterator++;
         
         // Reset the clock
         
         Clock.Reset();
         
         
      }

That way, the time between spawns will always be DELAY_TIME, even if there is lag suddenly somewhere. In the first example, you take a snapshot of the time taken for one loop at the very beginning of the game, before the main loop has started, This will always be a VERY small number.
This should fix some of the errors you are getting.
I'm not sure what you did after the first post, but what I suggested shouldn't have caused that at all.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
Delay using Clock
« Reply #11 on: May 08, 2011, 11:08:26 pm »
Ahh thanks, just tried put that in thanks. It's fixed the whole increment problem and I've also finally fixed the background one but for some reason my thing still says "EXC_BAD_ACCESS" which leads me to believe that i'm screwing up with like a memory leak due to it showing me the faulty memory address.

So what's happening in my code is that i'm creating a vector of sprites and for every 3 seconds i want to execute the code you've already seen. Then after that I want to move the vector along the x axis using a for loop and incrementing the x co ordiantes. Now I know this may come off as being lazy, but really I just want to get the bug fixed. so heres the code involving the vector and maybe somebody can point out where i'm going wrong:

Code: [Select]
// Set up rings vector

vector <sf::Sprite> ringVec;

vector <sf::Sprite>::iterator spawnIterator = ringVec.begin();

vector <sf::Sprite>::iterator ringIterator = ringVec.begin();


Then theres the one you've seen before. Then this:

Code: [Select]
// Check ring collision

for (ringIterator = ringVec.begin(); ringIterator < ringVec.end(); ringIterator++)
{
float ringPos = ringIterator->GetPosition().x;

if ( (WaterMelon.GetPosition().x < ringPos + (UPPER_RBOUND - 20)) && (WaterMelon.GetPosition().x > ringPos + (LOWER_RBOUND + 20)) )
{

// Add to score if melon passes through ring

score += RING_POINTS;

}

else if (
(ringPos + RING_Y) > WaterMelon.GetPosition().x > ringPos + (RING_Y - 20) ||
(ringPos - RING_Y) < WaterMelon.GetPosition().x < ringPos - (RING_Y + 20)
)
{


}

}



// Move Rings


for (ringIterator = ringVec.begin(); ringIterator < ringVec.end(); ringIterator++)
{

Move(-moveSpeed, 0.f, *ringIterator);

}


// Check if rings out of bounds

for (ringIterator = ringVec.begin(); ringIterator < ringVec.end(); ringIterator++)
{
float ringPos = ringIterator->GetPosition().x;

if (ringPos < 0 - (RING_Y / 2))
{

ringVec.erase(ringIterator);

}

}


Then finally to draw:
Code: [Select]
// Draw all Rings

for (ringIterator = ringVec.begin(); ringIterator != ringVec.end(); ringIterator++)
{

App.Draw(*ringIterator);

}



Thanks a lot guys.

 - Simon