So right now, i have a platformer and i want to make it so when i click on a button, the whole game restarts.
In main.py:
level=Level(level_map,screen)
while running:
if game_state=='game_active':
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
level.run()
screen.blit(sky_surface,(0,0))
pygame.display.update()
clock.tick(60)
in level.py:
class Level:
def __init__(self,level_data,surface):
self.display_surface=surface
self.level_building(level_data)
def level_building(self,tilesheet):
self.coins=pygame.sprite.Group()
self.player=pygame.sprite.GroupSingle()
for row_index,row in enumerate(level_map):
for col_index,cell in enumerate(row):
self.x=col_index*tile_size
self.y=row_index*tile_size
if cell=='R':
self.coin_sprite=Recyclables((self.x+22,self.y+55))
self.coins.add(self.coin_sprite)
if cell=='P':
self.player_sprite=Player((self.x+10,self.y))
self.player.add(self.player_sprite)
def collisions(self):
playercoin=pygame.sprite.groupcollide(self.coins,self.player,True,False) # kills the coin (to show it has been picked up)
if len(playercoin)==1:
self.score+=1
def run(self):
self.coins.draw(self.display_surface)
self.collisions()
self.player.draw(self.display_surface)
After my game finishes running, what is a good way to restart everything, and respawn all the sprites that were killed? (did not show the kill code since it'd be too long) so far i've tried killing all sprites after the game but i don't know how to re-draw everything.
In PyGame, you're in full control of what's being drawn on the screen every frame, so I'm not sure why you wouldn't be sure how to redraw things.
Since you apparently have already encapsulated your game logic into the Level class, restarting the level shouldn't require more than just
level = Level(level_map, screen)
so subsequent calls to level.run() use a fresh level.
(Also, unless you're doing esoteric things that you're not showing us here, you shouldn't necessarily need to even "kill sprites".)
Related
I want to completely prevent the user from closing the Pygame window except for the key x. Currently, I'm able to prevent the user from closing it, but I am unable to prevent the user from opening another window that overlaps it (press windows key -> open chrome, which overlaps the Pygame window).
import sys
import pygame
from pygame.locals import *
pygame.init()
infoObject = pygame.display.Info()
screen = pygame.display.set_mode((infoObject.current_w, infoObject.current_h), flags=pygame.NOFRAME)
while True:
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
pygame.quit()
sys.exit()
if event.type == QUIT:
pass
pygame.display.flip()
We don't have complete solutions for this task.
You can make the title var vanish away by setting display mode to NOFRAME (You have already used this): pygame.display.set_mode(flags = pygame.NOFRAME), but this is overkill for just stopping close buttons
Although any user with minimum Computer Knowledge will fire up a Task manager and kill python.exe :-(
There are ways of disabling task manager through Registry in Windows, Image File Execution Options blah blah, but your game script will barely run with Administrator priviliges (With nagging of UAC)
In order to do this, you can add this piece of code to your pygame.display.set_mode():
pygame.display.set_mode(..., flags=pygame.NOFRAME). Now, the bar with the "x" button will disapear.
Notice that if you decide to make this change, you won't be able to move your game window anymore. (Unless you change it back).
I wanted to make a game using pygame and I started my code making the pygame window
import pygame
pygame.init()
pygame.display.set_mode((1500, 1000))
But every time I run the program, my pygame window does not respond.
Does anyone know what is happening, this did happen to me on previous codes too but it wasn't all the time like it is now
you need a game loop to start the game and you need events to work on.
for python code i suggest:
import pygame
pygame.init()
pygame.display.set_mode((1500, 1000))
start_game = True
while start_game:
print("Game Started!")
and for the events you can use this code in the while loop:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
print("mouse button up pressed")
the source of this code is : RipTutorial
I assume that by 'my pygame window does not respond' you mean that you believe the window is not displaying. I think that you are just missing it because it is closing too quickly.
The window does display, but because your program ends right after you create the window, the window is immediately closed again. This is likely just happening so quickly that you are not noticing it. If you want to see this, then just put a call to sleep after opening the window and you will see the window sit there until the sleep expires and then it will close.
If you do not mean that and you are seeing the window but expecting it to respond, then I do not understand what you expect it to respond to. You do not have any code that tries to make it respond to anything.
EDIT:
I just noticed that #AnassABEA suggests that in a comment under his answer, though not in his answer. #AnassABEA you should update your answer to include this since I believe that is the actual answer to his question, not the missing event loop.
Add this below to your code:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
Lines 4 to 5 of the code are for closing pygame when the window is closed.
I'm a new in PyGame and I was making a game. Until I discovered that when you were moving the window to another place of your desktop for example, the game temporarily stops. But ticks of the game still running when I used pygame.time.get_ticks().
So I made a completely new program with only the necessary code and it does the same thing.
Can someone explain me why it does it and if we can resolve this problem?
import pygame
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption('The Test Program')
running = True
update_counter = 1
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
print(str(update_counter) + " updates")
update_counter += 1
pygame.quit()
quit()
# So try to move the window across your screen and you will see that, prints will stop and they will resume when you will release the click
So someone tell me that was normal, so I think it's only on Windows but there are no solutions. I put a script that show a pause symbol on screen when the cursor leave the window to make it normal.
I am beginner and learning about pygame. I am following a tutorial to a simple game and I can not figure out what the problem is. I have a crash function and use a time.sleep(). But the time sleep occurs earlier making whole code kind of useless.
I am working on Mac but I do not think that should be causing this.
I have tried to put time.sleep() into another function and use that one in the crash function but that does not work as well and I am not sure if time.sleep have some kind of preference.
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
game_loop()
def crash():
message_display('You Crashed')
The first two function should not be the problem but I posted them just to be sure.
So when the car in game crashes, it is supposed to write big "You Crashed", then wait 2 seconds and restart the game with game_loop() function. But it stops the game, waits 2 seconds, then writes "You Crashed" and immediately restart the game.
This happens because, after you update the screen surface with pygame.display.flip() or pygame.display.update(), you'll have to process events (by e.g. calling pygame.event.get) to give the window the chance to redraw itself.
This may work on Windows, because the window management works different there, but it would still be "wrong".
You have to stick to these rules:
never ever call time.sleep (unless you know better)
never ever call pygame.display.update() or pygame.display.flip() outside of your main loop (unless you know better)
never ever have more than one game loop (unless you know better)
your game runs in a loop, so to do anything that is based on "time" (like: print this for 2 seconds, do this in 4 seconds, etc), you have to keep track of the time in your game state (probably just a variable)
don't call your game loop from your game loop
have a basic idea of how your game should work, which states in can be in, and how you move between the states, and what happens in each state.
A simple example, let's say we want to create a little racing game, so we could think of these states:
Title screen
The actual racing game
Game over screen
An easy implementation whould just have a variable state and a big if/else block in the main loop:
if state == 'TITLE_SCREEN':
...render title screen...
...if the space bar was pressed set state = 'GAME'
elif state == 'GAME':
...render the player, obstacles, etc...
...if the player crashed, set state = 'GAMEOVER' and keep track of the current time, e.g. with `timer = pygame.Clock().get_ticks()`
elif state == 'GAMEOVER':
...render a game over message...
...if the space bar was pressed or `pygame.Clock().get_ticks() - timer > 2000` set state = 'GAME'
Similar problem:
Two display updates at the same time with a pygame.time.wait() function between
pygame.time.wait() makes the window freez
pygame - how to update HP bar slowly without time.sleep()
More about game states:
Pygame level/menu states
Probably also interesting:
Threading issue with Pygame
How do you make the code stop for a moment before checking for something else? (I'm new to code)
if BonusTime==True and Drop==True:
if event.type == pygame.MOUSEBUTTONDOWN:
window.blit(Fired,(mouseX-12,mouseY-12))
Cankill=True
#I want it to delay here
Cankill=False
There is a cross hair that follows the mouse and when I click it, it fires. The problem is, you can just hold the mouse down and leave the cross hair in one place. Whenever an enemy walks into the cross hair, they die. I need it so even when you hold it will only fire once. I plan to make it delay the if statement, to set "Cankill" to true and then wait a second, after waiting, it should set "Cankill" to false. I've already looked through a lot of other people's questions similar to this and haven't found something I can understand. So if you could please help me find out how to delay it in the way I need.
"Pausing" is not what you want - if you do that, your game will just freeze, and nothing will move (since you are usign the OS mouse pointer, maybe it could move).
Anyway, the function to "pause" inside a game is pygame.time.wait(1000) - the number is in miliseconds.
Waht you actually need is to mark down the time the click was made, continue with the game, and when 1 second has passed, reset the variable back to the other state.
Something along:
last_trigger = 0
while True:
# game updating code goes here (getting events, and such)
...
if Cankill and pygame.time.get_ticks() - last_trigger > 1000:
Cankill = False
if event.type == pygame.MOUSEBUTTONDOWN:
window.blit(Fired,(mouseX-12,mouseY-12))
Cankill=True
last_trigger = pygame.time.get_ticks()
The "get_ticks" call returns the number of miliseconds that passed since pygame was initialized - and is usefull for this time of timers.