SFML community forums
Help => General => Topic started by: Father_Sloth 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():
// Initialise counter for ring spawn delay
sf::Clock Clock;
float Time = Clock.GetElapsedTime();
Clock.Reset();
Second part whilst App is running and player alive:
// 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.
-
You should use "Time >= DELAY_TIME", you will most likely never have a strict equality between Time and DELAY_TIME.
-
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
9.53674e-07
Any reason why that might be?
-
You aren't incrementing Time anywhere, by the looks of it.
In you main loop, somewhere, you need:
Time += Clock.GetElapsedTime();
Hope that fixes it.
-
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?
-
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
-
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...
-
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:
// Initialise counter for ring spawn delay
sf::Clock Clock;
float time = 0;
float ElapsedTime = Clock.GetElapsedTime();
Clock.Reset();
and
// 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 (http://i1105.photobucket.com/albums/h349/Father_Sloth/Screenshot2011-05-08at185256.png) - 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:
-
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?
-
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
-
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:
// 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:
// 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.
-
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:
// 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:
// 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:
// Draw all Rings
for (ringIterator = ringVec.begin(); ringIterator != ringVec.end(); ringIterator++)
{
App.Draw(*ringIterator);
}
Thanks a lot guys.
- Simon