Spawning Object issue - python

I am trying to get objects spawn on screen. But they don't seem to come up.
When exiting the game the sprites come up. It's only during the game you can't see any objects.
Exit = False
while not Exit:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == QUIT:
Exit = True
elif event.type == USEREVENT +1:
fireball.add(fire(screen, random.randint(50,1000), random.randint(50,800)))
fireball.update()
fireball.draw(screen)
pygame.display.flip()

Since you do not tell us, I'm going to assume that fireball is a sprite.Group and fire a child class of sprite.Sprite. From the little I can see, seems to be the correct guess.
So what you want is to create and add fire instances to the fireball group during the game.
You can achieve it by adding the following lines in the main loop before firefall.update():
newev = pygame.event.Event(USEREVENT+1)
pygame.event.post(newev)
This will create a custom event of type USEREVENT+1 which will be catch by the event checking loop next iteration, executing hence the line: fireball.add(fire(screen, random.randint(50,1000), random.randint(50,800)))
Maybe you do not want to create a new fire sprite each iteration. In that case you should add some flow control to skip those lines under some conditions.
For example, if you want a random approach, you can do:
if random.random() < 0.1:
newev = pygame.event.Event(USEREVENT+1)
pygame.event.post(newev)
In this case, each iteration of the main loop you have a 10% of probability to submit the custom event. Adjust the probability to your suits.
If instead you want to add a new fire sprite after a given amount of time, you need to measure the time with pygame.time.get_ticks(). If a given amount of time is passed, the event is submitted.
checktime = pygame.time.get_ticks() - reftime
if checktime > 5000: #5 seconds, the time is in milliseconds
reftime = pygame.time.get_ticks() #reset the reference time
newev = pygame.event.Event(USEREVENT+1)
pygame.event.post(newev)
And of course remember to define reftime = pygame.time.get_ticks() the first time before the main loop.
You can refer to this answer for another example on how to measure time with pygame.

Related

How can I create a timer that will start at a certain time and wont interupt my program in pygame?

I am making this game where you use the w, a, s, d keys to move a ball. I am trying to make a timer that starts when you press "start game". The problem is, when I do something like time.sleep, it interrupts the movement of the ball. I want to render the timer in the top right corner of the screen and make it 1 minute (also I will make a conditional statement for when the timer stops so I would like that to be possible).
This is what I believe would be easiest, and fit your needs the best.
clock = pygame.time.Clock()
fps = 60 # Or whatever frame-rate you want to cap the game at.
time = 0
game_started = False
# This is the main loop.
while True:
dt = clock.tick(fps)
if game_started:
time += dt
if time >= 60000: # 60 seconds.
game_started = False
# Then handle, events, update/draw objects etc.
Just set game_started = True when you press the button and the time variable will start to increment in time. Then you can just draw the time variable to the screen however you like. If you don't want to draw it when it isn't running then just blit it when game_started is True.

Change the character image for a while in Python Pygame

I am struggling with a problem I can't solve.
I want to change the image of my character when the enemy hurts it.
In pseudocode, it would be like this:
*If enemy collides -> player close eyes and get red;*
*After 0.50 seg -> player gets normal back again*
I tried to do it with Clock and Timers but it is very difficult. I only get changing the image, but not getting it back.
Any ideas?
Thank you!
I would assume it's as easy as this. pygame.time.set_timer(x, y) basically creates an x event on the event stack every y milliseconds.
# Main game loop
while True:
# display stuff and other parts of your game
# replace this with whatever detection you have for collision
if enemycollide:
player.setSprite(1)
pygame.time.set_timer(14, 500) # 500 milliseconds = .5 seconds
# event handling
for event in pygame.event.get():
if event.type == 14:
player.setSprite(0)
pygame.time.set_timer(14, 0) # Disable the timer

pygame: current time millis and delta time

As you can see in the below code I have a basic timer system
done = False
clock = pygame.time.Clock()
# Create an instance of the Game class
game = space_world.SpaceWorld()
# Main game loop
while not done:
# Process events (keystrokes, mouse clicks, etc)
done = game.process_events()
# Update object positions, check for collisions...
game.update()
# Render the current frame
game.render(screen)
# Pause for the next frame
clock.tick(30)
My question is, how can I get the current time milli seconds and how do I create delta time, so I can use it in the update method ?
ms = clock.tick(30)
The function returns milliseconds since the previous call.
From the documentation: pygame.time.Clock.get_time will return the number of milliseconds between the previous two calls to Clock.tick.
There is also pygame.time.get_ticks which will return the number of milliseconds since pygame.init() was called.
Delta-time is simply the amount of time that passed since the last frame, something like:
t = pygame.time.get_ticks()
# deltaTime in seconds.
deltaTime = (t - getTicksLastFrame) / 1000.0
getTicksLastFrame = t

how to prevent button spamming in pygame

basically, at the moment, in my game the user can shoot as many times as they wish... this defeats the objective of the game (it makes it too easy) as they can just spam bullets. I have a 'Shop' type function which enables the user to purchase upgrades, therefore the spamming defeats the purpose of the shop.
elif event.key == K_SPACE:
newBullet = {'rect': pygame.Rect(bulletX, bulletY, 10, 3), 'surface': bullet}
pistolSound.play()
bullets.append(newBullet)
This is the code, what can I add to it in order prevent the button mashing spam. I'm bad with the pygame time function, but I have a feeling that could be used.
Additionally, i would like to my zombies to spawn consistently instead of at the moment where it is quite random...
timer = clock.tick()
if waveNumber <= 2:
timer += 1
if timer == 2:
newZombie = {'rect':pygame.Rect(zombieX, zombieY, 75, 75), 'surface': zombie}
zombieSound.play()
zombies.append(newZombie)
timer = 0
How would I go about doing this? I think I'm using the time function wrong.
Many thanks, Will.
Limit the number of bullets to some small number:
elif event.key == K_SPACE:
if len(bullets) < 3:
newBullet = {'rect': pygame.Rect(bulletX, bulletY, 10, 3), 'surface': bullet}
pistolSound.play()
bullets.append(newBullet)
You should break your simulation and event handling into brief "turns" and allow the player to shoot only one bullet per turn (or even less).
The closest to your code example would be setting a "shot button pressed this turn" flag when the appropriate kind of event is processed, then after all events have been processed shooting at most once:
#each event
if event.key == K_SPACE:
playerShooting=True
...
#each turn
if playerShooting:
newBullet = {'rect': pygame.Rect(bulletX, bulletY, 10, 3), 'surface': bullet}
pistolSound.play()
bullets.append(newBullet)
playerShooting=False#clear to prepare for next turn
Zombies have a similar problem: you cannot predict the value of clock.tick(). Instead, spawn zombies at most once per turn (likely on a schedule, e.g. every fifth turn). The clock should be used to decide whether the main loop should proceed to game state update instead of waiting for further inputs, and to decide when to render frames.
For reference, a bad example and a good but incomplete example of PyGame main loops.

Do something every x (milli)seconds in pygame

I'm learing Python and Pygame, and my first thing I'm making is a simple Snake game. I'm trying to make it so that the snake moves once every 0.25 seconds. Here is the part of my code that loops:
while True:
check_for_quit()
clear_screen()
draw_snake()
draw_food()
check_for_direction_change()
move_snake() #How do I make it so that this loop runs at normal speed, but move_snake() only executes once every 0.25 seconds?
pygame.display.update()
I want all of the other function to run normally, but move_snake() to only occur once every 0.25 seconds. I've looked it up and found a few answers but they all seem too complicated for someone who's making their first ever Python script.
Would it be possible to actually get an example of what my code should look like rather than just telling me which function I need to use? Thanks!
There are several approaches, like keeping track of the system time or using a Clock and counting ticks.
But the simplest way is to use the event queue and creating an event every x ms, using pygame.time.set_timer():
pygame.time.set_timer()
repeatedly create an event on the event queue
set_timer(eventid, milliseconds) -> None
Set an event type to appear on the event queue every given number of milliseconds. The first event will not appear until the amount of time has passed.
Every event type can have a separate timer attached to it. It is best to use the value between pygame.USEREVENT and pygame.NUMEVENTS.
To disable the timer for an event, set the milliseconds argument to 0.
Here's a small, running example where the snake moves every 250 ms:
import pygame
pygame.init()
screen = pygame.display.set_mode((300, 300))
player, dir, size = pygame.Rect(100,100,20,20), (0, 0), 20
MOVEEVENT, t, trail = pygame.USEREVENT+1, 250, []
pygame.time.set_timer(MOVEEVENT, t)
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_w]: dir = 0, -1
if keys[pygame.K_a]: dir = -1, 0
if keys[pygame.K_s]: dir = 0, 1
if keys[pygame.K_d]: dir = 1, 0
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
if e.type == MOVEEVENT: # is called every 't' milliseconds
trail.append(player.inflate((-10, -10)))
trail = trail[-5:]
player.move_ip(*[v*size for v in dir])
screen.fill((0,120,0))
for t in trail:
pygame.draw.rect(screen, (255,0,0), t)
pygame.draw.rect(screen, (255,0,0), player)
pygame.display.flip()
Use the Clock module of Pygame to keep track of time. Specifically the method tick of the Clock class will report to you the number of milliseconds since the last time you called tick. Therefore you can call tick once at the beginning (or at the end) of every iteration in your game loop and store its return value in a variable called dt. Then use dt to update your time-dependent game state variables.
time_elapsed_since_last_action = 0
clock = pygame.time.Clock()
while True: # game loop
# the following method returns the time since its last call in milliseconds
# it is good practice to store it in a variable called 'dt'
dt = clock.tick()
time_elapsed_since_last_action += dt
# dt is measured in milliseconds, therefore 250 ms = 0.25 seconds
if time_elapsed_since_last_action > 250:
snake.action() # move the snake here
time_elapsed_since_last_action = 0 # reset it to 0 so you can count again

Categories

Resources