So I was making a game in python with pygame and I had some assets as characters. I coded everything correctly. But when I run the program none of the images show up and the window crashes immediately.
import pygame
import os
import random
WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Fly game")
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
FPS = 60
VEL = 5
BORDER = pygame.Rect(WIDTH//2 - 5, 0, 10, HEIGHT)
PLAYER_WIDTH, PLAYER_HEIGHT = 55, 40
SKY = pygame.image.load(
os.path.join('C:\\Users\\Kostadin Klemov\\Desktop\\Programms\\Python\\projects\\Fly game\\Assets\\SKY.jpg')), (WIDTH, HEIGHT)
JETPACK_MAN_IMAGE = pygame.image.load(
os.path.join('C:\\Users\\Kostadin Klemov\\Desktop\\Programms\\Python\\projects\\Fly game\\Assets\\JETPACK_MAN.jpg'))
JETPACK_MAN = pygame.transform.scale(
JETPACK_MAN_IMAGE, (PLAYER_WIDTH, PLAYER_HEIGHT))
FLY_IMAGE = pygame.image.load(
os.path.join('C:\\Users\\Kostadin Klemov\\Desktop\\Programms\\Python\\projects\\Fly game\\Assets\\FLY.png'))
FLY = pygame.transform.scale(
FLY_IMAGE, (PLAYER_WIDTH, PLAYER_HEIGHT))
def draw_window(jetpack, fly):
WIN.blit(SKY, (0, 0))
pygame.draw.rect(WIN, BLACK, BORDER)
WIN.blit(JETPACK_MAN, (jetpack.x, jetpack.y))
WIN.blit(FLY, (fly.x, fly.y))
pygame.display.update()
def main():
jetpack = pygame.Rect(225, 250, PLAYER_WIDTH, PLAYER_HEIGHT)
fly = pygame.Rect(675, 250, PLAYER_WIDTH, PLAYER_HEIGHT)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
draw_window(jetpack, fly)
main()
if __name__ == "__main__":
main
No error showed up so I didn't know what was wrong.
If you can, please check out the code and try to fix it!
This is an indentation error.
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
# <---- INDENTATION
# this should be in the while loop, the "game loop", not in the quit condition
draw_window(jetpack, fly)
Also, you probably don't want to call main() after you program terminates. (Assuming you want people to be able to exit your game easily.
if __name__ == "__main__":
main
This main does nothing, it needs to be called, like main(). With the parentheses. It's not "crashing instantly," it's just not running anything.
SKY = pygame.image.load(
os.path.join('C:\\Users\\Kostadin Klemov\\Desktop\\Programms\\Python\\projects\\Fly game\\Assets\\SKY.jpg')), (WIDTH, HEIGHT)
That (WIDTH, HEIGHT) at the end is very suspicious. Presumably you just want the image put in the SKY variable, not another random tuple.
On another note, os.path.join() does nothing if you give it the full path as an argument.
Related
I wrote a small code to try working with pygame for the first time, but I'm having trouble getting the game window to respond to any input at all including the exit button. No matter if I run the code through Sublime, VScode, or Python the window loads fine but the sprite takes no input (so fare I have only coded left) nor will the window close. If I want to close the window I have to close whatever editor/terminal I'm running the program through
import pygame
import os
pygame.display.set_caption("CyberPunk 3077")
WIDTH, HEIGHT = 900, 500
PLAYER, SIZE = 34, 34
WIN = pygame.display.set_mode((WIDTH,HEIGHT))
'''We have now created the window and it's size
Now lets create the background display'''
FPS = 60
VELOCITY = 3
WHITE = ((255, 255, 255))
MID_BORDER = pygame.Rect((WIDTH/2)-2.5, 0,5, HEIGHT) #this will place a solid line in the middle of the screen
Player_1 = pygame.transform.scale(pygame.image.load(os.path.join('skins', 'player.png')), (PLAYER,SIZE))
P1 = pygame.transform.rotate(Player_1, 270)
Player_2 = pygame.transform.scale(pygame.image.load(os.path.join('skins', 'enemy.png')), (PLAYER,SIZE))
P2 = pygame.transform.rotate(Player_2, 270)
SKY = pygame.transform.scale(pygame.image.load(os.path.join('skins', 'bg.png')), (WIDTH,HEIGHT))
#this will search our folder 'skins' for the file 'bg' to make our background
def draw(yellow, blue):
WIN.blit(SKY, (0,0))
pygame.draw.rect(WIN, WHITE, MID_BORDER)
WIN.blit(P1, (yellow.y, yellow.y))
WIN.blit(P2, (blue.x, blue.y))
#pygame starts tracking at the top left with 0,0
pygame.display.update()
def P1_moves(keys_pressed, yellow):
if keys_pressed[pygame.K_a] and yellow.x - VELOCITY > 0: #LEFT
yellow.x -= VELOCITY
'''this is the only instance of movement I have coded so far. Didn't want to continue if I can't even get 'left' to work '''
def main():
yellow = pygame.Rect(200, 250, 32, 32)
blue = pygame.Rect(650, 250, 32, 32)
run = True
clock = pygame.time.Clock()
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run == False
keys_pressed = pygame.key.get_pressed()
P1_moves(keys_pressed, yellow)
draw(yellow, blue)
pygame.quit()
if __name__ == "__main__":
main()
The keys_pressed[pygame.K_a] should be keys_pressed[pygame.K_A] (capital 'A').
Rabbid76 answered this problem in a comment.
run = False instead of run == False
WIN.blit(P1, (yellow.x, yellow.y)) instead of WIN.blit(P1, (yellow.y, yellow.y))
Rabbid76 Sep 15 at 18:18
I'm having trouble with the framerate in my game. I've set it to 60 but it only goes to ~25fps. This was not an issue before displaying the background (was fine with only win.fill(WHITE)). Here is enough of the code to reproduce:
import os, pygame
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50, 50)
pygame.init()
bg = pygame.image.load('images/bg.jpg')
FPS = pygame.time.Clock()
fps = 60
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
winW = 1227
winH = 700
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_icon(win)
def redraw_window():
#win.fill(WHITE)
win.blit(bg, (0, 0))
win.blit(text_to_screen('FPS: {}'.format(FPS.get_fps()), BLUE), (25, 50))
pygame.display.update()
def text_to_screen(txt, col):
font = pygame.font.SysFont('Comic Sans MS', 25, True)
text = font.render(str(txt), True, col)
return text
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
redraw_window()
FPS.tick(fps)
pygame.quit()
Ensure that the background Surface has the same format as the display Surface. Use convert() to create a Surface that has the same pixel format. That should improve the performance, when the background is blit to the display, because the formats are compatible and blit do not have to do an implicit transformation.
bg = pygame.image.load('images/bg.jpg').convert()
Furthermore, it is sufficient to create the font once, rather than every time when a text is drawn. Move font = pygame.font.SysFont('Comic Sans MS', 25, True) to the begin of the application (somewhere after pygame.init() and before the main application loop)
Instead use screen.blit(pygame.image.load(picture.png))
Just image = pygame.image.load(picture.png) then screen.blit(image)
( if you keep loading your pictures continuously it will get lag )
I'm having trouble with the framerate in my game. I've set it to 60 but it only goes to ~25fps. This was not an issue before displaying the background (was fine with only win.fill(WHITE)). Here is enough of the code to reproduce:
import os, pygame
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (50, 50)
pygame.init()
bg = pygame.image.load('images/bg.jpg')
FPS = pygame.time.Clock()
fps = 60
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
winW = 1227
winH = 700
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_icon(win)
def redraw_window():
#win.fill(WHITE)
win.blit(bg, (0, 0))
win.blit(text_to_screen('FPS: {}'.format(FPS.get_fps()), BLUE), (25, 50))
pygame.display.update()
def text_to_screen(txt, col):
font = pygame.font.SysFont('Comic Sans MS', 25, True)
text = font.render(str(txt), True, col)
return text
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
redraw_window()
FPS.tick(fps)
pygame.quit()
Ensure that the background Surface has the same format as the display Surface. Use convert() to create a Surface that has the same pixel format. That should improve the performance, when the background is blit to the display, because the formats are compatible and blit do not have to do an implicit transformation.
bg = pygame.image.load('images/bg.jpg').convert()
Furthermore, it is sufficient to create the font once, rather than every time when a text is drawn. Move font = pygame.font.SysFont('Comic Sans MS', 25, True) to the begin of the application (somewhere after pygame.init() and before the main application loop)
Instead use screen.blit(pygame.image.load(picture.png))
Just image = pygame.image.load(picture.png) then screen.blit(image)
( if you keep loading your pictures continuously it will get lag )
I want to change the color of each button inside one by one, on every change in color I want to play one sound.
The sounds are playing perfectly, but the button color is changing only at the end when all of the sounds are played.
What should I do the make the color change and sound play for each button at the same time?
Here is my code:
import pygame, pygbutton, sys
from pygame.locals import *
import time
import threading
from threading import Thread
FPS = 30
WINDOWWIDTH = 1550
WINDOWHEIGHT = 1200
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
GREY = (211, 211, 211)
exitcode = 0
def main():
#1 constants
windowBgColor = WHITE
size=(100,30)
running = 1
#2 initialize
FPSCLOCK = pygame.time.Clock()
pygame.mixer.init(frequency=22050,size=-16,channels=13)
#3 load
zebrasound = pygame.mixer.Sound("resources/audio/zebra.wav")
zlet = pygame.mixer.Sound("resources/audio/Z.wav")
elet = pygame.mixer.Sound("resources/audio/E.wav")
blet = pygame.mixer.Sound("resources/audio/B.wav")
rlet = pygame.mixer.Sound("resources/audio/R.wav")
alet = pygame.mixer.Sound("resources/audio/A.wav")
wrong = pygame.mixer.Sound("resources/audio/fail.wav")
right = pygame.mixer.Sound("resources/audio/chime.wav")
beep = pygame.mixer.Sound("resources/audio/sensor.wav")
flip = pygame.mixer.Sound("resources/audio/flip.wav")
zebrasound.set_volume(3)
zlet.set_volume(3)
elet.set_volume(3)
blet.set_volume(3)
rlet.set_volume(3)
alet.set_volume(3)
wrong.set_volume(3)
right.set_volume(5)
#4 Display
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Animal game')
#5 Buttons
buttonForward = pygbutton.PygButton((700, 900, 600,482), normal='resources/images/arrow.png')
buttonBackward = pygbutton.PygButton((600, 900, 600,482), normal='resources/images/arrowBackward.png')
buttonZebra = pygbutton.PygButton((100, 150, 640,480), normal='resources/images/zebraclip.png')
buttonZebra1 = pygbutton.PygButton((850, 200, 600, 120), 'Z E B R A')
buttonZebra2 = pygbutton.PygButton((850, 400, 600, 120), 'Z A B R A')
buttonZebra3 = pygbutton.PygButton((850, 600, 600, 120), 'Z B R E A')
buttonZebra11 = pygbutton.PygButton((855, 205, 110, 110), 'Z')
buttonZebra12 = pygbutton.PygButton((975, 205, 110, 110), 'E')
buttonZebra13 = pygbutton.PygButton((1095, 205, 110, 110), 'B')
buttonZebra14 = pygbutton.PygButton((1215, 205, 110, 110), 'R')
buttonZebra15 = pygbutton.PygButton((1335, 205, 110, 110), 'A')
buttonZebra1.font = pygame.font.Font(None,110)
buttonZebra11.font = pygame.font.Font(None,110)
buttonZebra12.font = pygame.font.Font(None,110)
buttonZebra13.font = pygame.font.Font(None,110)
buttonZebra14.font = pygame.font.Font(None,110)
buttonZebra15.font = pygame.font.Font(None,110)
buttonZebra2.font = pygame.font.Font(None,110)
buttonZebra3.font = pygame.font.Font(None,110)
button = [buttonZebra,buttonZebra1,buttonZebra2,buttonZebra3]
button_zebra = [buttonZebra11,buttonZebra12,buttonZebra13,buttonZebra14,buttonZebra15]
allButtons = button
windowBgColor = WHITE
#6 Event loop
#while True:
while running:
#pygame.display.flip()
for event in pygame.event.get(): # event handling loop
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
if 'click' in button[0].handleEvent(event):
zebrasound.play()
if 'click' in button[1].handleEvent(event):
sound_please(right)
change_color_bg(button[1], GREEN)
change_color_fg(button_zebra[0], GREEN)
change_color_bg(button_zebra[0], BLACK)
sound_please(zlet)
change_color_fg(button_zebra[1], GREEN)
change_color_bg(button_zebra[1], BLACK)
sound_please(elet)
change_color_fg(button_zebra[2], GREEN)
change_color_bg(button_zebra[2], BLACK)
sound_please(blet)
change_color_fg(button_zebra[3], GREEN)
change_color_bg(button_zebra[3], BLACK)
sound_please(rlet)
change_color_fg(button_zebra[4], GREEN)
change_color_bg(button_zebra[4], BLACK)
sound_please(alet)
if 'click' in button[2].handleEvent(event):
sound_please(wrong)
change_color_bg(button[2], RED)
if 'click' in button[3].handleEvent(event):
sound_please(wrong)
change_color_bg(button[3], RED)
pygame.display.update()
screen.fill(windowBgColor)
buttonForward.draw(screen)
for a in allButtons:
a.draw(screen)
for b in button_zebra:
b.draw(screen)
pygame.display.update()
FPSCLOCK.tick(FPS)
def change_color_fg(button,color):
button.fgcolor = color
pygame.display.update()
def change_color_bg(button,color):
button.bgcolor = color
pygame.display.update()
def sound_please(sound):
sound.play()
while pygame.mixer.get_busy():
time.sleep(1)
pygame.display.update()
if __name__ == "__main__":
main()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
Button[1] is the big button and button_zebra 1,2,3,4 are small buttons inside bigbutton.
I have 4 buttons in a bigbutton, When I click the bigbutton and color of it changes.
Since input handling (the section of code that you posted) is usually just one part of the game loop, and you haven't posted the contents of change_color_fg, I can only make an educated guess here.
My guess is that change_color_fg does not actually update the display, and only changes the color that a button is supposed to draw with. It's my guess partly because it wouldn't make sense to re-draw the display within a function that's executing multiple times within a single frame.
For starters, don't delay in the middle of your update loop. If you need to do something when a single sound ends, implement a callback, or check playing sounds for completion once every frame until they finish.
For example, with each sound you play, you could either check its length with pygame.mixer.Sound.get_length, and then schedule a function to execute after that amount of time which changes the color of your next button and plays your next sound. Or, you could get the pygame.mixer.Channel object back from pygame.mixer.Sound.play, and then check pygame.mixer.Channel.get_busy until it returns False, which would indicate that your sound has stopped playing, at which point you can play the next one.
I have a problem. i am trying to program a menu for a game in python I am making now. But I have a problem. Every time I run the code, the code exits without even doing anything. i went through the code, and see nothing that can cause this. Here is the code:
#importing the libraries
import pygame
import sys
WINDOWWIDTH = 640
WINDOWHEIGHT = 480
#colour R G B
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
DARKGREEN = ( 0, 155, 0)
DARKGREY = ( 40, 40, 40)
BGCOLOR = BLACK
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
def main():
global DISPLAYSURF, BASICFONT
pygame.init()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
BASICFONT = pygame.font.Font('DrippingCool.ttf, 18')
pygame.display.set_caption('Badger Defense - Aplha(0.0.1)')
showStartScreen()
#Drawing the screen
DISPLAYSURF.fill(BGCOLOR)
pygame.display.update()
#Drawing the message
def drawPressKeyMsg():
pressKeySurf = BASICFONT.render("Press a key to play...", True, DARKGREY)
pressKeyRect = pressKeySurf.get_rect()
pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30)
DISPLAYSURF.blit(pressKeySurf, pressKeyRect)
#Reaction to the message
def checkForKeyPress():
if len(pygame.event.get(QUIT)) > 0:
terminate()
keyUpEvents = pygame.event.get(KEYUP)
if len(keyUpEvent) == 0:
return None
if keyUpEvents[0].key == K_SPACE:
terminate()
return keyUpEvents[0].key
#Showing the start screen
def showStartScreen():
titleFont = pygame.font.Font('DrippingCool.ttf', 100)
titleMain = titleFont.render('Badger Defense', True, WHITE, DARKGREEN)
titleSecond = titleFont.render('Badger Defense', True, GREEN)
degrees1 = 0
degrees2 = 0
while True:
DISPLAYSURF.fill(BCOLOR)
rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1)
rotatedRect1 = rotatedSurf1.get_rect()
rotatedRect1.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
DISPLAYSURF.blit(rotatedSurf1, rotatedRect1)
rotatedSurf2 = pygame.transform.rotate(titleSurf2, degrees2)
rotatedRect2 = rotatedSurf2.get_rect()
rotatedRect2.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
DISPLAYSURF.blit(rotatedSurf2, rotatedRect2)
drawPressKeyMsg()
if checkForKeyPress():
pygame.event.get()
return
pygame.display.update()
degrees1 += 3 #rotate by 3 degrees each frame
degrees2 += 7 #rotate by 7 degrees each frame
def terminate():
pygame.quit()
sys.exit()
I am running Ubuntu 12.04. I wrote the code in Sublime but tried to run it in Geany as well. Both didn't work.
Thanks for the help in advance.
You don't seem to have a if __name__ == '__main__': section at the bottom of your code, or anything else that would actually run your code. You are defining everything, but nothing runs because you have not told it to run.
Try adding something like this to the bottom of your code:
if __name__ == '__main__':
main()
The StackOverflow question What does if __name__ == "__main__": do? talks about why you would put that in your file.