I am a beginner in programming and I started to create a game in C++ where the player disappears from the screen(he dies) when a rock hits it.
What can i do to put the player back on the screen after 2 seconds?
I have number of lifes(LifeNb) a function which delete the player from the screen(removePlayer) and a function that add the player on the screen(addPlayer).
How can i do this using ?
int time = std::clock()/1000;
if(the rock hit) {
number of lives --;
remove player;
if(time == 2)
add player;
}
It's something like this?
One way to do it: When your player dies, store the current time (plus two seconds) to a variable. On each iteration of the game's event loop, check to see if the current time is greater than or equal to the time in the variable. If it is, restore the player, and set the variable's value to (a very large value that the clock will never reach).
clock_t timer = clock();
if ((clock()/CLOCKS_PER_SEC)-(timer/CLOCKS_PER_SEC) >= 2)
player.add();
If you just want to wait two seconds, however, you could also use the system library function sleep() for two seconds.
The sleep() function will delay for a specified number of seconds before continuing execution. It seems to be what you are looking for.
See here: http://pubs.opengroup.org/onlinepubs/009604599/functions/sleep.html
Related
I'm building a tetris game and I need the pieces to fall every x seconds; something like:
while(true){
moveDown();
sleep(x)
}
The problem is, I need to be able to move the pieces left and right in the meantime, i.e., call a function while it's sleeping.
How can I do that in c++?
Both time and key presses can be events which can be used to wait on. On UNIXes you'd use something like poll() with a suitable time for timeout and the input device used to recognize key presses. On other systems there are similar facilities (I'm a UNIX persons and I have never worked on Windows specific stuff although it seems the Windows facilities are actually more flexible). Depending on the result of poll() (timeout or activity on the I/O device in that case) you'd do the appropriate action.
This problem is solvable in multiple ways (another idea that comes to mind is multithreading, but that seems overkill). One approach would be to keep track of the number of "game cycles" and execute some function every n-th cycle like this:
for(int32_t count{1};;count++)
{
if (!count % 5)
{
// do something every 5th cycle
}
// do something every cycle
sleep(x);
}
you can measure how much time has passed since last fall and move piece down after given amount and then reset counter. In pseudo-code it could look like this:
while(true)
{
counter.update();
if(counter.value() == fall_period)
{
move_piece_down();
couter.reset();
}
// rotate pieces
}
If you are using typical implementation of game loop your counter can just accumulate elapsed time since last frame.
I am looking at trying to pause something in C++. Specifically a bullet you shoot in a space invaders game. Each time you press the UP key it fires a shot, I have been trying to find a way to pause it for a number of seconds before being able to fire again.
I've tried Sleep(); but it freezes the entire game rather than pauses the ability to press UP again.
Firing code
if (CInput::getInstance()->getIfKeyDownEvent(DIK_UP))
{
g_pGame->AddSprite(new CMissile(m_fX, m_fY+0.5*m_fH, 0.09, 0.9, 2));
}
Try taking the current time and then adding your delay to it. Store that in your shooting object. The next time through your program loop, if the current time is less than the time stored in the object, ignore the UP arrow.
Here are two simple ways to manage this.
When you fire a bullet, take the current system time and add the delay you want to it. If the player attempts to fire again while the current time is less than the variable you set, nothing happens.
Or, when you fire a bullet, set a timer variable to the delay you want. Each update, subtract delta time from the timer. When the timer is <=0, the user can fire.
Typically when you want to deal with real time seconds, you need something called delta time. Due to the inconsistency with frame rates, you need a way to measure real time. Typically you do this by counting the amount of time elapsed between frames. Here's an example of this implementation:
Source
int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
int oldTimeSinceStart = 0;
while( ... ) // main game loop
{
int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
int deltaTime = timeSinceStart - oldTimeSinceStart;
oldTimeSinceStart = timeSinceStart;
secondsSinceLastShot += deltaTime;
if (secondsSinceLastShot > shotTimer)
{
canShoot = true;
secondsSinceLastShot = 0;
}
if ( // press space or something )
{
canShoot = false;
// shoot
}
}
Note that this uses GLUT's implementation of a timer, but you need to implement that yourself (probably using clock()).
I've tried Sleep(); but it freezes the entire game rather than pauses the ability to press UP again.
Sleeping will freeze the thread, which is not what you want to do. However, sleep() is typically used in an implementation that contains delta time, usually sleep()ing for the amount of time elapsed between frames. For an example, see Lazy Foo's SDL tutorials
Ignore the fact that I linked to both OpenGL and SDL links, the principle is the same no matter the graphics library used.
I am trying to get my arduino mega to run a function in the background while it is also running a bunch of other functions.
The function that I am trying to run in the background is a function to determine wind speed from an anemometer. The way it processes the data is similar to that of an odometer in that it reads the number of turns that the anemometer makes during a set time period and then takes that number of turns over the time to determine the wind speed. The longer time period that i have it run over the more accurate data i receive as there is more data to average.
The problem that i have is there is a bunch of other data that i am also reading in to the arduino which i would like to be reading in once a second. This one second time interval is too short for me to get accurate wind readings as not enough revolutions are being completed by the anemometer to give high accuracy wind data.
Is there a way to have the wind sensor function run in the background and update a global variable once every 5 seconds or so while the rest of my program is running simultaneously and updating the other data every second.
Here is the code that i have for reading the data from the wind sensor. Every time the wind sensor makes a revolution there is a portion where the signal reads in as 0, otherwise the sensor reads in as a integer larger than 0.
void windmeterturns(){
startime = millis();
endtime = startime + 5000;
windturncounter = 0;
turned = false;
int terminate = startime;
while(terminate <= endtime){
terminate = millis();
windreading = analogRead(windvelocityPin);
if(windreading == 0){
if(turned == true){
windturncounter = windturncounter + 1;
turned = false;
}
}
else if(windreading >= 1){
turned = true;
}
delay(5);
}
}
The rest of the processing of takes place in another function but this is the one that I am currently struggling with. Posting the whole code would not really be reasonable here as it is close to a 1000 lines.
The rest of the functions run with a 1 second delay in the loop but as i have found through trial and error the delay along with the processing of the other functions make it so that the delay is actually longer than a second and it varies based off of what kind of data i am reading in from the other sensors so a 5 loop counter for timing i do not think will work here
Let Interrupts do the work for you.
In short, I recommend using a Timer Interrupt to generate a periodic interrupt that measures the analog reading in the background. Subsequently this can update a static volatile variable.
See my answer here as it is a similar scenario, detailing how to use the timer interrupt. Where you can replace the callback() with your above analogread and increment.
Without seeing how the rest of your code is set up, I would try having windturncounter as a global variable, and add another integer that is iterated every second your main program loops. Then:
// in the main loop
if(iteratorVariable >= 5){
iteratorVariable = 0;
// take your windreading and implement logic here
} else {
iteratorVariable++;
}
I'm not sure how your anemometer stores data or what other challenges you might be facing, so this may not be a 100% solution, but it would allow you to run the logic from your original post every five seconds.
I have done a memory tiles program but i want it to be timed, i.e, the user shoud be able to play the game only for 2 mins. what do i do?
Also in linux sleep() does not work, what should we use for a delay??
I presume the game has a "main loop" somewhere.
At the beginning of the main loop (before the actual loop), take the current time, call this start_time. Then in each iteration of the loop, take the current time again, call this now. The elapsed time is elapsed_time = now - start_time;. Assuming time is in seconds, then if (elapsed_time >= 120) { ... end game ... } would do the trick.
In pygame, I am using function "pressed_key"
This is my Code:
if(pressed_keys[K_y]):
base += 10;
But when I do it by pressing it only once, the "base" increased 200ish. I want to know if there is a way to increase the time between two entry?
Thanks for helping!
(p.s. I really dont know how to search similar questions on this question. I hope this is not duplicate. But in case it is, let me know. I will delete this question. Thanks again!)
Here http://www.pygame.org/docs/ref/key.html#pygame.key.set_repeat
pygame.key.set_repeat(delay, interval): return None
also:
pygame.key.get_pressed()[K_y]: return bool
another way is to get the time you accepted the "key pressing" ,and wait before accepting it again:
import time
interval = 100 #you set your interval in miliseconds
lasttime = 0
while 1:
draw() #draw routine
events() #another events
now = time.time() #save in one variable if you are going to test against more than one, reducing the number of time.time() calls
if(pressed_keys[K_y] and (now-lasttime)>interval):
lasttime = now
base += 10
time.time() Return the time in seconds since the epoch as a floating point number.
The epoch is the point where the time starts. On January 1st of that year, at 0 hours, the “time since the epoch” is zero. For Unix, the epoch is 1970.
knowing that, you are getting the time right now against the lasttime you saved it:
now-lasttime. When this delta is more than the interval, you are allowed to continue your event, don't forget to update your lasttime variable.
I hope you know enough about pygame to use a clock.
(For simplicity's sake we'll say the time interval required will be one second)
A simple solution would be to only check for input every second, using a simple counter and the pygame clock.
First off start the clock and the counter, outside of your main loop.
Also, add a boolean variable to determine if the key was pressed within this second.
FRAMERATE = 30 #(The framerate used in this example is 30 FPS)
clock = pygame.time.Clock()
counter = 0
not_pressed = True
Then inside the main loop, the first thing you do is increase the counter, then tick the clock.
while argument:
counter+=1
clock.tick(FRAMERATE)
Then were you have your code, an if statement to see if the button has been pressed this second:
if not_pressed:
if(pressed_keys[K_y]):
not_pressed=False
base += 10
#Rest of code:
if(pressed_keys[K_up]):
Finally, at the end of your main loop, add a checker to switch the boolean not_pressed back to True every second:
if counter == FRAMERATE:
counter=0
not_pressed=True
That should allow the program to only take input from the user once every second.
To change the interval, simply change the if counter == FRAMERATE: line.
if counter == FRAMERATE: would be 1 Second
if counter == (FRAMERATE*2): would be 2 Seconds
if counter == int(FRAMERATE/4): would be a quarter of a second*
*note- make sure you turn FRAMERATE divided by a number, into an integer, either by using int() surrounding the division, or by using integer division: (FRAMERATE//4)
For a similar example to see how everything fits, see this answer.
See also: Pygame: key.get_pressed() does not coincide with the event queue To use repeated movement while key is held down. Using state polling for those keys works better.