This question already has an answer here:
Why is my pygame application loop not working properly?
(1 answer)
Closed 2 years ago.
All I get is a black screen.
Not sure if I can't find the image in the directory or, if some if I'm not calling something right... But it's not giving me an error so I'm not sure what to work off of.
import pygame
# Intialize the pygame
pygame.init()
# Create the screen
screen = pygame.display.set_mode((300, 180))
#Title and Icon
pygame.display.set_caption("Fighting Game")
# Add's logo to the window
# icon = pygame.image.load('')
# pygame.display.set_icon(icon)
# Game Loop
running = True
while running:
# screen.fill((0, 0, 0))
# screen.blit(BackGround.image, BackGround.rect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
class Background(pygame.sprite.Sprite):
def __init__(self, image_file, location):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.image = pygame.image.load("images/image.png")
self.rect = self.image.get_rect(300,180)
self.rect.left, self.rect.top = location
BackGround = Background('image.png', [0,0])
screen.fill((0, 0, 0))
screen.blit(BackGround.image, BackGround.rect)
You have to blit the image in the main application loop and you have to update the display by pygame.display.flip.
Furthermore it is not necessary to pass any parameters to self.image.get_rect(). Anyway the arguments to get_rect() have to be keyword arguments.
What you can do is to set the location by the keyword argument topleft.
class Background(pygame.sprite.Sprite):
def __init__(self, image_file, location):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.image = pygame.image.load("images/image.png")
self.rect = self.image.get_rect(topleft = location)
BackGround = Background('image.png', [0,0])
# Game Loop
running = True
while running:
# screen.fill((0, 0, 0))
# screen.blit(BackGround.image, BackGround.rect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#screen.fill((0, 0, 0)) # unnecessary because of the background image
screen.blit(BackGround.image, BackGround.rect)
pygame.display.flip()
Note, the main application loop has to:
handle the events
clear the display or blit the backgrond image
draw the scene
update the display
Related
import pygame as pygame , sys,time
pygame.init()
size = (700,500)
window_game = pygame.display.set_mode(size)
_run_ = True
white = (255,255,255)
mouse_pos = pygame.mouse.get_pos()
class mySprite(pygame.sprite.Sprite):
def __init__ (self,cord_x,cord_y,picture,colorkey):
super().__init__()
self.image = pygame.Surface([0,0])
self.image = pygame.image.load(picture)
self.image.set_colorkey(colorkey)
self.rect = self.image.get_rect()
self.rect.center = [cord_x,cord_y]
self.kill()
placeSP_group = pygame.sprite.Group()
Clock = pygame.time.Clock()
FPS = 500
while _run_:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.QUIT
sys.exit()
mouse_pos = pygame.mouse.get_pos()
placeSP = [mySprite(mouse_pos[0],mouse_pos[1],'sp_1.png',white)]
pygame.display.flip()
placeSP_group.draw(window_game)
placeSP_group.add(placeSP[:])
Clock.tick(FPS)
now i want that my sprite get's killed and get the new mouse position
and window_game.fill('black')
dosen't work is there any thing you can do to fix it pls tell me...
what i wan't is every time my mouse moves i wan't kill the last sprite and create the other one with the current sprite pos.
You use kill() in wrong moment.
kill() works when Sprite is inside Group but you first create Sprite which try to use kill() and later you add this sprite to Group.
You should first create Sprite, next add to Group and later run kill() for first Sprite in Group
placeSP_group.sprites()[0].kill()
but normal Group doesn't have to keep sprites in order and better use
placeSP_group = pygame.sprite.OrderedUpdates()
Full working code. It display 5 sprites which follow mouse.
import pygame
import sys
# --- constants --- # PEP8: `UPPER_CASE_NAMES` for constants
WHITE = (255, 255, 255) # PE8: space after `,`
SIZE = (700, 500)
FPS = 50 # there is no need to use `500` because Python can't run so fast,
# and monitors runs with 60Hz (eventually 120Hz) which can display 60 FPS (120 FPS)
# --- classes --- # PEP8: `CamelCaseNames` for classes
class MySprite(pygame.sprite.Sprite):
def __init__(self, x, y, picture, colorkey):
super().__init__()
# you need one of them
# load image
#self.image = pygame.image.load(picture)
# OR
# create surface
self.image = pygame.Surface((10, 10))
self.image.fill((255, 0, 0))
# ----
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.image.set_colorkey(colorkey)
# --- main ---
pygame.init()
window_game = pygame.display.set_mode(SIZE)
#placeSP_group = pygame.sprite.Group()
placeSP_group = pygame.sprite.OrderedUpdates() # Group which keep order
sprite1 = MySprite(0, 0, 'sp_1.png', WHITE)
sprite2 = MySprite(0, 0, 'sp_1.png', WHITE)
sprite3 = MySprite(0, 0, 'sp_1.png', WHITE)
sprite4 = MySprite(0, 0, 'sp_1.png', WHITE)
sprite5 = MySprite(0, 0, 'sp_1.png', WHITE)
placeSP_group.add([sprite1, sprite2, sprite3, sprite4, sprite5])
clock = pygame.time.Clock() # PEP8: `lower_case_names` for variables
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
#running = False
pygame.quit()
exit()
# create new Sprite
x, y = pygame.mouse.get_pos()
new_sprite = MySprite(x, y, 'sp_1.png', WHITE)
# add new Sprite at the end of OrderedUpdates()
placeSP_group.add([new_sprite])
# remove Sprite at the beginning of OrderedUpdates()
placeSP_group.sprites()[0].kill()
# ---
pygame.display.flip()
window_game.fill('black')
placeSP_group.draw(window_game)
clock.tick(FPS)
from numpy import size
import pygame
import sys
# --- constants --- # PEP8: `UPPER_CASE_NAMES` for constants
WHITE = (255, 255, 255) # PE8: space after `,`
SIZE = (700, 500)
FPS = 120 # there is no need to use `500` because Python can't run so fast,
# and monitors runs with 60Hz (eventually 120Hz) which can display 60 FPS (120 FPS)
# --- classes --- # PEP8: `CamelCaseNames` for classes
class MySprite(pygame.sprite.Sprite):
def __init__(self, x, y, picture, colorkey):
super().__init__()
# you need one of them
# load image
self.image = pygame.image.load(picture)
# OR
# create surface
# self.image = pygame.Surface((10, 10))
# self.image.fill((255, 0, 0))
# ----
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.image.set_colorkey(colorkey)
def update(self):
if event.type == pygame.MOUSEBUTTONDOWN:
mouse = pygame.mouse.get_pos()
print(mouse[:])
# --- main ---
pygame.init()
window_game = pygame.display.set_mode(SIZE)
backGround = pygame.image.load('bg.jpg').convert_alpha(window_game)
backGround = pygame.transform.smoothscale(backGround,SIZE)
backGround.set_colorkey(WHITE)
#placeSP_group = pygame.sprite.Group()
placeSP_group = pygame.sprite.OrderedUpdates() # Group which keep order
sprite1 = [MySprite(0, 0, 'crossHair.png', WHITE),MySprite(0, 0, 'crossHair_2.png', WHITE)]
placeSP_group.add([sprite1[0],sprite1[1]])
pygame.mouse.set_visible(False)
clock = pygame.time.Clock() # PEP8: `lower_case_names` for variables
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
#running = False
pygame.quit()
exit()
# create new Sprite
global x,y
x, y = pygame.mouse.get_pos()
new_sprite = sprite1[:]
# add new Sprite at the end of OrderedUpdates()
placeSP_group.add([new_sprite])
# remove Sprite at the beginning of OrderedUpdates()
placeSP_group.sprites()[0].kill()
placeSP_group.update()
# ---
pygame.display.flip()
window_game.fill('white')
window_game.blit(backGround,(0,0)).size
placeSP_group.draw(window_game)
clock.tick(FPS)
when i assignee new_sprite to all the assigned sprites in placeSP
it dosen't show any thing can you help me with that i am not sure why is that happening but can you fix it ... this an edited question. And i didn't got any answer .... but i have the concept in my head can and i also don't wan't to modify my code that much can you help me with that...
Create a sprite class with a list of images. Add an attribute that counts the frames. Get image from image list in the update method based on number of frames:
class MySprite(pygame.sprite.Sprite):
def __init__(self, x, y, image_list):
super().__init__()
self.frame = 0
self.image_list = image_list
self.image = self.image_list[0]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def update(self, event_list):
animation_interval = 20
self.frame += 1
if self.frame // animation_interval >= len(self.image_list):
self.frame = 0
self.image = self.image_list[self.frame // animation_interval]
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
mouse = event.pos
print(mouse[:])
However, instead of constantly creating and killing the sprite every frame, you need to create the sprite once before the application loop. Change the position of the sprite and update the sprite in the application loop:
file_list = ['crossHair.png', 'crossHair_2.png', 'crossHair_3.png']
image_list = []
for name in file_list:
image = pygame.image.load(name)
image.set_colorkey(WHITE)
image_list.append(image)
# create sprite
sprite1 = MySprite(0, 0, image_list)
placeSP_group = pygame.sprite.OrderedUpdates()
placeSP_group.add([sprite1])
clock = pygame.time.Clock()
running = True
while running:
# handle events
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
running = False
# update sprite
x, y = pygame.mouse.get_pos()
placeSP_group.sprites()[0].rect.center = (x, y)
placeSP_group.update(event_list)
# draw scene
window_game.fill('white')
window_game.blit(backGround,(0,0)).size
placeSP_group.draw(window_game)
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
exit()
See also:
how to create an illusion of animations in pygame
Animated sprite from few images
How do I create animated sprites using Sprite Sheets in Pygame?
In my game I am trying to make it so when you walk into a object, it displays an image.
I'm pretty sure that pygame.display.update() is being called every frame because otherwise the game would be perfectly still.
However when I draw my new rect upon collision it doesn't appear, unless I put another pygame.display.update(rect) with it after it being drawn. This means that update is being called twice at one time, in the main game loop and after drawing the rect. This causes the rect (which has been drawn now) to flicker because of the multiple update calls.
I cannot figure it out why it doesn't get drawn without the second update call.
Main game loop call:
def events(self):
#game loop events
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.playing = False
self.running = False
def update(self):
self.all_sprites.update()
def main(self):
while self.playing:
self.events()
self.update()
self.draw()
self.running = False
def draw(self):
self.screen.fill(black)
self.all_sprites.draw(self.screen)
self.clock.tick(FPS)
pygame.display.update()
#create game instance
g= Game()
g.new()
while g.running:
#main gameloop
g.main()
pygame.quit()
sys.exit()
Here is when I call to draw the rect after collision with my object:
def update(self):
self.hitbox.center = numpy.add(self.rect.center,(8,22))
self.interactionhitbox.center = numpy.add(self.rect.center, (8,16))
if(self.showPopup):
# Initialwzng Color
color = (255,0,0)
# Drawing Rectangle
rect = pygame.Rect((0,0,60,60))
pygame.display.update(rect) # WITHOUT THIS LINE IT DOES NOT GET DRAWN, WITH IT IT FLICKERS
pygame.draw.rect(self.game.screen, color, rect)
So basically with the second pygame.display.update(rect) call it appears but flickers, and without it it doesn't show up at all
Any help is appreciated sorry if this is a bad question or not formatted right I haven't been here since 2017!
The rectangle is not drawn because the screen will later be cleared with self.screen.fill(black) later. You must draw the rectangle after self.screen.fill(black) and before pygame.display.update().
Create 2 images and choose the image to be drawn in update:
def __init__(self, ...)
# [...]
self.image = ...
self.original_image = self.image
self.image_and_rect = self.image.copy()
pygame.draw.rect(self.image_and_rect, (255,0,0), self.image_and_rect.get_rect(), 5)
def update(self):
self.hitbox.center = numpy.add(self.rect.center,(8,22))
self.interactionhitbox.center = numpy.add(self.rect.center, (8,16))
if self.showPopup:
self.image = self.image_and_rect
else:
self.image = self.original_image
So there you go, I wanted to experiment a little pygame but I find myself stuck.
Context
I created a small sprite (with Piskelapp) that represents the player and looks like:
player.png
then add my background in jpg format. However when launching the game, my sprite is cut by the background as follows:
The ship is not placed in front of the background and more I go up it, more it disappears behind the background...
Here is my code:
import pygame
pygame.init()
# class user
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.pv = 100
self.__max_health = 100
self.attack = 2
self.velocity = 5
self.image = pygame.image.load('assets/player.png')
self.rect = self.image.get_rect()
self.rect.x = 400
self.rect.y = 500
# open game window
pygame.display.set_caption("Rocket 'n' Rock")
screen = pygame.display.set_mode((1080, 720))
# background import
bg = pygame.image.load('assets/bg.jpg')
# load player
player = Player()
running = True
# game mainloop
while running:
# bg apply
screen.blit(bg, (0,-400))
# screen update
pygame.display.flip()
# player image apply
screen.blit(player.image, player.rect)
# if player close the window
for event in pygame.event.get():
# *close event
if event.type == pygame.QUIT:
running = False
pygame.quit()
print("close game")
anyone have a tip? I'm wondering if it's not a file format problem?
thank you for your time
In you game mainloop, you should put:
screen.blit(player.image, player.rect)
before:
pygame.display.flip()
I have written simple code to get a green block which is my sprite to scroll across the screen. When the game starts the sprite is meant to appear in the centre of the screen, however when I run my code the screen is just black and the green block does not appear unless I click on the x cross on the window to exit the screen, then it appears for a second when the window is closing. Any ideas how I can resolve this.
import pygame, random
WIDTH = 800 #Size of window
HEIGHT = 600 #size of window
FPS = 30
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
class Player(pygame.sprite.Sprite):
#sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH/2, HEIGHT/2)
def update(self):
self.rect.x += 5
#initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
#Game loop
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
#check for closing window
if event.type == pygame.QUIT:
running = False
#update
all_sprites.update()
#Render/Draw
screen.fill(BLACK)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()
All your code to updat the sprites, fill the screens and draw the sprites is outside your main loop (while running)
You must have in mind that identation Python's syntax: your commands are just outside your mainloop.
Moreover, I'd strongly advise to put that mainloop inside a proper function, instead of just leaving it on the module root.
...
#Game loop
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
#check for closing window
if event.type == pygame.QUIT:
running = False
#update
all_sprites.update()
#Render/Draw
screen.fill(BLACK)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()