How Do I Scroll My BackGround Image In Pygame? [duplicate] - python

This question already has answers here:
Making the background move sideways in pygame
(2 answers)
Closed 2 years ago.
I was Wonder How I Could Scroll mY background image in pygame
I have a moving object I want it to scroll when that object is moving
here is a video of the background image right now video
right now I am just blitting the background image
def redrawwindow():
window.blit(bg,(0,0))
here is my full code
import pygame
import random
pygame.init()
#this is screem height
window = pygame.display.set_mode((500,500))
#know we put screem name
pygame.display.set_caption("Noobs Flappy Bird Game")
#player class
class bird:
def __init__(self,x,y,height,width,color):
self.x = x
self.y =y
self.bright = [
pygame.image.load("killers50.png"),
pygame.image.load("killers51.png"),
pygame.image.load("killers52.png"),
pygame.image.load("killers53.png"),
]
self.bleft = [
pygame.image.load("ms1.png"),
pygame.image.load("ms2.png"),
pygame.image.load("ms3.png"),
pygame.image.load("ms4.png"),
]
self.bright = [pygame.transform.scale(image,(image.get_width()//15,image.get_height()//15)) for image in self.bright]
self.bleft = [pygame.transform.scale(image,(image.get_width()//15,image.get_height()//15)) for image in self.bleft]
self.height = height
self.width = width
self.isJump = False
self.JumpCount = 10
self.fall = 0
self.speed = 5
self.Walking = 0
self.vel = 5
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.direction = "down"
# this makes the enemy move right and left
def draw(self):
self.rect.topleft = (self.x,self.y)
if self.Walking + 1 >= 33:
self.Walking = 0
if self.vel > 0: # left
window.blit(self.bright[self.Walking % 3], (self.x,self.y))
self.Walking += 1
else: # right
window.blit(self.bleft[self.Walking % 3], (self.x,self.y))
self.Walking += 1
class platform:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.pipis = pygame.image.load("pip.png")
self.pipis = pygame.transform.scale(self.pipis,(self.pipis.get_width()//3,self.pipis.get_height()//3))
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft=(self.x,self.y)
window.blit(self.pipis,self.rect)
class pip:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.pipis = pygame.image.load("pipo.png")
self.pipis = pygame.transform.scale(self.pipis,(self.pipis.get_width()//3,self.pipis.get_height()//3))
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft=(self.x,self.y)
window.blit(self.pipis,self.rect)
#player and enemy
white = (255,255,255)
bird1 = bird(0,400,50,50,white)
red = (255,48,48)
platform1 = platform(600,300,150,50,white)
platform2 = platform(800,200,150,50,white)
platform3 = platform(1100,300,150,50,white)
platform4 = platform(1300,400,150,50,white)
platform5 = platform(1500,300,150,50,white)
platform6 = platform(1800,200,150,50,white)
# ROUND 2
platform7 = platform(2200,300,150,50,white)
platform8 = platform(2400,200,150,50,white)
platform9 = platform(2600,300,150,50,white)
platform10 = platform(2700,400,150,50,white)
platform11 = platform(2900,300,150,50,white)
platform12 = platform(3200,200,150,50,white)
# rOUND 3
platform13 = platform(3400,300,150,50,white)
platform14 = platform(3600,200,150,50,white)
platform15 = platform(3800,300,150,50,white)
platform16 = platform(4000,400,150,50,white)
platform17 = platform(4200,300,150,50,white)
platform18 = platform(4400,200,150,50,white)
# ROUND 4
platform19 = platform(600,300,150,50,white)
platform20 = platform(800,200,150,50,white)
platform21 = platform(1100,300,150,50,white)
platform22 = platform(1300,400,150,50,white)
platform23 = platform(1500,300,150,50,white)
platform24 = platform(1800,200,150,50,white)
platforms = [platform1,platform2,platform3,platform4,platform5,platform6,platform7,platform8,platform9,platform10,platform11,platform12,platform13,platform14,platform15,platform16,platform17,platform18,platform19,platform20,platform21,platform22,platform23,platform24]
# sceond pip
pip1 = pip(600,-160,150,50,white)
pip2 = pip(800,-270,150,50,white)
pip3 = pip(1100,-170,150,50,white)
pip4 = pip(1300,-170,150,50,white)
pip5 = pip(1500,-170,150,50,white)
pip6 = pip(1800,-270,150,50,white)
# ROUND 2
pip7 = pip(2200,-160,150,50,white)
pip8 = pip(2400,-270,150,50,white)
pip9 = pip(2600,-170,150,50,white)
pip10 = pip(2700,-170,150,50,white)
pip11 = pip(2900,-170,150,50,white)
pip12 = pip(3200,-270,150,50,white)
# ROUND 3
# rOUND 3
pip13 = pip(3400,-160,150,50,white)
pip14 = pip(3600,-270,150,50,white)
pip15 = pip(3800,-170,150,50,white)
pip16 = pip(4000,-170,150,50,white)
pip17 = pip(4200,-170,150,50,white)
pip18 = pip(4400,-270,150,50,white)
# ROUND 4
pip19 = pip(600,-160,150,50,white)
pip20 = pip(800,-270,150,50,white)
pip21 = pip(1100,-170,150,50,white)
pip22 = pip(1300,-170,150,50,white)
pip23 = pip(1500,-170,150,50,white)
pip24 = pip(1800,-270,150,50,white)
pips = [pip1,pip2,pip3,pip4,pip5,pip6,pip7,pip8,pip9,pip10,pip11,pip12,pip13,pip14,pip15,pip16,pip17,pip18,pip19,pip20,pip21,pip22,pip23,pip24]#window
class orb:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft = (self.x,self.y)
class particleAndPoint:
def __init__(self,x,y,height,width,color):
self.x = x
self.y =y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft = (self.x,self.y)
particleAndPoints = []
# this is the orbs
orb1 = orb(1500,100,50,550,white)
orb2 = orb(2600,100,50,550,white)
orbes = [orb1,orb2]
platformGroup = pygame.sprite.Group
platformList = []
level = [" ",
" ",
" ",
" ",
" p p p p p p p p p p p p p p p p p p",
" ",
" ",
" ",
" ",
" ",
" ",]
for iy, row in enumerate(level):
for ix, col in enumerate(row):
if col == "p":
new_platforms = particleAndPoint(ix*10, iy*0, 10,1010,(255,255,255))
particleAndPoints.append(new_platforms)
# the score text
font = pygame.font.Font('Candarai.ttf',60)
score = 0
loltext = font.render("" + str(score), True, (255,255,255))
lolrect = loltext.get_rect()
lolrect.center = ((130,60))
# wow sound anime
wowsound = pygame.mixer.Sound("wows.wav")
explodesound = pygame.mixer.Sound("partexplode.wav")
class particle:
def __init__(self,x,y):
self.x = x
self.y = y
self.x_vel = random.randrange(-10,13)*1
self.y_vel = random.randrange(-10,-1)*1
self.lifetime = 0
def draw(self,window):
self.lifetime += 1
if self.lifetime <30:
self.x -= self.x_vel
self.y -= self.y_vel
pygame.draw.rect(window,(232,255,24),(self.x,self.y, 16,16))
# draw the screen things
def redrawwindow():
bg = pygame.image.load("bgs.png")
window.blit(bg,(0,0))
#player draw
bird1.draw()
for platform in platforms:
platform.draw()
for pip in pips:
pip.draw()
for particleAndPoint in particleAndPoints:
particleAndPoint.draw()
window.blit(loltext,lolrect)
for orb in orbes:
orb.draw()
for particle in particles:
particle.draw(window)
fps = (30)
clock = pygame.time.Clock()
particles = []
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# if player collides with the obsticles add 1 to the player and delete the obstacle
for one in range(len(particleAndPoints)-1,-1,-1):
if bird1.rect.colliderect(particleAndPoints[one].rect):
score += 1
bird1.speed += 0.2
del particleAndPoints[one]
explodesound.play()
loltext = font.render("" + str(score), True, (255,255,255))
lolrect.center = ((130,60))
for x in range(60):
x, y = bird1.rect.center
particles.append( particle( x, y ) )
# if ball collides with player1 show the particles
# if ball collides with player1 show the particles
if bird1.rect.colliderect( orb1.rect ):
for x in range(60):
wowsound.play()
explodesound.play()
x, y = bird1.rect.center
particles.append( particle( x, y ) )
if bird1.rect.colliderect( orb2.rect ):
for x in range(60):
wowsound.play()
explodesound.play()
x, y = bird1.rect.center
particles.append( particle( x, y ) )
keys = pygame.key.get_pressed()
# bird moving
bird1.x += bird1.speed
if not bird1.isJump:
bird1.y += bird1.speed
bird1.isJump = False
if keys[pygame.K_SPACE]:
bird1.isJump = True
# this part lets you jump on platform
collide = False
for platform in platforms:
if bird1.rect.colliderect(platform.rect):
collide = False
# this makes the player fall down up to
if bird1.rect.bottom >= 500:
collide = True
bird1.isJump = False
bird1.JumpCount = 10
bird1.y = 500 - bird1.height
if collide:
if keys[pygame.K_SPACE]:
bird1.isJump = True
bird1.fall = 0
else:
if bird1.JumpCount > 0:
bird1.y -= (bird1.JumpCount*abs(bird1.JumpCount)) * 0.2
bird1.JumpCount -= 1
else:
bird1.JumpCount = 10
bird1.isJump = False
# this scrolls my screen right
if bird1.x > 300:
bird1.x -= bird1.speed
for platform in platforms:
platform.x -= bird1.speed
for pip in pips:
pip.x -=bird1.speed
for particleAndPoint in particleAndPoints:
particleAndPoint.x -= bird1.speed
for orb in orbes:
orb.x -= bird1.speed
redrawwindow()
pygame.display.update()
pygame.quit()
I want the background to keep scrolling right because my player is always moving right Thank YOu!

You have to draw the background twice in a tiled mode. Add a variable which defines the offset of the background bg_shift. Compute the offset in relation to the width of the background by the % (modulo) operator (See Binary arithmetic operations). Finally blit the background twice:
bg_shift = 0
def redrawwindow():
bg_width = gb.get_widht()
bg_offset = bg_shift % bg_width
window.blit(bg, (-bg_offset, 0))
window.blit(bg, (bg_width - bg_offset, 0))
You have to change the variabel bg_shift in the main application loop dependent on the movement of the bird.
bg_shift += bird1.speed
You can even try to move the background with a different speed, which gives a nice perspective effect. For instance:
bg_shift += round(bird1.speed / 2)

Related

Hitboxes only scaling from one side pygame

Im making a plat former
game with pygame
So im creating sprites using
self.rect = self.image.get_rect()
then to get it to scale the hotbox im using
self.rect.inflate(-40,-20)
but this only seems to alter the hotbox from the right side and I think the bottom (Because the x,y starts in the top left of the sprite)
so now my hotbox for my enemy sprite is fine on the left side but still unproportionate on the left side
I hear theres a way to make the hitbox start in the centre of the sprite, How would I do this?
If not how should I go about fixing hotboxes
Thanks in advance,
edit: this is my code for my sprite
#ENEMY SPRITE class
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('img/blob.png')
self.image = pygame.transform.scale(self.image, (65,35))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.move_direction = 1
self.move_counter = 0
def update(self): #update enemy (movement)
self.rect.x += self.move_direction
self.move_counter += 1
if abs(self.move_counter) > 50:
self.move_direction *= -1
self.move_counter *= -1
Full code
#import modules
import pygame
from pygame.locals import *
from pygame import mixer
import pickle
from os import path
#initiliaze pygamee
pygame.mixer.pre_init(44100,-16,2,512) #volume control
mixer.init()
pygame.init()
#fps
clock = pygame.time.Clock()
font = pygame.font.SysFont('Bauhaus 93', 70)
font_score = pygame.font.SysFont('Bauhaus 93',30)
#screen creation/global variables
screen_width = 800
screen_height = 800
tile_size = 40
fps = 60
game_over = 0
main_menu = True
level = 1
max_levels = 7
score = 0
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Crashlandingv6')
#color
white = (255,255,255)
red = (255,15,15)
blue = (0,0,200)
#load images
bg_img = pygame.image.load('img/background.jpg')
bg_img = pygame.transform.scale(bg_img, (1000,1000))
earth_img = pygame.image.load('img/earth.png')
earth_img = pygame.transform.scale(earth_img, (100,100))
rect = bg_img.get_rect()
restart_img = pygame.image.load('img/restart_btn.png')
start_img = pygame.image.load('img/start_btn.png')
exit_img = pygame.image.load('img/exit_btn.png')
#Load sounds
pygame.mixer.music.load('img/music.wav')
pygame.mixer.music.play(-1,0.0,15000)
coin_fx = pygame.mixer.Sound('img/coin.wav')
coin_fx.set_volume(0.4)
jump_fx = pygame.mixer.Sound('img/jump.wav')
jump_fx.set_volume(0.4)
game_over_fx = pygame.mixer.Sound('img/gameover.wav')
game_over_fx.set_volume(0.5)
def draw_text(text,font,text_col,x,y):
img = font.render(text,True, text_col)
screen.blit(img,(x,y))
#function to reset level
def reset_level(level):
player.reset(100, screen_height - 130)
blob_group.empty()
lava_group.empty()
exit_group.empty()
if path.exists(f'level{level}_data'):
pickle_in = open(f'level{level}_data', 'rb')
world_data = pickle.load(pickle_in)
world = World(world_data)
return world
#create button class
class Button():
def __init__(self,x,y,image):
self.image = image
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.clicked = False
def draw(self):
action = False
pos = pygame.mouse.get_pos()
#check for button collision (if button was clicked {action}
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
action = True
self.clicked = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
#draw button to screen
screen.blit(self.image,self.rect)
return action
#class for player
class Player():
def __init__(self, x, y):
self.reset(x,y)
def update(self,game_over):
dx = 0 #delta x
dy = 0 #delta y
walk_cooldown = 4 #speed
if game_over == 0: #if game is running gameover = 0 if game is over gameover = -1
#get keypresses (controls)
key = pygame.key.get_pressed()
if key[pygame.K_SPACE] and self.jumped == False:
jump_fx.play()
self.vel_y = -15
self.jumped = True
if key[pygame.K_LEFT]:
dx -= 5
self.counter += 1
self.direction = -1
if key[pygame.K_RIGHT]:
dx += 5
self.counter += 1
self.direction = 1
if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
self.counter = 0
self.index = 0
if self.direction == 1:
self.image = self.images_right[self.index]
if self.direction == -1:
self.image = self.images_left[self.index]
#TO DO < insert here !!
# add idle player animation if all buttons are false set player to idle
# players animation
if self.counter > walk_cooldown:
self.counter = 0
self.index += 1
if self.index >= len(self.images_right):
self.index = 0
if self.direction == 1:
self.image = self.images_right[self.index]
if self.direction == -1:
self.image = self.images_left[self.index]
#add gravity
self.vel_y += 1
if self.vel_y > 10:
self.vel_y = 10
dy += self.vel_y
#check for collision
for tile in world.tile_list:
#x direction collision
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
dx=0
#y direction collision
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
#check if below ground (jumping)
if self.vel_y <0:
dy = tile[1].bottom - self.rect.top
self.vel_y = 0
#check if above ground(falling)
elif self.vel_y >= 0:
dy = tile[1].top - self.rect.bottom
self.jumped = False
#check for collision with enemies
if pygame.sprite.spritecollide(self, blob_group, False):
game_over = -1
game_over_fx.play()
#check for collision with lava
if pygame.sprite.spritecollide(self,lava_group,False):
game_over = -1
# check for collision with lava
if pygame.sprite.spritecollide(self, exit_group, False):
game_over = 1
#if gameover (recall gameover = -1 gamerunning = 0)
elif game_over == -1:
self.image = self.dead_image
draw_text('GAME OVER!', font, red, (screen_width //2) - 200, screen_height //2)
if self.rect.y > 200:
self.rect.y -= 5
#update player coordinates
self.rect.x += dx
self.rect.y += dy
#draw player onto screen
screen.blit(self.image, self.rect)
#for rect outlines uncomment #pygame.draw.rect(screen,(255,255,255), self.rect, 2)
return game_over
def reset(self,x,y): #Player class under reset button , when player class is created info gets called from reset for efficiency purposes (instead of typing out twice)
self.images_right = []
self.images_left = []
self.index = 0
self.counter = 0
for num in range(1, 7):
img_right = pygame.image.load(f'img/guy{num}.png')
img_right = pygame.transform.scale(img_right, (40, 80))
img_left = pygame.transform.flip(img_right, True, False) # flips right image on the x axis {true} and not y axis {false}
self.images_right.append(img_right)
self.images_left.append(img_left)
self.dead_image = pygame.image.load('img/ghost.png')
self.image = self.images_right[self.index]
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.width = self.image.get_width()
self.height = self.image.get_height()
self.vel_y = 0
self.jumped = False
self.direction = 0
#class for tiles
class World():
def __init__(self,data):
self.tile_list = []
#load images
dirt_img = pygame.image.load('img/dirt.png')
moonrock_img = pygame.image.load('img/moonrock.png')
#game map
row_count = 0
for row in data:
col_count = 0
for tile in row:
if tile == 1: #replace with dirt
img = pygame.transform.scale(dirt_img,(tile_size,tile_size))
img_rect = img.get_rect()
img_rect.x = col_count * tile_size
img_rect.y = row_count * tile_size
tile = (img,img_rect)
self.tile_list.append(tile)
if tile == 2: #replace with moonrock
img = pygame.transform.scale(moonrock_img, (tile_size, tile_size))
img_rect = img.get_rect()
img_rect.x = col_count * tile_size
img_rect.y = row_count * tile_size
tile = (img, img_rect)
self.tile_list.append(tile)
if tile == 3: #replace with alien
blob = Enemy(col_count * tile_size, row_count * tile_size + 10)
blob_group.add(blob)
if tile == 6: #replace with acid
lava = Lava(col_count * tile_size, row_count * tile_size+(tile_size //2))
lava_group.add(lava)
if tile == 7:
coin = Coin(col_count * tile_size + (tile_size //2), row_count * tile_size + (tile_size // 2))
coin_group.add(coin)
if tile == 8:
exit = Exit(col_count * tile_size, row_count * tile_size - (tile_size//2))
exit_group.add(exit)
col_count += 1
row_count += 1
def draw(self): #draws tiles to screen
for tile in self.tile_list:
screen.blit(tile[0],tile[1])
#for rectangle outlines uncomment #pygame.draw.rect(screen,(255,255,255), tile[1], 1)
def hitbox_from_image(surf):
image_mask = pygame.mask.from_surface(surf)
rect_list = image_mask.get_bounding_rects()
return rect_list[0].unionall(rect_list)
#ENEMY SPRITE class
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('img/blob.png')
self.image = pygame.transform.scale(self.image, (65,35))
self.rect = hitbox_from_image(self.image)
self.rect.x = x
self.rect.y = y
self.move_direction = 1
self.move_counter = 0
def update(self): #update enemy (movement)
self.rect.x += self.move_direction
self.move_counter += 1
if abs(self.move_counter) > 50:
self.move_direction *= -1
self.move_counter *= -1
#LIQUID SPRITE (acid)
class Lava(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
img = pygame.image.load('img/lava2.jpg')
self.image = pygame.transform.scale(img, (tile_size, tile_size//2))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Coin(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
img = pygame.image.load('img/coin.png')
self.image = pygame.transform.scale(img, (tile_size//2, tile_size//2))
self.rect = self.image.get_rect()
self.rect.center = (x,y)
class Exit(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
img = pygame.image.load('img/exit.png')
self.image = pygame.transform.scale(img, (tile_size, int(tile_size * 1.5)))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
player = Player(100,screen_height - 130)
blob_group = pygame.sprite.Group()
lava_group = pygame.sprite.Group()
coin_group = pygame.sprite.Group()
exit_group = pygame.sprite.Group()
#score coin dumby coin
score_coin = Coin(tile_size//2, tile_size//2)
coin_group.add(score_coin)
#load in level data and create world
if path.exists(f'level{level}_data'):
pickle_in = open(f'level{level}_data', 'rb')
world_data = pickle.load(pickle_in)
world = World(world_data)
#create buttons
restart_button = Button(screen_width // 2 - 50, screen_height // 2 + 100, restart_img)
start_button = Button(screen_width// 2 - 350, screen_height // 2, start_img)
exit_button = Button(screen_width// 2 + 100, screen_height // 2, exit_img)
#main loop/ WHILE GAME IS RUNNING DO THIS
run = True
while run:
clock.tick(fps) #run the fps timers
screen.blit(bg_img,rect) #add bg img
screen.blit(earth_img,(100,100))
if main_menu == True:
if exit_button.draw():
run = False
if start_button.draw():
main_menu = False
else:
world.draw() #draw the world tiles
if game_over == 0: # while alive / not dead
blob_group.update()
#update score and checking for coin collection
if pygame.sprite.spritecollide(player,coin_group,True):
score += 1
coin_fx.play()
draw_text("X " + str(score), font_score ,white, tile_size - 10, 10)
blob_group.draw(screen)
lava_group.draw(screen)
coin_group.draw(screen)
exit_group.draw(screen)
game_over = player.update(game_over)
#if player is dead
if game_over == -1:
if restart_button.draw():
world_data = []
world = reset_level(level)
game_over = 0
score = 0
#If level complete reset and next level
if game_over == 1:
level += 1
if level <= max_levels:
#reset level
world_date = []
world = reset_level(level)
game_over = 0
else:
draw_text('WINNER WINNER!', font, blue, (screen_width //2) - 140, screen_height // 2)
#restart game
if restart_button.draw():
level = 1
# reset level
world_date = []
world = reset_level(level)
game_over = 0
score = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.update() #update display
pygame.quit() #quit game
See rect.inflate:
Returns a new rectangle with the size changed by the given offset. The rectangle remains centered around its current center.
However, while rect.inflate_ip changes the pygame.Rect object itself,
rect.inflate does not change the object, but it returns a new object with a different size
Note, the return value of rect.inflate_ip is None, but the return value of rect.inflate is a new pygame.Rect object.
Either call inflate_ip:
self.rect.inflate_ip(-40,-20)
or assign the return value of inflate to self.rect
self.rect = self.rect.inflate(-40,-20)
"how should I go about fixing hotboxes"
This depends on the area covered by the sprite in the bitmap. The covered area can be computed by using a pygame.mask.Mask object and get_bounding_rects.
Use pygame.mask.from_surface to create a pygame.mask.Mask from a pygame.Surface:
image_mask = pygame.mask.from_surface(self.image)
Get a list containing a bounding rectangles (sequence of pygame.Rect objects) for each connected component with get_bounding_rects:
rect_list = image_mask.get_bounding_rects()
Create the union rectangle of the sequence of rectangles with unionall:
self.rect = rect_list[0].unionall(rect_list)
See also How to get the correct dimensions for a pygame rectangle created from an image
Write a function that gets the job done:
def hitbox_from_image(surf):
image_mask = pygame.mask.from_surface(surf)
rect_list = image_mask.get_bounding_rects()
return rect_list[0].unionall(rect_list)
self.rect = hitbox_from_image(self.image)

Mute and unmute function

I have mute and unmute button on my main screen and the problem I'm having with is that when I press my mute button and it turns to a unmute button then when I play my game and die and I go back to the main screen, it turns it back to a mute button. I want to make it so that if I mute my game and I start it and die, it still a mute button, it does not revert to a unmute button. I have tried using a True and False statement also I have tried. https://gyazo.com/6b3d63d7615b07f2b4984d01ae239db5
My full code
import pygame,random
pygame.init()
width = 500
height = 600
# Screen width and height
window = pygame.display.set_mode((width,height))
# Name of the Screen
pygame.display.set_caption("Game")
# For off and on music
music_on = pygame.image.load("img/music_on.png")
music_on = pygame.transform.scale(music_on,(music_on.get_width()//2, music_on.get_height()//2))
music_off = pygame.image.load("img/music_off.png")
music_off = pygame.transform.scale(music_off,(music_off.get_width()//2, music_off.get_height()//2))
# Start screen
def text_objects(font,text):
textSurface = font.render(text,True,(0,0,0))
return textSurface, textSurface.get_rect()
def button(msg,x,y,w,h,ac,ic,action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(window,ac,(x,y,w,h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(window,ic,(x,y,w,h))
def quitgame():
pygame.quit()
def game2():
# part of making background shift
# player class
class Player:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.rect = pygame.Rect(x,y,width,height)
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# Button class
class button11:
def __init__(self,color,x,y,width,height,text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
self.over = False
def draw(self,window, outline=None):
# Call this method to draw button on screen
if outline:
pygame.draw.rect(window,outline(self.x-2,self.y-2,self.width+4,self.height+4),0)
pygame.draw.rect(window,self.color,(self.x,self.y,self.width,self.height),0)
if self.text != '':
font = pygame.font.SysFont("comicsans",60)
text = font.render(self.text,1,(0,0,0))
window.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y+ (self.height/2 - text.get_height()/2)))
def isOver(self,pos):
# Pos is mouse position or tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def playSoundIfMouseIsOver(self,pos,sound):
if self.isOver(pos):
if not self.over:
Hover.play()
self.over = True
else:
self.over = False
class Sweep:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.speed = 2
self.rect = pygame.Rect(x,y,width,height)
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# Color
white = (255,255,255)
Black = (0,0,0)
# Calss's cords,size, and color
playerman = Player(230,150,40,40,white)
right = Sweep(-600,0,600,800,Black)
right2 = Sweep(530,0,600,800,Black)
left1 = Sweep(-550,0,800,800,Black)
left2 = Sweep(250,0,800,800,Black)
sweeps = [right,right2,left1,left2]
font = pygame.font.Font("img/Bubble.ttf",60)
text = font.render("SPACE TO START!",True,(0,0,0))
textRect = text.get_rect()
textRect.center = ((250,400))
Sbutton = button11((0,255,0),431,16,40,50, '')
# Displaying class's in main loop
def redrawwindow():
window.fill((255,0,0))
# Drawing my classes and other things
playerman.draw()
window.blit(text,textRect)
if on:
window.blit(music_on,(420,10))
if off:
window.blit(music_off,(420,10))
for Sweep in sweeps:
Sweep.draw()
sound = True
mouseisover = True
switch = 1
Stimer = 0
off = False
on = True
timer = 0
fps = 35
clock = pygame.time.Clock()
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
if switch == 1 and Sbutton.isOver(pos):
switch = 2
on = False
off = True
else:
if switch == 2 and Sbutton.isOver(pos):
switch = 1
on = True
off = False
timer += 1
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE] and timer >= 20:
Stimer += 1
if Stimer > 0 :
Stimer += 1
right.x += 20
right2.x -= 20
if Stimer >= 32:
main_loop()
Stimer = 0
left1.x -= 20
left2.x += 20
redrawwindow()
pygame.display.update()
pygame.quit()
def main_loop():
global lose
# Making both peipes separate
Pipe_distance = 830
# part of making background shift
bg_shift = 0
# player class
# player class
class Player:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.speed = 5
self.JumpCount = False
self.isJump = 10
self.fall = 0
self.rect = pygame.Rect(x,y,width,height)
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# Pipe class
class Pipe:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.speed = 3
self.rect = pygame.Rect(x,y,width,height)
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# Pipe2 class
class Pipe2:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.speed = 3
self.rect = pygame.Rect(x,y,width,height)
def get_rect(self):
self.rect.topleft = (self.x,self.y)
return self.rect
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
class Sweep:
def __init__(self,x,y,width,height,color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.speed = 2
self.rect = pygame.Rect(x,y,width,height)
def draw(self):
self.rect.topleft = (self.x,self.y)
pygame.draw.rect(window,self.color,self.rect)
# Color
white = (255,255,255)
green = (0,255,0)
blue = (0,0,255)
Black = (0,0,0)
# Calss's cords,size, and color
playerman = Player(200,200,40,40,white)
pipe1 = Pipe(350,900,60,700,green)
pipe2 = Pipe2(350,-900,60,700,green)
pipe3 = Pipe(720,9900,60,700,white)
pipe4 = Pipe2(720,-9900,60,700,blue)
left1 = Sweep(-550,0,800,800,Black)
left2 = Sweep(250,0,800,800,Black)
# All my list
pipes = [pipe1,pipe3]
pipes2 = [pipe2,pipe4]
sweeps = [left1,left2]
# Point system
font = pygame.font.Font("img/CAT.ttf",60)
score = 0
text = font.render(""+str(score), True,(255,255,255))
textRect = text.get_rect()
textRect.center = ((250,60))
lose = False
def quitgame():
pygame.quit()
def unlose():
global lose
lose = False
def lost():
lfont = pygame.font.Font("img/CAT.ttf",60)
ltext = lfont.render("You Died",True,(255,255,255))
ltextRect = ltext.get_rect()
ltextRect.center = ((250,90))
lfont2 = pygame.font.Font("img/CAT.ttf",60)
ltext2 = lfont2.render("Score",True,(255,255,255))
ltextRect2 = ltext2.get_rect()
ltextRect2.center = ((250,510))
lfont3 = pygame.font.Font("img/CAT.ttf",50)
ltext3 = lfont3.render("Space To Return",True,(255,0,255))
ltextRect3 = ltext3.get_rect()
ltextRect3.center = ((250,270))
timer = 0
while lose:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
timer += 1
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE] and timer >= 20:
game2()
window.fill((0,0,0))
text = font.render(""+str(score), True,(255,255,255))
textRect.center = ((250,450))
window.blit(ltext,ltextRect)
window.blit(ltext2,ltextRect2)
window.blit(ltext3,ltextRect3)
window.blit(text,textRect)
pygame.display.update()
clock.tick(15)
# Displaying class's in main loop
def redrawwindow():
window.fill((0,0,0))
# Drawing my classes and other things
playerman.draw()
for Pipe in pipes:
Pipe.draw()
for Pipe2 in pipes2:
Pipe2.draw()
for Sweep in sweeps:
Sweep.draw()
window.blit(text,textRect)
# To make the game more difuclt
ptimer = 0
# for playing sprite when player jumps
# Making it so the rectangle dose not come for a whilw
Ptimer = 0
Ptimer2 = 0
spcdown = False
sound = True
# for making firse play once
fps = 35
clock = pygame.time.Clock()
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Making most of my classes move
for Pipe in pipes:
Pipe.x -= Pipe.speed
for Pipe2 in pipes2:
Pipe2.x -= Pipe2.speed
for Pipe2 in pipes2:
if Pipe2.x <= -200:
Pipe2.x = 550
left1.x -= 20
left2.x += 20
# Randomizing pipe
for Pipe in pipes:
if Pipe.x <= -200:
Pipe.x = 550
Pipe.y = random.randint(150,500)
pipe2.y = pipe1.y - Pipe_distance
pipe4.y = pipe3.y - Pipe_distance
# Making the game faster
ptimer += 1
if ptimer == 10000:
for Pipe in pipes:
for Pipe2 in pipes2:
Pipe.speed += 1
Pipe2.speed += 1
bg_shift += 3
for Pipe in pipes:
if playerman.rect.colliderect(Pipe.rect):
lose = True
lost()
for Pipe2 in pipes2:
if playerman.rect.colliderect(Pipe2.rect):
lose = True
lost()
keys = pygame.key.get_pressed()
if not keys[pygame.K_SPACE]:
spcdown = False # space released
if keys[pygame.K_SPACE]:
Jumping = 1
if not spcdown:
spcdown = True
collide = False
playerman.y += playerman.speed
# bird moving
if not playerman.isJump:
# [...]
# the bird is allowed to jump even if it is not colliding:
if keys[pygame.K_SPACE]:
playerman.isJump = True
if collide:
playerman.fall = 0
else:
if playerman.JumpCount > 0:
playerman.y -= (playerman.JumpCount*abs(playerman.JumpCount))*0.3
playerman.JumpCount -= 1
else:
playerman.JumpCount = 10
# if K_SPACE is pressed, then the bird keeps jumping
if not keys[pygame.K_SPACE]:
playerman.isJump = False
redrawwindow()
pygame.display.update()
pygame.quit()
unlose()
game2()
main_loop()
The problem is probably caused by using two separate variables to control the state of the sound:
if on:
window.blit(music_on,(420,10))
if off:
window.blit(music_off,(420,10))
I suggest using only a single, descriptive, variable name:
if ( sound_muted ):
window.blit( music_on, (420,10) ) # show "un-mute" button
else:
window.blit( music_off, (420,10) ) # show "mute" button
And change that when the image is clicked:
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
if Sbutton.isOver(pos):
sound_muted = not sound_muted # mute or un-mute the sound.

How Do I Make A Play Again Button That Restarts My Pygame From The Beginning Pygame? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
so I am remaking flappy bird and I wondering how I could make a remake button that restarts my game all over again video right now I have it as crashing the game when it collides with the pip
right now I have it has quiting my game when I collid with the pips
# colisions between the up platforms
for pip in pips:
if bird1.rect.colliderect(pip.hitbox):
print("collided")
pygame.quit()
keys = pygame.key.get_pressed()
heres my full code
import pygame
import random
pygame.init()
#this is screem height
window = pygame.display.set_mode((500,500))
#know we put screem name
pygame.display.set_caption("Noobs Flappy Bird Game")
#---------------------------------------------------
def button(msg,x,y,w,h,ic,ac,action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(window, ac,(x,y,w,h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(window, ic,(x,y,w,h))
smallText = pygame.font.SysFont("Candarai.ttf",40)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ( (x+(w/2)), (y+(h/2)) )
window.blit(textSurf, textRect)
#------------------------------------------------------
def text_objects(text, font):
black = (0,0,0)
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def game_intro():
# this makes it
snow_list=[]
no_of_circles=100;
clock = pygame.time.Clock()
FPS = 60
clock.tick(FPS)
for i in range(no_of_circles):
x = random.randrange(0, 600)
y = random.randrange(0, 500)
snow_list.append([x,y])
red = (200,0,0)
green = (255,250,250)
bright_red = (255,250,0)
bright_green = (0,255,0)
clock = pygame.time.Clock()
intro = True
while intro:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
intro = False
pygame.quit()
window.fill((0,0,0))
for point in snow_list:
point[1]+=1
pygame.draw.circle(window, (255,255,255), point, 2)
if(point[1] >= 600):
point[0] = random.randrange(0, 600)
point[1] = random.randrange(-10, -5)
clock.tick(FPS)
font = pygame.font.Font("Candarai.ttf", 50)
loltext = font.render("Blaste OF Immunity", True,(255,255,255))
lolrect = loltext.get_rect()
lolrect.center = ((250,100))
window.blit(loltext,lolrect)
font = pygame.font.Font("Candarai.ttf", 50)
loltext = font.render("Classic Flappy Bird Game", True,(255,255,255))
lolrect = loltext.get_rect()
lolrect.center = ((250,160))
window.blit(loltext,lolrect)
font = pygame.font.Font("Candarai.ttf", 50)
loltext = font.render("By:Habib I.", True,(255,255,255))
lolrect = loltext.get_rect()
lolrect.center = ((280,460))
window.blit(loltext,lolrect)
button("Click To Play!",180,250,190,40,green,bright_green,main_game)
# ---------------------------------------------------------------------
pygame.display.update()
def main_game():
#player class
class bird:
def __init__(self,x,y,height,width,color):
self.x = x
self.y =y
self.bright = [
pygame.image.load("killers50.png"),
pygame.image.load("killers51.png"),
pygame.image.load("killers52.png"),
pygame.image.load("killers53.png"),
]
self.bleft = [
pygame.image.load("ms1.png"),
pygame.image.load("ms2.png"),
pygame.image.load("ms3.png"),
pygame.image.load("ms4.png"),
]
self.bright = [pygame.transform.scale(image,(image.get_width()//15,image.get_height()//15)) for image in self.bright]
self.bleft = [pygame.transform.scale(image,(image.get_width()//15,image.get_height()//15)) for image in self.bleft]
self.height = height
self.width = width
self.isJump = False
self.JumpCount = 10
self.fall = 0
self.speed = 5
self.Walking = 0
self.vel = 5
self.color = color
self.rect = pygame.Rect(x,y,height,width)
self.direction = "down"
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
# this makes the enemy move right and left
def draw(self):
self.rect.topleft = (self.x,self.y)
self.hitbox = (self.x + 17, self.y + 11, 29, 22)
pygame.draw.rect(window, (255,0,0), self.hitbox,2)
if self.Walking + 1 >= 33:
self.Walking = 0
if self.vel > 0: # left
window.blit(self.bright[self.Walking % 3], (self.x,self.y))
self.Walking += 1
else: # right
window.blit(self.bleft[self.Walking % 3], (self.x,self.y))
self.Walking += 1
class platform:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.pipis = pygame.image.load("pip.png")
self.pipis = pygame.transform.scale(self.pipis,(self.pipis.get_width()//3,self.pipis.get_height()//3))
self.rect = pygame.Rect(x,y,height,width)
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
def draw(self):
self.rect.topleft=(self.x,self.y )
window.blit(self.pipis,self.rect)
self.rect.topleft = (self.x,self.y)
self.hitbox = (self.x + 5, self.y + 4, 79, 552)
pygame.draw.rect(window, (255,0,0), self.hitbox,2)
class pip:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.pipis = pygame.image.load("pipo.png")
self.pipis = pygame.transform.scale(self.pipis,(self.pipis.get_width()//3,self.pipis.get_height()//3))
self.rect = pygame.Rect(x,y,height,width)
self.hitbox = (self.x + 17, self.y + -11, 29, 100)
def draw(self):
self.rect.topleft=(self.x,self.y)
window.blit(self.pipis,self.rect)
self.hitbox = (self.x + 5, self.y + -200, 79, 552)
pygame.draw.rect(window, (255,0,0), self.hitbox,2)
#player and enemy
white = (255,255,255)
bird1 = bird(0,400,40,20,white)
red = (255,48,48)
platform1 = platform(600,300,50,550,white)
platform2 = platform(800,200,90,550,white)
platform3 = platform(1100,300,90,550,white)
platform4 = platform(1300,400,90,550,white)
platform5 = platform(1500,300,90,550,white)
platform6 = platform(1800,200,90,550,white)
# ROUND 2
platform7 = platform(2200,300,90,550,white)
platform8 = platform(2400,200,90,550,white)
platform9 = platform(2600,300,90,550,white)
platform10 = platform(2700,400,90,550,white)
platform11 = platform(2900,300,90,550,white)
platform12 = platform(3200,200,90,550,white)
# rOUND 3
platform13 = platform(3400,300,90,550,white)
platform14 = platform(3600,200,90,550,white)
platform15 = platform(3800,300,90,550,white)
platform16 = platform(4000,400,90,550,white)
platform17 = platform(4200,300,90,550,white)
platform18 = platform(4400,200,90,550,white)
# ROUND 4
platform19 = platform(600,300,90,550,white)
platform20 = platform(800,200,90,550,white)
platform21 = platform(1100,300,90,550,white)
platform22 = platform(1300,400,90,550,white)
platform23 = platform(1500,300,90,550,white)
platform24 = platform(1800,200,90,550,white)
platforms = [platform1,platform2,platform3,platform4,platform5,platform6,platform7,platform8,platform9,platform10,platform11,platform12,platform13,platform14,platform15,platform16,platform17,platform18,platform19,platform20,platform21,platform22,platform23,platform24]
# sceond pip
pip1 = pip(600,-160,100,50,white)
pip2 = pip(800,-270,150,50,white)
pip3 = pip(1100,-170,150,50,white)
pip4 = pip(1300,-170,150,50,white)
pip5 = pip(1500,-170,150,50,white)
pip6 = pip(1800,-270,150,50,white)
# ROUND 2
pip7 = pip(2200,-160,150,50,white)
pip8 = pip(2400,-270,150,50,white)
pip9 = pip(2600,-170,150,50,white)
pip10 = pip(2700,-170,150,50,white)
pip11 = pip(2900,-170,150,50,white)
pip12 = pip(3200,-270,150,50,white)
# ROUND 3
# rOUND 3
pip13 = pip(3400,-160,150,50,white)
pip14 = pip(3600,-270,150,50,white)
pip15 = pip(3800,-170,150,50,white)
pip16 = pip(4000,-170,150,50,white)
pip17 = pip(4200,-170,150,50,white)
pip18 = pip(4400,-270,150,50,white)
# ROUND 4
pip19 = pip(600,-160,150,50,white)
pip20 = pip(800,-270,150,50,white)
pip21 = pip(1100,-170,150,50,white)
pip22 = pip(1300,-170,150,50,white)
pip23 = pip(1500,-170,150,50,white)
pip24 = pip(1800,-270,150,50,white)
pips = [pip1,pip2,pip3,pip4,pip5,pip6,pip7,pip8,pip9,pip10,pip11,pip12,pip13,pip14,pip15,pip16,pip17,pip18,pip19,pip20,pip21,pip22,pip23,pip24]#window
class orb:
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft = (self.x,self.y)
class particleAndPoint:
def __init__(self,x,y,height,width,color):
self.x = x
self.y =y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)
def draw(self):
self.rect.topleft = (self.x,self.y)
particleAndPoints = []
# this is the orbs
orb1 = orb(1500,100,50,550,white)
orb2 = orb(2600,100,50,550,white)
orbes = [orb1,orb2]
platformGroup = pygame.sprite.Group
platformList = []
level = [" ",
" ",
" ",
" ",
" p p p p p p p p p p p p p p p p p p",
" ",
" ",
" ",
" ",
" ",
" ",]
for iy, row in enumerate(level):
for ix, col in enumerate(row):
if col == "p":
new_platforms = particleAndPoint(ix*10, iy*0, 10,1010,(255,255,255))
particleAndPoints.append(new_platforms)
# the score text
font = pygame.font.Font('Candarai.ttf',60)
score = 0
loltext = font.render("" + str(score), True, (255,255,255))
lolrect = loltext.get_rect()
lolrect.center = ((130,60))
# wow sound anime
wowsound = pygame.mixer.Sound("wows.wav")
explodesound = pygame.mixer.Sound("partexplode.wav")
class particle:
def __init__(self,x,y):
self.x = x
self.y = y
self.x_vel = random.randrange(-10,13)*1
self.y_vel = random.randrange(-10,-1)*1
self.lifetime = 0
def draw(self,window):
self.lifetime += 1
if self.lifetime <30:
self.x -= self.x_vel
self.y -= self.y_vel
pygame.draw.rect(window,(232,255,24),(self.x,self.y, 16,16))
# draw the screen things
# scrolling screen
bg_shift = 0
def redrawwindow():
bg = pygame.image.load("bgs.png")
bg_width = bg.get_width()
bg_offset = bg_shift % bg_width
window.blit(bg, (-bg_offset, 0))
window.blit(bg, (bg_width - bg_offset, 0))
#player draw
bird1.draw()
for platform in platforms:
platform.draw()
for pip in pips:
pip.draw()
for particleAndPoint in particleAndPoints:
particleAndPoint.draw()
window.blit(loltext,lolrect)
for orb in orbes:
orb.draw()
for particle in particles:
particle.draw(window)
fps = (30)
clock = pygame.time.Clock()
particles = []
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# if player collides with the obsticles add 1 to the player and delete the obstacle
for one in range(len(particleAndPoints)-1,-1,-1):
if bird1.rect.colliderect(particleAndPoints[one].rect):
score += 1
bird1.speed += 0.2
del particleAndPoints[one]
explodesound.play()
loltext = font.render("" + str(score), True, (255,255,255))
lolrect.center = ((130,60))
for x in range(60):
x, y = bird1.rect.center
particles.append( particle( x, y ) )
# if ball collides with player1 show the particles
# if ball collides with player1 show the particles
if bird1.rect.colliderect( orb1.rect ):
for x in range(60):
wowsound.play()
explodesound.play()
x, y = bird1.rect.center
particles.append( particle( x, y ) )
if bird1.rect.colliderect( orb2.rect ):
for x in range(60):
wowsound.play()
explodesound.play()
x, y = bird1.rect.center
particles.append( particle( x, y ) )
# collisions between the platforms
for platform in platforms:
if bird1.rect.colliderect(platform.hitbox):
print("collided")
pygame.quit()
# colisions between the up platforms
for pip in pips:
if bird1.rect.colliderect(pip.hitbox):
print("collided")
pygame.quit()
keys = pygame.key.get_pressed()
# bird moving
bird1.x += bird1.speed
if not bird1.isJump:
bird1.y += bird1.speed
bird1.isJump = False
if keys[pygame.K_SPACE]:
bird1.isJump = True
# this part lets you jump on platform
collide = False
for platform in platforms:
if bird1.rect.colliderect(platform.rect):
collide = False
# this makes the player fall down up to
if bird1.rect.bottom >= 500:
collide = True
bird1.isJump = False
bird1.JumpCount = 10
bird1.y = 500 - bird1.height
if collide:
if keys[pygame.K_SPACE]:
bird1.isJump = True
bird1.fall = 0
else:
if bird1.JumpCount > 0:
bird1.y -= (bird1.JumpCount*abs(bird1.JumpCount)) * 0.2
bird1.JumpCount -= 1
else:
bird1.JumpCount = 10
bird1.isJump = False
# this scrolls my screen right
if bird1.x > 300:
bird1.x -= bird1.speed
for platform in platforms:
platform.x -= bird1.speed
for pip in pips:
pip.x -=bird1.speed
for particleAndPoint in particleAndPoints:
particleAndPoint.x -= bird1.speed
for orb in orbes:
orb.x -= bird1.speed
# scrolling window
bg_shift += round(bird1.speed / 2)
redrawwindow()
pygame.display.update()
pygame.quit()
game_intro()
main_game()
I just want a basic functional button that allows my game to restart and works when my bird collides with the pips
black = (0,0,0)
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',25)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((500/2),(500/2))
window.blit(TextSurf, TextRect)
pygame.display.update()
main_game()
time.sleep(2)
def crash():
message_display('You Crashed')

Pygame Inquiry - How to have different sprites from different classes collide

So I have been searching for a long time online to try and find out how to get my two sprite classes in pygame to collide. I am trying to make a basic game where the player has to dodge the squares. I would like some code for when the player hits one of the squares gameOver is true. Here's the code the player.
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, image):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('Tri.png')
self.image = pygame.transform.scale (self.image, (int(width/16), int(width/15)))
self.rect = self.image.get_rect()
self.width, self.height = self.image.get_size()
self.rect.x = x
self.rect.y = y
def update(self):
mx, my = pygame.mouse.get_pos()
self.rect.x = mx - self.width/2
self.rect.y = (height * 0.8)
if self.rect.x <= 0 - self.width/2 + 10:
self.rect.x += 10
if self.rect.x + self.width >= width:
self.rect.x = width - self.width
def draw(self, screen):
if bgColour == black:
self.image = pygame.image.load('Tri2.png')
self.image = pygame.transform.scale (self.image, (int(width/16), int(width/15)))
else:
self.image = pygame.image.load('Tri.png')
self.image = pygame.transform.scale (self.image, (int(width/16), int(width/15)))
self.width, self.height = self.image.get_size()
gameDisplay.blit(self.image, self.rect)
Here's the code for the squares
class Square(pygame.sprite.Sprite):
def __init__(self, box_x, box_y, box_width, box_height,colour, box_speed, box_border, BC):
self.box_x = box_x
self.box_y = box_y
self.box_width = box_width
self.box_height = box_height
self.colour = colour
self.box_speed = box_speed
self.box_border = box_border
self.BC = BC
border = pygame.draw.rect(gameDisplay, self.BC, [self.box_x - self.box_border/2, self.box_y - self.box_border/2, self.box_width + self.box_border, self.box_height + self.box_border])
box = pygame.draw.rect(gameDisplay, self.colour, [self.box_x, self.box_y, self.box_width, self.box_height])
def Fall(self):
if self.box_y < height:
self.box_y += box_speed
elif self.box_y > height + 100:
del square[0]
border = pygame.draw.rect(gameDisplay, self.BC, [self.box_x - self.box_border/2, self.box_y - self.box_border/2, self.box_width + self.box_border, self.box_height + self.box_border])
box = pygame.draw.rect(gameDisplay, self.colour, [self.box_x, self.box_y, self.box_width, self.box_height])
And the main game loop. Sorry for the messy code and probably redundant variables but I'm still learning :)
def game_loop():
mx, my = pygame.mouse.get_pos()
x = mx
y = (height * 0.8)
player = Player(x, y, 'Tri.png')
box_width = int(width/15)
if round(box_width/5) % 10 == 0:
box_border = round(box_width/5)
else:
box_border = round(box_width/5 + 1)
box_x = random.randrange(0, width)
box_y = 0 - box_width
min_gap = box_width/4
global box_speed
box_col = False
box_start = random.randrange(0, width)
delay = 0
global square
square = []
move_speed = 10
#level variables
box_speed = 6
max_gap = box_width/2
score = 0
bgColourList = [white, black, white, white]
global bgColour
bgColour = bgColourList[0]
Blist = [red, green, black, pink, white]
BC = Blist[0]
Clist = [red, black, black, pink, white]
box_colour = red
text_colour = black
z = 60
level = 0
delayBG = 0
levelChange = 400
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameDisplay.fill(bgColour)
#blitting the player
player.update()
player.draw(gameDisplay)
#sets delay for level change
if score % levelChange == 0:
delayBG = 120
z = 120
if delayBG == 0:
bgColour = bgColourList[level]
BC = Blist[level]
box_colour = Clist[level]
if delay == 0:
score += 1
delay += 3
if delayBG == 0:
level += 1
box_speed += 1
max_gap -= 1
#creating a new square
if z == 0:
new = random.randint(0, width)
square.append(Square(new, box_y, box_width, box_width , box_colour, box_speed, box_border, BC))
z = random.randint(int(min_gap), int(max_gap))
last = new
lasty = box_y
#calling the Square.fall() function
for i in square:
i.Fall()
"""tris.remove(i)
i.checkCollision(tris)
tris.add(i)"""
pygame.draw.rect(gameDisplay, bgColour, [0,0, width, int(height/23)])
message_to_screen(str(score), text_colour, -height/2 + 15, 0)
delayBG -= 1
z -= 1
delay -= 1
pygame.display.update()
clock.tick(FPS)
game_loop()
pygame.quit()
quit()
Thank you in advance!
Create a group to hold all your Square objects:
square_group = pygame.sprite.Group()
Every time you create a Square object, add it to the group:
steven = Square(new, box_y, box_width, box_width , box_colour, box_speed, box_border, BC)
square_group.add(steven)
Then you can use spritecollide to check for collisions and act accordingly.
collisions = pygame.sprite.spritecollide(player, square_group, False)
if collisions:
gameExit = True

TypeError: argument 1 must be pygame.Surface, not list [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was working on a movement animations since I saw a youtuber explaining how to do it, but I'm getting this error:
TypeError: argument 1 must be pygame.Surface, not list
My code is about 500 lines.
# Pygame Template - skeleton for a new pygame project
import pygame
import random
import os
from os import path
vec = pygame.math.Vector2
width = 800
height = 600
FPS = 60
POWERUP_TIME = 5000
title = 'Parkourse'
# Player properties
player_acceleration = 0.5
player_friction = -0.12
player_gravity = 0.8
player_jump = 10
# Starting platforms
platforms_list = [(0,height-40,width,50), # Ground
(0,0,800,10), # Top
(0,0,10,600), # Left Border
(790,height-400,10,600),# Right Border
(250,height - 160,width-200,10), # Floor 1
(0,height - 280,width-200,10), # Floor 2
(250,height - 400,width-100,10)] # Floor 3
# Define Colors
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
# set up assets folders
game_folder = os.path.dirname(__file__)
image_folder = os.path.join(game_folder, "Image")
sound_folder = os.path.join(game_folder, "Sound")
# Initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption(title)
clock = pygame.time.Clock()
# Load all game graphics
background = pygame.image.load(path.join(image_folder, "background.png")).convert()
background_rect = background.get_rect()
no_mvmt_0 = pygame.image.load(path.join(image_folder,"no_mvmt_0.png")).convert()
no_mvmt_1 = pygame.image.load(path.join(image_folder,"no_mvmt_1.png")).convert()
running_0 = pygame.image.load(path.join(image_folder,"running_0.png")).convert()
running_1 = pygame.image.load(path.join(image_folder,"running_1.png")).convert()
jumping_0 = pygame.image.load(path.join(image_folder,"jumping_0.png")).convert()
mini_no_mvmt = pygame.transform.scale(no_mvmt_0, (25,48))
mini_no_mvmt.set_colorkey(white)
scissors = pygame.image.load(path.join(image_folder,"scissors.png")).convert()
mob_left = pygame.image.load(path.join(image_folder,"mob_left.png")).convert()
power_upper_image = {}
power_upper_image['shield_0'] = pygame.image.load(path.join(image_folder,"shield_upper_0.png")).convert()
power_upper_image['shield_1'] = pygame.image.load(path.join(image_folder,"shield_upper_1.png")).convert()
power_upper_image['shield_2'] = pygame.image.load(path.join(image_folder,"shield_upper_2.png")).convert()
power_upper_image['life'] = pygame.image.load(path.join(image_folder,"life_upper.png")).convert()
power_upper_image['power'] = pygame.image.load(path.join(image_folder,"power.png")).convert()
explosion_animation = {}
explosion_animation['normal']=[]
explosion_animation['small']=[]
explosion_animation['player']=[]
for explosion in range(5):
explose = 'explosion_{}.png'.format(explosion)
image = pygame.image.load(path.join(image_folder, explose)).convert()
image.set_colorkey(white)
image.set_colorkey(black)
image_normal = pygame.transform.scale(image, (80,80))
explosion_animation['normal'].append(image_normal)
image_small = pygame.transform.scale(image, (30, 30))
explosion_animation['small'].append(image_small)
death = 'dying_{}.png'.format(explosion)
image = pygame.image.load(path.join(image_folder, death)).convert()
image.set_colorkey(white)
explosion_animation['player'].append(image)
#Load all game sounds
scream_sound = []
for scream in ["slightscream_0.wav", "slightscream_1.wav", "slightscream_2.wav",
"slightscream_3.wav", "slightscream_4.wav", "slightscream_5.wav",
"slightscream_6.wav", "slightscream_7.wav", "slightscream_8.wav",
"slightscream_9.wav", "slightscream_10.wav", "slightscream_11.wav",
"slightscream_12.wav", "slightscream_13.wav", "slightscream_14.wav"]:
scream_sound.append(pygame.mixer.Sound(path.join(sound_folder,scream)))
shoot_sound = pygame.mixer.Sound(path.join(sound_folder,"shoot.wav"))
shield = pygame.mixer.Sound(path.join(sound_folder,"shield.wav"))
life = pygame.mixer.Sound(path.join(sound_folder,"life.wav"))
special_power = pygame.mixer.Sound(path.join(sound_folder,"special_power.wav"))
death_sound = pygame.mixer.Sound(path.join(sound_folder,"death.ogg"))
explosion_sound = []
for sound in ["explosion.wav", "explosion_2.wav"]:
explosion_sound.append(pygame.mixer.Sound(path.join(sound_folder, sound)))
pygame.mixer.music.load(path.join(sound_folder,"gameplay.ogg"))
pygame.mixer.music.set_volume(0.6)
font_name = pygame.font.match_font('arial')
def draw_text (surf, text,color,size, x, y):
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
def newmob():
m = Mobs()
all_sprites.add(m)
mobs.add(m)
def draw_shield_bar(screen, x,y,percentage):
if percentage < 0:
percentage = 0
bar_lenght = 100
bar_height = 10
fill = (percentage / 100) * bar_lenght
outline_rect = pygame.Rect(x,y,bar_lenght,bar_height)
fill_rect = pygame.Rect(x,y,fill, bar_height)
pygame.draw.rect(screen, green, fill_rect)
pygame.draw.rect(screen, black, outline_rect, 2) # 2 is the the number of pixels
# of how wide you want the outline
# of the rectangle to be
def draw_lives (surface, x, y, lives, image):
for i in range(lives):
image_rect = image.get_rect()
image_rect.x = x + 30 * i
image_rect.y = y
surface.blit(image, image_rect)
score = 0
def show_game_over_screen():
screen.blit(background, background_rect)
draw_text(screen, "Dang..!",red,100, width/2, 200)
draw_text(screen, "Score: " + str(score),blue,30, width/2, 330)
draw_text(screen, "Press any key to retry",blue,30, width/2, 390)
pygame.display.flip()
waiting = True
while waiting:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYUP:
waiting = False
def show_start_screen():
screen.blit(background, background_rect)
draw_text(screen,"Parkourse!", green, 100, width/2, 200)
draw_text(screen, "Use the arrow keys to move, S to fire, and space to Jump",blue,30, width/2, 330)
draw_text(screen, "Press any key to begin",blue,30, width/2, 390)
pygame.display.flip()
waiting = True
while waiting:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYUP:
waiting = False
class Player (pygame.sprite.Sprite):
# Sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.load_movement_images()
self.image = self.standing_frame[0]
self.rect = self.image.get_rect()
self.pos = vec(50,500)
self.vel = vec(0,0)
self.acc = vec(0,0)
self.shield = 100
self.lives = 3
self.hidden = False
self.hide_timer = pygame.time.get_ticks()
self.power = 1
self.power_timer = pygame.time.get_ticks()
self.running = False
self.jumping = False
self.current_frame = 0
self.last_update = 0
def load_movement_images(self):
self.standing_frame = [no_mvmt_0, no_mvmt_1]
self.running_frame_right = [running_0,running_1]
self.running_frame_left = []
for frame in self.standing_frame:
frame.set_colorkey(white)
for frame in self.running_frame_right:
self.running_frame_left.append(pygame.transform.flip(frame,True,False)) # True is horizontaly, False is vertically
frame.set_colorkey(white)
self.jumping_frame = jumping_0
self.jumping_frame.set_colorkey(white)
def animate(self):
now = pygame.time.get_ticks()
if not self.jumping and not self.running:
if now - self.last_update > 350:
self.last_update = now
self.current_frame = (self.current_frame + 1) % len(self.standing_frame)
self.image = self.standing_frame
def jump(self):
# Jump only if standing on a Platform
self.rect.x +=1
hits = pygame.sprite.spritecollide(player,platforms, False)
self.rect.x -= 1
if hits:
self.vel.y = - player_jump
def update(self):
self.animate()
# timeout for powerups
if self.power >=2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME:
self.power -= 1
self.power_time = pygame.time.get_ticks()
# unhide if hidden
if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:
self.hidden = False
self.pos = vec(30, 400)
self.acc = vec(0,player_gravity)
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT] or keystate[pygame.K_a]:
self.acc.x = -player_acceleration
if keystate[pygame.K_RIGHT] or keystate[pygame.K_d]:
self.acc.x = player_acceleration
if keystate[pygame.K_SPACE]:
player.jump()
# apply friction
self.acc.x += self.vel.x * player_friction
# equations of motions
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
# wrap around the sides of the screen
if self.pos.x > 750:
self.pos.x = 750
if self.pos.x <= 0:
self.pos.x = 25
self.rect.midbottom = self.pos
def powerup(self):
self.power += 1
self.power_time = pygame.time.get_ticks()
def shoot(self):
if self.power == 1:
bullet = Bullet(self.pos.x + 5, self.pos.y - 20)
all_sprites.add(bullet)
bullets.add(bullet)
shoot_sound.play()
if self.power >= 2:
bullet1 = Bullet(self.pos.x + 5, self.pos.y - 20)
bullet2 = Bullet(self.pos.x + 35, self.pos.y -20)
all_sprites.add(bullet1)
all_sprites.add(bullet2)
bullets.add(bullet1)
bullets.add(bullet2)
shoot_sound.play()
def hide(self):
# hide the player temporarily
self.hidden = True
self.hide_timer = pygame.time.get_ticks()
self.pos = vec(0, 6000)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = scissors
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.image = pygame.transform.scale(scissors, (30,15))
self.rect.bottom = y
self.rect.centerx = x
self.speedx = 10
def update(self):
self.rect.x += self.speedx
# kill if it moves off the top of the screen
if self.rect.bottom < 0:
self.kill()
class Mobs(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = mob_left
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.rect.x = random.randrange(0,800)
self.rect.y = 530
self.speedx = 2
def update(self):
self.rect.x -= self.speedx
if self.rect.right < 0:
self.rect.x = 800
class Explosion(pygame.sprite.Sprite):
def __init__(self, center, size, frame):
pygame.sprite.Sprite.__init__(self)
self.size = size
self.image = explosion_animation[self.size][0]
self.rect = self.image.get_rect()
self.rect.center = center
self.frame = 0
self.last_update = pygame.time.get_ticks()
self.frame_rate = frame
def update(self):
now = pygame.time.get_ticks()
if now - self.last_update > self.frame_rate:
self.last_update = now
self.frame += 1
if self.frame == len(explosion_animation[self.size]):
self.kill()
else:
center = self.rect.center
self.image = explosion_animation[self.size][self.frame]
self.rect = self.image.get_rect()
self.rect.center = center
class Normal_Power(pygame.sprite.Sprite):
def __init__(self, center):
pygame.sprite.Sprite.__init__(self)
self.type = random.choice(['shield_0','shield_1','shield_2'])
self.image = power_upper_image[self.type]
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.rect.center = center
class Special_Power(pygame.sprite.Sprite):
def __init__(self, center):
pygame.sprite.Sprite.__init__(self)
self.type = random.choice(['life','power'])
self.image = power_upper_image[self.type]
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.rect.center = center
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((w, h))
self.image.fill(black)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
pygame.mixer.music.play(loops=-1) # loops = -1 means that pygame will restart the song when it's finished
# Game loop
running = True
new_game = True
game_over = False
while running:
if new_game:
show_start_screen()
new_game = False
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
for plat in platforms_list:
p = Platform (*plat)
all_sprites.add(p)
platforms.add(p)
mobs = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
bullets = pygame.sprite.Group()
powerups = pygame.sprite.Group()
for i in range(1):
newmob()
score = 0
if game_over:
show_game_over_screen()
game_over = False
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
for plat in platforms_list:
p = Platform (*plat)
all_sprites.add(p)
platforms.add(p)
mobs = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
bullets = pygame.sprite.Group()
powerups = pygame.sprite.Group()
for i in range(1):
newmob()
score = 0
# Keep loop running at the right speed
clock.tick(FPS)
# Process input (events)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
player.shoot()
# Updates
all_sprites.update()
# check if player hits a platform - only if falling
if player.vel.y > 0:
hits = pygame.sprite.spritecollide(player,platforms,False)
if hits:
player.pos.y = hits[0].rect.top
player.vel.y = 0
# check to see if a bullet hit a mob
hits = pygame.sprite.groupcollide(mobs,bullets,True,True)
for hit in hits:
score += 1
random.choice(explosion_sound).play()
expl = Explosion(hit.rect.center, 'normal', 50)
all_sprites.add(expl)
if random.random() > 0.75:
power = Normal_Power(hit.rect.center)
all_sprites.add(power)
powerups.add(power)
if random.random() > 0.90:
lives = Special_Power(hit.rect.center)
all_sprites.add(lives)
powerups.add(lives)
newmob()
# check to see if the mob hit the player
hits = pygame.sprite.spritecollide(player, mobs,True)
for hit in hits:
random.choice(explosion_sound).play()
player.shield -= 25
newmob()
expl = Explosion(hit.rect.center, 'small', 50)
all_sprites.add(expl)
if player.shield <= 0:
death_sound.play()
death_animation = Explosion(player.rect.center, 'player', 100)
all_sprites.add(death_animation)
player.hide()
player.lives -= 1
player.shield = 100
else:
random.choice(scream_sound).play()
# check if the player hit a powerup
hits = pygame.sprite.spritecollide(player, powerups, True)
for hit in hits:
if hit.type == 'shield_0':
player.shield += 5
if player.shield >= 100:
player.shield = 100
shield.play()
if hit.type == 'shield_1':
player.shield += 20
if player.shield >= 100:
player.shield = 100
shield.play()
if hit.type == 'shield_2':
player.shield += 20
if player.shield >= 100:
player.shield = 100
shield.play()
if hit.type == 'life':
player.lives += 1
if player.lives >= 3:
player.lives = 3
life.play()
if hit.type == 'power':
special_power.play()
player.powerup()
# if the player died and the explosion finished playing
if player.lives == 0 and not death_animation.alive():
game_over = True
# Draw / Render
screen.fill(white)
screen.blit(background, background_rect)
all_sprites.draw(screen)
draw_text(screen,str(score),red,30, width/ 2, 30)
draw_text(screen,"Score:",red,30, width / 2, 3)
draw_shield_bar(screen,90,20, player.shield)
draw_lives(screen,95,40,player.lives, mini_no_mvmt)
# *after* drawing everything, flip the display
pygame.display.flip()
pygame.quit()
quit()
The error is caused by a sprite in your all_sprites group that has a list as its self.image attribute. I've just printed the sprites before the all_sprites.draw(screen) line
for sprite in all_sprites:
print(sprite, sprite.image)
and it was the player sprite which had a list as its image.
<Player sprite(in 1 groups)> [<Surface(40x25x32 SW)>, <Surface(40x25x32 SW)>]
In the load_movement_images method you define self.standing_frame as a list of two images/pygame.Surfaces and in __init__ you set self.image to the first item of that list. But in the animate method you set self.image to the whole list instead of the active image self.image = self.standing_frame and that leads to the error.
class Player (pygame.sprite.Sprite):
# Sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.load_movement_images()
# self.image is the first image in the
# self.standing_frame list.
self.image = self.standing_frame[0]
# ...
def load_movement_images(self):
self.standing_frame = [no_mvmt_0, no_mvmt_1]
# ...
def animate(self):
now = pygame.time.get_ticks()
if not self.jumping and not self.running:
if now - self.last_update > 350:
self.last_update = now
self.current_frame = (self.current_frame + 1) % len(self.standing_frame)
# Here you set the self.image to the self.standing_fram list instead one image.
self.image = self.standing_frame
# It should be:
# self.image = self.standing_frame[self.current_frame]

Categories

Resources