__init__() takes exactly 3 arguments (1 given)? - python
It is asking for 3 arguments and i have given it one. How do i give it 2 more and could you explain how to do that as well? Thanks
import pygame, random, collisionObjects
pygame.init()
screen = pygame.display.set_mode((640,480))
class Pirate(pygame.sprite.Sprite):
EAST = 0
def __init__(self, screen, dx):
self.screen = screen
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("king_pirate/running e0000.bmp")
self.image = self.image.convert()
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.inflate_ip(-50, -30)
self.rect.center = (0, random.randrange(30,450))
self.img = []
self.loadPics()
self.frame = 0
self.delay = 4
self.pause = self.delay
self.dx = dx
def update(self):
#set delay
self.pause -= 1
if self.pause <= 0:
self.pause = self.delay
self.frame += 1
if self.frame > 7:
self.frame = 0
self.image = self.img[self.frame]
self.rect.centerx += self.dx
if self.rect.centerx > self.screen.get_width():
self.rect.centerx = 0
self.rect.centery = random.randrange(30,450)
#load pictures
def loadPics(self):
for i in range(8):
imgName = "king_pirate/running e000%d.bmp" % i
tmpImg = pygame.image.load(imgName)
tmpImg.convert()
tranColor = tmpImg.get_at((0, 0))
tmpImg.set_colorkey(tranColor)
self.img.append(tmpImg)
class Pirate2(pygame.sprite.Sprite):
WEST = 0
def __init__(self, screen, dx):
self.screen = screen
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("pirate/running w0000.bmp")
self.image = self.image.convert()
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.inflate_ip(-50, -30)
self.rect.center = (640, random.randrange(20,460))
self.img = []
self.loadPics()
self.frame = 0
self.delay = 4
self.pause = self.delay
self.dx = dx
def update(self):
#set delay
self.pause -= 1
if self.pause <= 0:
self.pause = self.delay
self.frame += 1
if self.frame > 7:
self.frame = 0
self.image = self.img[self.frame]
self.rect.centerx -= self.dx
if self.rect.centerx < 0:
self.rect.centerx = self.screen.get_width()
self.rect.centery = random.randrange(20,460)
#load pictures
def loadPics(self):
for i in range(8):
imgName = "pirate/running w000%d.bmp" % i
tmpImg = pygame.image.load(imgName)
tmpImg.convert()
tranColor = tmpImg.get_at((0, 0))
tmpImg.set_colorkey(tranColor)
self.img.append(tmpImg)
#set up class for gold object,
class Gold(pygame.sprite.Sprite):
def __init__(self, screen, imageFile):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(imageFile)
self.image = self.image.convert()
self.rect = self.image.get_rect()
self.rect.centerx = random.randrange(0, screen.get_width())
self.rect.centery = random.randrange(0, screen.get_height())
#main character class
class Thief(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("thief2.gif")
self.image = self.image.convert()
tranColor = self.image.get_at((1, 1))
self.image.set_colorkey(tranColor)
self.rect = self.image.get_rect()
self.rect.inflate_ip(-15, -10)
self.rect.center = (30, (screen.get_height()-40))
self.dx = 30
self.dy = 30
if not pygame.mixer:
print("problem with sound")
else:
pygame.mixer.init()
self.collectcoin = pygame.mixer.Sound("collectcoin.wav")
self.hit = pygame.mixer.Sound("hit.ogg")
def update(self):
if self.rect.bottom > screen.get_height():
self.rect.centery = (screen.get_height()-40)
elif self.rect.top < 0:
self.rect.centery = 40
elif self.rect.right > screen.get_width():
self.rect.centerx = (screen.get_width()-30)
elif self.rect.left < 0:
self.rect.centerx = 30
#define movements
def moveUp(self):
self.rect.centery -= self.dy
def moveDown(self):
self.rect.centery += self.dy
def moveLeft(self):
self.rect.centerx -= self.dx
def moveRight(self):
self.rect.centerx += self.dx
def reset(self):
self.rect.center = (30, (screen.get_height()-40))
#set up a scoreboard
class Scoreboard(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.lives = 0
self.score = 0
self.font = pygame.font.SysFont("None", 40)
self.number = 0
#with a self updating label
def update(self):
self.text = "Damage: %d %% Gold Taken: %d" % (self.lives, self.score)
self.image = self.font.render(self.text, 1, (199,237,241))
self.rect = self.image.get_rect()
#define the game function
def game():
#set up background
background = pygame.Surface(screen.get_size())
background = pygame.image.load("sand.jpg")
background = pygame.transform.scale(background, screen.get_size())
screen.blit(background, (0, 0))
#initialize pirates & scoreboard sprites
pirate = Pirate()
scoreboard = Scoreboard()
#create two arrays for multiple gold object occurances
#two arrays are used for better distribution on screen
gold1 = []
numberofGold = 16
for i in range(numberofgolds):
oneGold = golds(screen,"gold1.png")
golds1.append(onegold)
for gold in golds1:
gold.rect.centerx = random.randrange(20,620)
gold.rect.centery = random.randrange(20,240)
gold.rect.inflate_ip(-5, -5)
gold2 = []
for i in range(numberofgolds):
onegold = golds(screen,"gold1.png")
golds2.append(onegold)
for gold in golds2:
gold.rect.centerx = random.randrange(20,620)
gold.rect.centery = random.randrange(250,460)
gold.rect.inflate_ip(-5, -5)
totalgolds = ((len(golds1)-1)+(len(golds2)-1))
#initialize gold sprites
goldSprites = pygame.sprite.Group(golds1,
#initialize pirate sprites & instances
pirate1 = pirate1(screen,13)
pirate2 = pirate2(screen,13)
pirate3 = pirate1(screen,11)
pirate4 = pirate2(screen,11)
pirate5 = pirate1(screen,13)
pirateSprites = pygame.sprite.Group(pirate1, pirate2, pirate3, pirate4, pirate5)
#use ordered updates to keep clean appearance
allSprites = pygame.sprite.OrderedUpdates(goldSprites, thief, pirateSprites, scoreboard)
#set up clock & loop
clock = pygame.time.Clock()
keepGoing = True
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
thief.moveUp()
elif event.key == pygame.K_DOWN:
thief.moveDown()
elif event.key == pygame.K_LEFT:
thief.moveLeft()
elif event.key == pygame.K_RIGHT:
thief.moveRight()
elif event.key == pygame.K_ESCAPE:
keepGoing = False
#check collisions here
hitpirates = pygame.sprite.spritecollide(thief, pirateSprites, False)
hitgold = pygame.sprite.spritecollide(thief, goldSprites, True)
if hitpirates:
thief.hit.play()
scoreboard.lives += 1
if scoreboard.lives >= 100:
keepGoing = False
number = 0
if hitgolds:
thief.collectcoin.play()
scoreboard.score += 1
totalgolds -= 1
if totalgolds <= 0:
keepGoing = False
number = 1
#draw sprites
allSprites.clear(screen, background)
allSprites.update()
allSprites.draw(screen)
pygame.display.flip()
return scoreboard.score
return scoreboard.number
def instructions(score, number):
pygame.display.set_caption("Hunt for Gold!")
background = pygame.Surface(screen.get_size())
background = pygame.image.load("sand.jpg")
background = pygame.transform.scale(background, screen.get_size())
screen.blit(background, (0, 0))
if number == 0:
message = "Sorry try again..."
elif number == 1:
message = "The theif escapes!"
else:
message = "Onto the hunt for gold!"
insFont = pygame.font.SysFont("Calibri", 25)
insLabels = []
instructions = (
"Last score: %d" % score ,
"%s" % message,
"",
"GOLD!",
"Get all the gold before you are "
"obliterated!",
"Use arrow keys to move the thief.",
"Space to start, Esc to quit."
)
for line in instructions:
tempLabel = insFont.render(line, 1 , (0,0,0))
insLabels.append(tempLabel)
#set up homescreen loop
keepGoing = True
clock = pygame.time.Clock()
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
donePlaying = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
keepGoing = False
donePlaying = False
if event.key == pygame.K_ESCAPE:
keepGoing = False
donePlaying = True
for i in range(len(insLabels)):
screen.blit(insLabels[i], (50, 30*i))
pygame.display.flip()
return donePlaying
#define main function
def main():
donePlaying = False
score = 0
message = ""
while not donePlaying:
donePlaying = instructions(score, message)
if not donePlaying:
score = game()
else:
pygame.quit()
if __name__ == "__main__":
main()
Glancing at your code, this line:
pirate = Pirate()
Your Pirate class expects self, screen, dx. You only implicitly provide self.
I can only guess at what you want, especially since I don't know off the bat what dx is supposed to mean in respect to your game, but this will probably at least avoid the error:
pirate = Pirate(pygame.display.get_surface(), 60)
Related
Cannot see bullets when game is running
Hello, so I can only see the bullet when i'm closing my game's window, but I do not see the mistake. import pygame, math, random, os pygame.init() clock = pygame.time.Clock() width = 800 height = 608 screen = pygame.display.set_mode((width, height)) running = True gameover = False levelferdig = False levelnr = 0 ferdig = False jump = False levels =[[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,8,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [1,0,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,7,0,0,0], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0], [1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]], [[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0], [9,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1], [0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1], [0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1], [0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1], [0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0], [0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0], [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0], [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0], [0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,1,1]]] ghostgruppe = pygame.sprite.Group() tilegruppe = pygame.sprite.Group() utganggruppe = pygame.sprite.Group() backgroundgruppe_1 = pygame.sprite.Group() backgroundgruppe_2 = pygame.sprite.Group() moving_sprites = pygame.sprite.Group() spillergruppe = pygame.sprite.Group() bullet_img = pygame.transform.scale(pygame.image.load(os.path.join('Bullets', 'bullet.png.png')), (10,10)) background_image_2 = pygame.image.load('skog.png').convert() background_image_1 = pygame.image.load("beach.png").convert() pygame.display.set_caption('pygame') #setter navnet på spillet når du åpner spillet icon = pygame.image.load('menneske.png') pygame.display.set_icon(icon) font = pygame.font.Font('freesansbold.ttf', 72 ) #font som skal brukes gameovertekst = font.render('Game over', True, (255,0,0)) #farge og tekst gameover gameoverrect = gameovertekst.get_rect() gameoverrect.center = (width/2, height/2) font = pygame.font.Font('freesansbold.ttf', 72 ) #font som skal brukes levelferdigtekst = font.render('Ferdig', True, (0,255,0)) #farge og tekst gameover levelferdigrect = levelferdigtekst.get_rect() levelferdigrect.center = (width/2, height/2) ferdigtekst = font.render('Victory', True, (0,0,255)) ferdigrect = levelferdigtekst.get_rect() ferdigrect.center = (width/2, height/2) class Spiller(pygame.sprite.Sprite): def __init__(self,x,y): super().__init__() self.spiller_animation = False self.sprites = [] self.sprites.append(pygame.image.load('spiller.rett(1).png')) self.sprites.append(pygame.image.load('spiller.høyre(1).png')) self.sprites.append(pygame.image.load('spiller.venstre(1).png')) self.sprites.append(pygame.image.load('spiller.hopp(1).png')) self.current_sprite = 0 self.image = self.sprites[self.current_sprite] self.rect = self.image.get_rect() self.rect.topleft =[x,y] self.bullets = [] #list self.x = x self.y = y self.stepIndex = 0 self.face_right = True self.face_left = False self.fy = 10 self.fx = 10 self.jump = False def direction(self): if self.face_right: return 1 if self.face_left: return -1 def animation(self): self.spiller_animation = True def skytt(self): if trykketliste[pygame.K_RIGHT] and not gameover: bullet = Bullet(self.x, self.y, self.direction()) self.bullets.append(bullet) for bullet in self.bullets: bullet.move() def reset(self): self.fartx = 0 self.farty = 0 def update(self,speed): if self.spiller_animation == True: self.current_sprite += speed if int(self.current_sprite) >= len(self.sprites): self.current_sprite = 0 self.is_animating = False self.image = self.sprites[int(self.current_sprite)] self.rect.x += self.fartx tiletreffliste = pygame.sprite.spritecollide(self,tilegruppe, False) if tiletreffliste: if self.fartx > 0: self.rect.right = tiletreffliste[0].rect.left else: self.rect.left = tiletreffliste[0].rect.right self.rect.y += self.farty tiletreffliste = pygame.sprite.spritecollide(self, tilegruppe, False) if tiletreffliste: if self.farty > 0: self.rect.bottom = tiletreffliste[0].rect.top else: self.rect.top = tiletreffliste[0].rect.bottom utgangtreffliste = pygame.sprite.spritecollide(self, utganggruppe, False) if utgangtreffliste: global levelferdig levelferdig = True global levelnr levelnr += 1 restart() class Bullet: def __init__(self,x,y, direction): super().__init__() self.x = x + 15 self.y = y + 25 self.direction = direction def draw_bullet(self): screen.blit(bullet_img, (self.x, self.y)) def move(self): if self.direction == 1: self.x += 15 if self.direction == -1: self.x -= 15 class Ghost(pygame.sprite.Sprite): def __init__(self, x, y, fx,fy): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load('ghost.png').convert_alpha() self.rect = self.image.get_rect() #self rect rektangler, fin rektangel bilde som passer self.rect.x = x self.rect.y = y self.fartx = fx self.farty = fy def flytt(self): self.rect.x = self.rect.x + self.fartx self.rect.y = self.rect.y + self.farty def update(self): # Flytter høyre/venstre og sjekker kollisjon self.rect.x += self.fartx tiletreffliste = pygame.sprite.spritecollide(self,tilegruppe, False) if tiletreffliste: if self.fartx > 0: self.rect.right = tiletreffliste[0].rect.left else: self.rect.left = tiletreffliste[0].rect.right self.fartx *= -1 self.rect.y += self.farty tiletreffliste = pygame.sprite.spritecollide(self, spillergruppe, False) if tiletreffliste: if self.farty > 0: self.rect.bottom = tiletreffliste[0].rect.top else: self.rect.top = tiletreffliste[0].rect.bottom self.farty *= -1 def treffTile(self): if self.rect.x > width or self.rect.x < 0: self.fartx = self.fartx * -1 if self.rect.y > height or self.rect.y < 0: self.farty = self.farty * -1 class Tile(pygame.sprite.Sprite): def __init__(self,x,y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load('sand.png').convert_alpha() self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y class Utgang(pygame.sprite.Sprite): def __init__(self,x,y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load('dør.png') self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y def restart(): global gameover global levelferdig gameover = False levelferdig = False for tile in tilegruppe: tile.kill() for utgang in utganggruppe: utgang.kill() for ghost in ghostgruppe: ghost.kill() spiller.reset() for i in range(5): #hvor mange ghosts skal vi ha ghost = Ghost(random.randint(0,width),random.randint(0, height), random.randint(1,8),random.randint(1,8)) ghostgruppe.add(ghost) if levelnr < len(levels): for y,rad in enumerate(levels[levelnr]): for x,verdi in enumerate(rad): if verdi == 1: tile = Tile(x*32,y*32) tilegruppe.add(tile) if verdi == 9: utgang = Utgang(x*32, y*32) utganggruppe.add(utgang) if verdi == 8: spiller.rect.x = x*32 spiller.rect.y = y*32 else: global ferdig ferdig = True #skytt spiller = Spiller(100, 100) moving_sprites.add(spiller) restart() while running: pygame.display.bullet() spiller.farty = 0 spiller.fartx = 0 trykketliste = pygame.key.get_pressed() spiller.skytt() background_image_1 = pygame.image.load("beach.png").convert() screen.blit(background_image_1, [0,0]) if trykketliste[pygame.K_RIGHT] and not gameover: spiller.farty = -1 spiller.sprites.append(pygame.image.load('spiller.venstre(1).png')) spiller.animation() spiller.skytt() if trykketliste[pygame.K_LEFT] and not gameover: spiller.farty = 1 spiller.sprites.append(pygame.image.load('spiller.høyre(1).png')) spiller.animation() if trykketliste[pygame.K_UP] and not gameover: spiller.fartx = -1 spiller.animation() spiller.sprites.append(pygame.image.load('spiller.hopp(1).png')) if trykketliste[pygame.K_DOWN]and not gameover: spiller.fartx = 1 spiller.animation() spiller.sprites.append(pygame.image.load('spiller.rett(1).png')) if jump is False and trykketliste[pygame.K_SPACE] and not gameover: jump = True spiller.animation() spiller.sprites.append(pygame.image.load('spiller.hopp(1).png')) if jump is True: spiller.rect.y -= spiller.farty *4 spiller.farty -= 1 if spiller.farty < -10: jump = False spiller.farty = 10 if levelnr == 1: background_image_1 = pygame.image.load("skog.png").convert() screen.blit(background_image_2, [0,0]) spillertruffet = pygame.sprite.groupcollide(spillergruppe, ghostgruppe, False, False, pygame.sprite.collide_mask) if spillertruffet: gameover = True ghosttruffet = pygame.sprite.groupcollide(ghostgruppe, spillergruppe, True, True, pygame.sprite.collide_mask) if ghosttruffet: spiller.kill() #Gruppene oppdateres ghostgruppe.update() tilegruppe.update() utganggruppe.update() spillergruppe.update() moving_sprites.draw(screen) moving_sprites.update(0.25) #gruppene vises på skjermen. ghostgruppe.draw(screen) tilegruppe.draw(screen) utganggruppe.draw(screen) spillergruppe.draw(screen) if gameover: screen.blit(gameovertekst,gameoverrect) if levelferdig: screen.blit(levelferdigtekst, levelferdigrect) spillergruppe.draw(screen) clock.tick(60) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.K_n: levelnr = O restart() for bullet in spiller.bullets: bullet.draw_bullet() pygame.time.delay(30) pygame.display.flip() pygame.quit()
You have to draw the bullets after drawing the background. Use a loop to iterate through the list of bullets and call the draw_bullet method for each bullet: while running: # pygame.display.bullet() <--- DELETE spiller.farty = 0 spiller.fartx = 0 trykketliste = pygame.key.get_pressed() spiller.skytt() background_image_1 = pygame.image.load("beach.png").convert() screen.blit(background_image_1, [0,0]) # INSERT for bullet in spiller.bullets: bullet.draw_bullet() # [...] pygame.display.update() # [...] screen.blit(background_image_1, [0,0]) draws the background and hides anything previously drawn. pygame.display.update() updates the display and makes everything that is drawn visible. Therefor you need to draw all the objects of the scene after screen.blit(background_image_1, [0,0]) and before pygame.display.update().
I am having trouble with my stat function in my player class
When I shoot at my cement block sprites I have it set so that self.score is self.score += 1 in my player collision function, but when I shoot my cement blocks and destroy them, either 1 or 2 points is added at random to my score. Why? How can I fix this? A clear example is, I shoot at and destroy 2 cement blocks in a row and 1 point is added for each one destroyed which means my score is 2, which is what I want cause I want to add 1 point to my score whenever I destroy a cement block, but then when I shoot and destroy the third cement block, 2 points are added instead of 1 bringing my score to 4 instead of being a score of 3 points. Github: https://github.com/Enoc-Mena99/AutoPilot My code: import random import pygame import pygame.freetype pygame.init() #screen settings WIDTH = 1000 HEIGHT = 400 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("AutoPilot") screen.fill((255, 255, 255)) #fps FPS = 120 clock = pygame.time.Clock() #load images bg = pygame.image.load('background/street.png').convert_alpha() # background bullets = pygame.image.load('car/bullet.png').convert_alpha() debris_img = pygame.image.load('debris/cement.png') #define game variables shoot = False #player class class Player(pygame.sprite.Sprite): def __init__(self, scale, speed): pygame.sprite.Sprite.__init__(self) self.bullet = pygame.image.load('car/bullet.png').convert_alpha() self.bullet_list = [] self.speed = speed #self.x = x #self.y = y self.moving = True self.frame = 0 self.flip = False self.direction = 0 self.score = 0 #load car self.images = [] img = pygame.image.load('car/car.png').convert_alpha() img = pygame.transform.scale(img, (int(img.get_width()) * scale, (int(img.get_height()) * scale))) self.images.append(img) self.image = self.images[0] self.rect = self.image.get_rect() self.update_time = pygame.time.get_ticks() self.movingLeft = False self.movingRight = False self.rect.x = 465 self.rect.y = 325 #draw car to screen def draw(self): screen.blit(self.image, (self.rect.centerx, self.rect.centery)) #move car def move(self): #reset the movement variables dx = 0 dy = 0 #moving variables if self.movingLeft and self.rect.x > 33: dx -= self.speed self.flip = True self.direction = -1 if self.movingRight and self.rect.x < 900: dx += self.speed self.flip = False self.direction = 1 #update rectangle position self.rect.x += dx self.rect.y += dy #shoot def shoot(self): bullet = Bullet(self.rect.centerx + 18, self.rect.y + 30, self.direction) bullet_group.add(bullet) #check collision def collision(self, debris_group): for debris in debris_group: if pygame.sprite.spritecollide(debris, bullet_group, True): debris.health -= 1 if debris.health <= 0: self.score += 1 #player stats def stats(self): myfont = pygame.font.SysFont('comicsans', 30) scoretext = myfont.render("Score: " + str(self.score), 1, (0,0,0)) screen.blit(scoretext, (100,10)) #bullet class class Bullet(pygame.sprite.Sprite): def __init__(self, x, y, direction): pygame.sprite.Sprite.__init__(self) self.speed = 5 self.image = bullets self.rect = self.image.get_rect() self.rect.center = (x,y) self.direction = direction def update(self): self.rect.centery -= self.speed #check if bullet has gone off screen if self.rect.centery < 1: self.kill() #debris class class Debris(pygame.sprite.Sprite): def __init__(self,scale,speed): pygame.sprite.Sprite.__init__(self) self.scale = scale self.x = random.randrange(100,800) self.speed_y = 10 self.y = 15 self.speed = speed self.vy = 0 self.on_ground = True self.move = True self.health = 4 self.max_health = self.health self.alive = True self.velocity = random.randrange(1,2) self.speed_x = random.randrange(-3,3) self.moving_down = True self.is_destroyed = False #load debris self.image = debris_img self.rect = self.image.get_rect() self.rect.x = random.randrange(100, 800) self.rect.y = random.randrange(-150, -100) self.rect.center = (self.x,self.y) #load explosion self.img_explosion_00 = pygame.image.load('explosion/0.png').convert_alpha() self.img_explosion_00 = pygame.transform.scale(self.img_explosion_00, (self.img_explosion_00.get_width() * 2, self.img_explosion_00.get_height() * 2)) self.img_explosion_01 = pygame.image.load('explosion/1.png').convert_alpha() self.img_explosion_01 = pygame.transform.scale(self.img_explosion_01, (self.img_explosion_01.get_width() * 2, self.img_explosion_01.get_height() * 2)) self.img_explosion_02 = pygame.image.load('explosion/2.png').convert_alpha() self.img_explosion_02 = pygame.transform.scale(self.img_explosion_02, (self.img_explosion_02.get_width() * 2, self.img_explosion_02.get_height() * 2)) self.img_explosion_03 = pygame.image.load('explosion/3.png').convert_alpha() self.img_explosion_03 = pygame.transform.scale(self.img_explosion_03, (self.img_explosion_03.get_width() * 2, self.img_explosion_03.get_height() * 2)) #explosion list self.anim_explosion = [self.img_explosion_00, self.img_explosion_01, self.img_explosion_02, self.img_explosion_03] self.anim_index = 0 self.frame_len = 10 #spawn new debris def spawn_new_debris(self): self.rect.x = random.randrange(100, 800) self.rect.y = random.randrange(-150, -100) self.velocity = random.randrange(1, 2) self.speed_x = random.randrange(-3, 3) #respawn debris when they go of the screen def boundaries(self): if self.rect.left > WIDTH + 10 or self.rect.right < -10 or self.rect.top > HEIGHT + 10: self.spawn_new_debris() #update image def update(self): self.rect.y += self.velocity self.rect.x += self.speed_x self.boundaries() if self.health <= 0: max_index = len(self.anim_explosion) - 1 if self.anim_index > max_index: self.kill() else: if self.frame_len == 0: self.image = self.anim_explosion[self.anim_index] self.anim_index += 1 self.frame_len = 10 else: self.frame_len -= 1 #make debris fall down def falldown(self): self.rect.centery += self.velocity if self.moving_down and self.rect.y > 350: self.kill() ######################CAR/DEBRIS########################## player = Player(1,5) ########################################################## #groups bullet_group = pygame.sprite.Group() debris_group = pygame.sprite.Group() all_sprites = pygame.sprite.Group() for x in range(50): d = Debris(1, 5) debris_group.add(d) all_sprites.add(d) #game runs here run = True while run: #draw street screen.blit(bg, [0, 0]) #update groups bullet_group.update() bullet_group.draw(screen) debris_group.update() debris_group.draw(screen) #draw car player.draw() player.move() player.collision(debris_group) player.stats() #update all sprites all_sprites.update() all_sprites.draw(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False #check if key is down if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: run = False if event.key == pygame.K_a: player.movingLeft = True if event.key == pygame.K_d: player.movingRight = True if event.key == pygame.K_SPACE: player.shoot() shoot = True #check if key is up if event.type == pygame.KEYUP: if event.key == pygame.K_a: player.movingLeft = False if event.key == pygame.K_d: player.movingRight = False #update the display pygame.display.update() pygame.display.flip() clock.tick(FPS) pygame.quit()
Do not count debris objects with healt <= 0: class Player(pygame.sprite.Sprite): # [...] def collision(self, debris_group): for debris in debris_group: # if health > 0 and collision: if debris.health > 0 and pygame.sprite.spritecollide(debris, bullet_group, True): debris.health -= 1 if debris.health <= 0: self.score += 1
How can I go back and forth between modules in pygame?
I'm trying to make a Home Screen for two games in pygame, I changed the first game's name to module1 in the code Im providing and the Home Screen to Mainscreen module1 is already done and now I'm just trying to get the Main Menu script to import the maingame when I click on the play button that I already have on the screen display, then when I finish the game (health reaches 0) , if I want to go back to the Main Menu I should just click anywhere on the "game over" screen that should appear when health reaches 0 or press escape. here is what I tried: this is the whole game script, the game loop is at the end of the script and sorry for how messy it is: # Pygame skeleton import pygame import math import random import sys import os pygame.init() pygame.mixer.init() vec = pygame.math.Vector2 # Constants WIDTH = 1306 HEIGHT = 526 FPS_INGAME = 60 FPS_HOMESCREEN = 30 FULL_SCREEN = (0,0) bullet_img = pygame.image.load('Bullet.png') jump = False bullet_timer = 0 score = 0 moving_left = False moving_right = False shoot = False acceleration = 0.7 friction = -0.1 gravity = 9.8 platform_color = (150,59,230) # Classes and Sprites class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.shoot_cooldown = 0 self.anime = [] self.frame_index = 0 self.update_time = pygame.time.get_ticks() self.action = 0 animation_types = ["Shoot","Go"] for animation in animation_types: temp_list = [] num_of_frames = len(os.listdir(f'MySprite/{animation}')) for i in range(1,num_of_frames): img = pygame.image.load(f'MySprite/{animation}/{i}.png') temp_list.append(img) self.anime.append(temp_list) self.direction = 1 self.flip = False self.image = self.anime[self.action][self.frame_index] self.rect = self.image.get_rect() # vectors and sprite constants self.health = 100 self.pos = vec(WIDTH/2, HEIGHT/2) self.vel_vec = vec(0,0) self.acc_vec = vec(0,0) def jump(self): self.rect.y += 1 hits = pygame.sprite.spritecollide(player_group.sprite, platform_group,False) self.rect.y -= -1 if hits: self.vel_vec.y = -15 def screen_edge(self): if self.pos.x > WIDTH: self.pos.x = 0 if self.pos.x < 0: self.pos.x = WIDTH def get_damage(self,damage_mag): self.health -= damage_mag def update(self): animation_cooldown = 75 self.image = self.anime[self.action][self.frame_index] if pygame.time.get_ticks() - self.update_time >= animation_cooldown: self.update_time = pygame.time.get_ticks() self.frame_index += 1 if self.frame_index >= len(self.anime[self.action]): self.frame_index = 0 if self.shoot_cooldown > 0: self.shoot_cooldown -= 1 def update_action(self,new_action): if new_action != self.action: self.action = new_action self.frame_index = 0 self.update_time = pygame.time.get_ticks() def move(self,moving_left,moving_right): self.acc_vec = vec(0,acceleration) if moving_left: self.acc_vec.x = -(acceleration) self.direction = 1 self.flip = False if moving_right: self.acc_vec.x = acceleration self.direction = -1 self.flip = True self.acc_vec.x += self.vel_vec.x * friction self.vel_vec += self.acc_vec self.pos += self.vel_vec + 0.5 * self.acc_vec self.rect.midbottom = self.pos hits = pygame.sprite.spritecollide(player_group.sprite, platform_group,False) if hits: self.pos.y = hits[0].rect.top self.vel_vec.y = 0 def draw(self): screen.blit(pygame.transform.flip(self.image,self.flip,False),self.rect) class Platform(pygame.sprite.Sprite): def __init__(self,x,y,w,h): super().__init__() self.image = pygame.Surface((w,h)) self.image.fill(platform_color) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y class Hostiles(pygame.sprite.Sprite): def __init__(self,x_pos,y_pos,speed): super(Hostiles,self).__init__() self.images = [] self.images.append(pygame.image.load('MySprite/images/go_1.png')) self.images.append(pygame.image.load('MySprite/images/go_2.png')) self.images.append(pygame.image.load('MySprite/images/go_3.png')) self.images.append(pygame.image.load('MySprite/images/go_4.png')) self.images.append(pygame.image.load('MySprite/images/go_5.png')) self.images.append(pygame.image.load('MySprite/images/go_6.png')) self.images.append(pygame.image.load('MySprite/images/go_7.png')) self.images.append(pygame.image.load('MySprite/images/go_8.png')) self.images.append(pygame.image.load('MySprite/images/go_9.png')) self.images.append(pygame.image.load('MySprite/images/go_10.png')) self.index = 0 self.image = self.images[self.index] self.rect = self.image.get_rect(center = (x_pos,y_pos)) self.speed = speed def update(self): self.index += 1 if self.index >= len(self.images): self.index = 0 self.image = self.images[self.index] self.rect.centerx += self.speed if self.rect.centerx >= 1350 or self.rect.centerx <= -50: self.kill() class Hostiles2(pygame.sprite.Sprite): def __init__(self,x_pos,y_pos,speed): super(Hostiles2,self).__init__() self.images2 = [] self.images2.append(pygame.image.load('MySprite/images2/go_1.png')) self.images2.append(pygame.image.load('MySprite/images2/go_2.png')) self.images2.append(pygame.image.load('MySprite/images2/go_3.png')) self.images2.append(pygame.image.load('MySprite/images2/go_4.png')) self.images2.append(pygame.image.load('MySprite/images2/go_5.png')) self.images2.append(pygame.image.load('MySprite/images2/go_6.png')) self.images2.append(pygame.image.load('MySprite/images2/go_7.png')) self.images2.append(pygame.image.load('MySprite/images2/go_8.png')) self.images2.append(pygame.image.load('MySprite/images2/go_9.png')) self.images2.append(pygame.image.load('MySprite/images2/go_10.png')) self.index = 0 self.image = self.images2[self.index] self.rect = self.image.get_rect(center = (x_pos,y_pos)) self.speed = speed def update(self): self.index += 1 if self.index >= len(self.images2): self.index = 0 self.image = self.images2[self.index] self.rect.centerx += self.speed if self.rect.centerx >= 1350 or self.rect.centerx <= -50: self.kill() class Bullets(pygame.sprite.Sprite): def __init__(self,x,y,direction): super().__init__() self.speed = 10 self.image = bullet_img self.rect = self.image.get_rect(center = (x,y)) self.direction = direction def update(self): self.rect.x -= (self.direction * self.speed) if self.rect.left >= WIDTH or self.rect.right <= 0: self.kill() screen.blit(self.image,self.rect) # Functions def make_text(font_type,font_size,text,color,position): font = pygame.font.Font(font_type, font_size) title = font.render(text,True,(color)) title_rect = title.get_rect(center = (position)) screen.blit(title,title_rect) def main_game(): pygame.draw.rect(screen,(255,0,0),(22,20,200,10)) pygame.draw.rect(screen,platform_color,(22,20,2 * player_group.sprite.health,10)) screen.blit(heart,(0,2)) bullet_group.draw(screen) player.draw() hostiles_group.draw(screen) platform_group.draw(screen) bullet_group.update() player_group.update() hostiles_group.update() player_group.update() player.screen_edge() if shoot: if player.shoot_cooldown == 0: bullet = Bullets(player.rect.centerx - (0.6 * player.direction * player.rect.size[0]),player.rect.centery,player.direction) bullet_group.add(bullet) player.shoot_cooldown = 40 if moving_left or moving_right: player.update_action(1) else: player.update_action(0) player.move(moving_left,moving_right) if pygame.sprite.spritecollide(player_group.sprite,hostiles_group,True): player_group.sprite.get_damage(10) pygame.sprite.groupcollide(hostiles_group, bullet_group,True,True) return 2 def game_over(): screen.fill((0,0,0)) text = gamefont.render("GAME OVER",True,(255,255,255)) text_rect = text.get_rect(center = (653,243)) screen.blit(text,text_rect) scoresurface = gamefont.render(f"Score: {score}",True,(255,255,255)) score_rect = scoresurface.get_rect(center = (653,283)) screen.blit(scoresurface,score_rect) # Creating window screen = pygame.display.set_mode((WIDTH,HEIGHT)) pygame.display.set_caption("game name") clock = pygame.time.Clock() # Groups and objects gamefont = pygame.font.Font('Chernobyl.ttf',40) player = Player() platform = Platform(0,HEIGHT-96,WIDTH,100) platform_group = pygame.sprite.GroupSingle() platform_group.add(platform) player_group = pygame.sprite.GroupSingle() player_group.add(player) hostiles_group = pygame.sprite.Group() hostile_event = pygame.USEREVENT pygame.time.set_timer(hostile_event,300) bullet_group = pygame.sprite.Group() pygame.mouse.set_visible(True) sky = pygame.image.load('SkyNight.png') wallpaper = pygame.image.load('GamePlatform.png') heart = pygame.image.load('Heart.png') # Game loop running = True while running: # Events (Inputs) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == hostile_event: random_xpos = [-40,-20] random_xpos2 = [1340,1360] random_hs = [-2,2] hostile_left = Hostiles2(random.choice(random_xpos),400,random.choice(random_hs)) hostile_right = Hostiles(random.choice(random_xpos2),400,random.choice(random_hs)) hostiles_group.add(hostile_left,hostile_right) if event.type == pygame.MOUSEBUTTONDOWN and player_group.sprite.health <= 0: player_group.sprite.health = 100 hostiles_group.empty() score = 0 import MainMenu if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: moving_left = True if event.key == pygame.K_RIGHT: moving_right = True if event.key == pygame.K_q: shoot = True if event.key == pygame.K_ESCAPE: running = False if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT: moving_left = False if event.key == pygame.K_RIGHT: moving_right = False if event.key == pygame.K_q: shoot = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: player_group.sprite.jump() if player_group.sprite.health > 0: score += main_game() print (score) else: game_over() pygame.display.update() screen.blit(sky,FULL_SCREEN) screen.blit(wallpaper,FULL_SCREEN) programIcon = pygame.image.load('icon.png') pygame.display.set_icon(programIcon) clock.tick(FPS_INGAME) and this is all the main screen / main menu .py file: import pygame,sys pygame.init() screen = pygame.display.set_mode((1306,526)) clock = pygame.time.Clock() pygame.mouse.set_visible(True) screen_home = pygame.image.load('HomeScreen.png') def make_text(font_type,font_size,text,color,position): font = pygame.font.Font(font_type, font_size) title = font.render(text,True,(color)) title_rect = title.get_rect(center = (position)) screen.blit(title,title_rect) while True: font1 = pygame.font.Font('Starjedi.ttf',60) game1 = font1.render("Play",True,(255,255,255)) game1_rect = game1.get_rect(center = (640,300)) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.MOUSEBUTTONDOWN: if game1_rect.collidepoint(event.pos): import MainGame.py screen.blit(screen_home,(0,0)) screen.blit(game1,game1_rect) make_text('Chernobyl.ttf',70,"Title Here",(255,255,255),(315,80)) pygame.display.update() clock.tick(45) when I run the main menu I get the Home Screen I made, then I click on the on my display screen and it imports the game script and the game starts, when my health reaches 0 and I click on the screen to quit the game loop, it takes me back to the main menu which is exactly what I wanted,however, when I press play again to go back to the game it doesn't work it gives me an error: ModuleNotFoundError: No module named 'MainGame.py'; 'MainGame' is not a package I know the code is a mess I'm still new at this I'm sorry if my question wasn't clear enough, any help would be appreciated!
Ok, now that I see your code I can see you have a big problem using import: You use it like this: import MainGame.py Assume the file you created is MainGame.py you supposed to import it this way: import MainGame Same goes to import MainMenu.py And that's might be the problem, though if you still have an issue, so instead of: in the game, this is part of the main game loop: Please copy all of the code, in both files, and write the name of each file next to the code.
Collision detection not working in pygame
I am making a game at the moment and I am experiencing problems with collision detection. I am making an end of level block but it can not detect if the player is standing on it to change to level 2. The collision detection for the block is found in player.updater(). As well as this the block is a class and in a group called endPlatform to allow the collision detection to work. The game runs perfectly fine however it can not detect when the Player hits Endplatform. I get no errors which show up. EndPlatform: class EndPlatform(pygame.sprite.Sprite): def __init__(self, display): super().__init__() self.image = pygame.image.load("endPlatform.png") self.rect = self.image.get_rect() display.blit(self.image, self.rect) Player: class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() # Is it touching the floor? self.standing = True # Rendering image and creating some variables self.image = pygame.image.load("Slime.png") self.sprite_x_change = 0 self.sprite_y_change = 0 self.rect = self.image.get_rect() self.rect.y = 460 self.rect.x = 120 # Mobility: Left, right, up and stop def move_right(self): self.sprite_x_change = 8 def move_left(self): self.sprite_x_change = -8 def move_up(self, platform): if self.standing == True: self.sprite_y_change = -25 self.standing = False def stop(self): self.sprite_x_change = 0 def sprint(self): self.sprite_x_change += 10 def updater(self, platforms, powerups, score, endPlatform): self.gravity() self.rect.x += self.sprite_x_change self.standing = False platforms_hit = pygame.sprite.spritecollide(self, platforms, False) for blocks in platforms_hit: if self.sprite_x_change > 0: self.rect.right = blocks.rect.left elif self.sprite_x_change < 0: self.rect.left = blocks.rect.right self.rect.y += self.sprite_y_change platforms_hit = pygame.sprite.spritecollide(self, platforms, False) for blocks in platforms_hit: # Going down if self.sprite_y_change > 0: self.rect.bottom = blocks.rect.top - 1 self.standing = True # Going up elif self.sprite_y_change < 0: self.rect.top = blocks.rect.bottom self.standing = False self.sprite_y_change = 0 coins_hit = pygame.sprite.spritecollide(self, powerups, True) if len(coins_hit) > 0: score.add() endLevel = pygame.sprite.spritecollide(self, endPlatform, True) if len(endLevel) > 0: score.add() All the code: import pygame import random pygame.font.init() # Colours + Global constants WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) BLACK = (0, 0, 0) RANDOM = (12, 211, 123) WIDTH = 800 HEIGHT = 600 SIZE = (WIDTH, HEIGHT) AGENT = pygame.font.SysFont("Agent Orange", 30) # CLASSES # Block is the common platform class EndPlatform(pygame.sprite.Sprite): def __init__(self, display): super().__init__() self.image = pygame.image.load("endPlatform.png") self.rect = self.image.get_rect() display.blit(self.image, self.rect) class Coins(pygame.sprite.Sprite): def __init__(self, display): super().__init__() self.image = pygame.image.load("hud_coins.png") self.rect = self.image.get_rect() display.blit(self.image, self.rect) class Score: def __init__(self): self.score = 0 def msgs(self, msg, colour, display): screen_text = AGENT.render(msg, True, colour) display.blit(screen_text, [0, 0]) def add(self): self.score += 1 class Monster(pygame.sprite.Sprite): def __init__(self, length, height, colour): super().__init__() self.image = pygame.Surface([length, height]) self.image.fill(colour) self.rect = self.image.get_rect() # Setting Y coordinates self.rect.y = HEIGHT - 80 def jump(self): self.rect.y = -10 class Block(pygame.sprite.Sprite): def __init__(self, length, height, colour): super().__init__() # Making image self.image = pygame.Surface([length, height]) self.image.fill(colour) self.rect = self.image.get_rect() # Setting Y coordinates self.rect.y = 468 class Platform(pygame.sprite.Sprite): def __init__(self, display, x_screen, y_screen, x_sheet, y_sheet, height, length): super().__init__() self.tiles = pygame.image.load("tiles_spritesheet.png") self.image = self.tiles.subsurface(pygame.Rect(x_sheet, y_sheet, height, length)) self.rect = self.image.get_rect(x=x_screen, y=y_screen) class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() # Is it touching the floor? self.standing = True # Rendering image and creating some variables self.image = pygame.image.load("Slime.png") self.sprite_x_change = 0 self.sprite_y_change = 0 self.rect = self.image.get_rect() self.rect.y = 460 self.rect.x = 120 # Mobility: Left, right, up and stop def move_right(self): self.sprite_x_change = 8 def move_left(self): self.sprite_x_change = -8 def move_up(self, platform): if self.standing == True: self.sprite_y_change = -25 self.standing = False def stop(self): self.sprite_x_change = 0 def sprint(self): self.sprite_x_change += 10 def updater(self, platforms, powerups, score, endPlatform): self.gravity() self.rect.x += self.sprite_x_change self.standing = False platforms_hit = pygame.sprite.spritecollide(self, platforms, False) for blocks in platforms_hit: if self.sprite_x_change > 0: self.rect.right = blocks.rect.left elif self.sprite_x_change < 0: self.rect.left = blocks.rect.right self.rect.y += self.sprite_y_change platforms_hit = pygame.sprite.spritecollide(self, platforms, False) for blocks in platforms_hit: # Going down if self.sprite_y_change > 0: self.rect.bottom = blocks.rect.top - 1 self.standing = True # Going up elif self.sprite_y_change < 0: self.rect.top = blocks.rect.bottom self.standing = False self.sprite_y_change = 0 coins_hit = pygame.sprite.spritecollide(self, powerups, True) if len(coins_hit) > 0: score.add() endLevel = pygame.sprite.spritecollide(self, endPlatform, True) if len(endLevel) > 0: score.add() def gravity(self): self.sprite_y_change += 3 class Level: def __init__(self): # Creating groups self.endPlatform = pygame.sprite.Group() self.powerups = pygame.sprite.Group() self.sprites = pygame.sprite.Group() self.all_things = pygame.sprite.Group() self.platforms = pygame.sprite.Group() self.entities = pygame.sprite.Group() self.shift_x = 0 self.shift_y = 0 def updater(self, display, score): self.all_things.draw(display) score.msgs("Score: " + str(score.score), RED, display) def scroll_x(self, shift_x_change): self.shift_x += shift_x_change for platform in self.entities: platform.rect.x += shift_x_change def scroll_y(self, shift_y_change): self.shift_y += shift_y_change for platform in self.entities: platform.rect.y += shift_y_change class Level01(Level): def __init__(self, player1, monster, display): # Initialise level1 super().__init__() # Level01 things block = Block(245, 3, BLACK) Level.all_things = self.all_things self.sprites.add(player1, monster) self.platforms.add(block) self.all_things.add(player1, block, monster) self.entities.add(block) theLevel = [] level = [[600, 400, 648, 0, 70, 70], [740, 320, 648, 0, 70, 70], [380, 400, 648, 0, 70, 70], [900, 280, 648, 0, 70, 70], [1200, 530, 648, 0, 70, 70], [1350, 450, 648, 0, 70, 70], [1500, 550, 648, 0, 70, 70], [1680, 500, 648, 0, 70, 70], ] for platform in theLevel: block = Block(platform[0], platform[1], RED) block.rect.x = platform[2] block.rect.y = platform[3] self.platforms.add(block) self.all_things.add(block) self.entities.add(block) for goodPlatform in level: platform = Platform(display, goodPlatform[0], goodPlatform[1], goodPlatform[2], goodPlatform[3], goodPlatform[4], goodPlatform[5]) self.platforms.add(platform) self.all_things.add(platform) self.entities.add(platform) for n in range(1): coin = Coins(display) coin.rect.x = random.randint(0, WIDTH*3) coin.rect.y = 400 self.all_things.add(coin) self.entities.add(coin) self.powerups.add(coin) platforms_hit = pygame.sprite.spritecollide(coin, self.entities, False) for hit in platforms_hit: coin.rect.x = random.randrange(0, WIDTH*3) finalPlatform = EndPlatform(display) finalPlatform.rect.x = 1900 finalPlatform.rect.y = 420 self.all_things.add(finalPlatform) self.entities.add(finalPlatform) self.platforms.add(finalPlatform) self.endPlatform.add(finalPlatform) class Level02(Level): def __init__(self, player1, monster): super().__init__() # Level01 things block = Block(245, 3, BLACK) Level.all_things = self.all_things self.sprites.add(player1, monster) self.platforms.add(block) self.all_things.add(player1, block, monster) def main(): # Init pygame pygame.init() # Set screen backgrounds = ["background2.jpg", "background.jpg"] background = pygame.image.load(backgrounds[0]) backgroundRect = background.get_rect() display = pygame.display.set_mode(background.get_size()) # Creating FPS thingy clock = pygame.time.Clock() # Making levels + Player score = Score() monster = Monster(30, 30, RANDOM) player = Player() level_1 = Level01(player, monster, display) level_2 = Level02(player, monster) # Choosing level levelList = [] levelList.append(level_1) levelList.append(level_2) currentLevelNumber = 0 # Game loop loop = True while loop == True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT: player.move_right() if event.key == pygame.K_LEFT: player.move_left() if event.key == pygame.K_UP: player.move_up(currentLevel.platforms) if event.key == pygame.KMOD_LSHIFT and event.key == pygame.K_RIGHT: player.sprint() if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT and player.sprite_x_change < 0: player.stop() if event.key == pygame.K_RIGHT and player.sprite_x_change > 0: player.stop() if event.key == pygame.KMOD_LSHIFT: player.sprite_x_change -= 10 # Update things #monster.jump() if player.rect.x > 400: player.rect.x = 400 currentLevel.scroll_x(-10) if player.rect.x >= WIDTH: player.rect.x = WIDTH currentLevel.scroll(0) if player.rect.y >= HEIGHT: main() if player.sprite_x_change < 0 and player.rect.x >= 120: currentLevel.scroll_x(0) if player.rect.left <= 120 and player.sprite_x_change < 0: player.rect.x = 120 player.rect.left = 120 currentLevel.scroll_x(10) ''' if player.rect.y <= 300: if player.standing == False and player.sprite_y_change < 0: currentLevel.scroll_y(10) if currentLevel.shift_y > 0: y_speed = -4 if player.standing == True and player.rect.y < 300: y_speed = 4 print(currentLevel.shift_y) currentLevel.scroll_y(y_speed) ''' currentLevel = levelList[currentLevelNumber] if currentLevel.shift_x > 0: currentLevel.scroll_x(currentLevel.shift_x * -1) display.blit(background, backgroundRect) player.updater(currentLevel.platforms, currentLevel.powerups, score, currentLevel.endPlatform) currentLevel.updater(display, score) # Refresh screen clock.tick(30) pygame.display.update() pygame.quit() loop = False if __name__ == "__main__": main()
It seems I found the problem, for some daft reason you can't use collision detection twice on the same object. I used it once so that the player could stand on the block and another time so that you could go on to the next level!
The reason why it doesn't switch to the next level is that you change the position of the rect when it collides with a platform, so the player.rect gets moved out of the blocks.rect and therefore can't collide again when you call spritecollide with the endPlatform group. A quick and dirty fix would be to check in the for blocks in platforms_hit: loops if the block is in the endPlatform group and then return True: for blocks in platforms_hit: if blocks in endPlatform: score.add() return True And then increase the currentLevelNumber in the main function if True is returned: change_level = player.updater(currentLevel.platforms, currentLevel.powerups, score, currentLevel.endPlatform) if change_level: currentLevelNumber += 1
My sprites checker doesn't work
I have created code to see whether my aliens are dead however it doesn't work, can anyone see the problem. CODE: enemies = pygame.sprite.Group(aliens) if len(enemies) <= 0: print("game over") gameover() Complete code: #MathsVaders import pygame, random, time from pygame.locals import * import Databaseconnector import tkMessageBox pygame.init() # set up the graphics window size = [800, 595] screen = pygame.display.set_mode(size, 0) screenrect = screen.get_rect() pygame.display.set_caption("Mathsvaders") # set some variables done = False life = 3 aliens = pygame.sprite.Group() allsprites = pygame.sprite.Group() bombs = pygame.sprite.Group() green = [0, 255, 0] white = [255, 255, 255] # create a timer to control how often the screen updates clock = pygame.time.Clock() fps = 100 # loads images to use in the game which link in with my classes(further down) cannon = pygame.image.load("spaceship.png").convert() cannon.set_colorkey(white) blast = pygame.image.load("blast.png").convert_alpha() boom = pygame.image.load("expl.png").convert_alpha() bomb = pygame.image.load("missile_player.png").convert_alpha() back = pygame.image.load("rsz_space.png").convert() enemy = pygame.image.load("sii.png").convert_alpha() lives2 = pygame.image.load("alien2.png").convert() lives2.set_colorkey(white) lives3 = pygame.image.load("alien3.png").convert() lives3.set_colorkey(white) lives1 = pygame.image.load("alien1.png").convert() lives1.set_colorkey(white) # (Classes) # the explosion class class Explosion(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = boom self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y self.count = 6 def update(self): self.count -= 1 if self.count < 1: self.kill() class scoreClass: def __init__(self): self.value = 0 # set a font, default font size 28 self.font = pygame.font.Font(None, 28) def update(self): text = self.font.render("Score: %s" % self.value, True, (green)) textRect = text.get_rect() textRect.centerx = screenrect.centerx screen.blit(text, textRect) class Msg: def __init__(self, words): # set a font, default font size 28 self.font = pygame.font.Font(None, 28) self.text = self.font.render(words, True, (green)) self.textRect = self.text.get_rect() def update(self): self.textRect.centerx = screenrect.centerx self.textRect.centery = screenrect.centery screen.blit(self.text, self.textRect) # the invader class class Pi(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) aliens.add(self) self.image = enemy self.rect = self.image.get_rect() self.rect.left = x self.rect.top = y self.speed = 1 def update(self): self.rect.right += self.speed if self.rect.right >= (screenrect.right -5): self.speed = -1 self.rect.top += self.rect.height if self.rect.left <= (screenrect.left +5): self.speed = 1 self.rect.top += self.rect.height if self.rect.top > screenrect.bottom: self.kill() i = random.randrange(1000) j = self.rect.centerx if i == 1: laser_bomb = Bomb(j, self.rect.bottom) allsprites.add(laser_bomb) aliens.add(laser_bomb) class Gun(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = cannon self.rect = self.image.get_rect() self.rect.bottom = screenrect.bottom self.rect.centerx = screenrect.centerx self.speed=0 def update(self): self.rect.centerx += self.speed if self.rect.right >= screenrect.right: self.rect.centerx = 0 if self.rect.right <= 0: self.rect.right = screenrect.right # bomb class class Bomb(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = bomb self.rect = self.image.get_rect() self.rect.centerx = x self.rect.centery = y bombs.add(self) def update(self): self.rect.centery +=1 # the laser blast class class Blast(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = blast self.image.set_colorkey(white) self.rect = self.image.get_rect() self.rect.top = (player.rect.top + 5) self.rect.centerx = player.rect.centerx self.speed = 0 def update(self): if self.speed == 0: self.rect.centerx = player.rect.centerx self.rect.top -= self.speed # function to make a sheet of invaders def invade(): for j in range(10, 200, 120): for i in range(10): aliens.add(Pi((i*70)+10, j)) def gameover(): message = Msg("Game Over") message.update() player.kill() shot.kill() SQL = 'INSERT INTO TblScore(Score, StudentID) VALUES (' + str(score.value) + ', ' + str(8) + ')' Databaseconnector.INSERT(SQL) #pygame.quit() ##def gameover(): ## message = Msg("Game Over") ## message.update() ## player.kill() ## shot.kill() ## SQL = 'INSERT INTO TblScore(Score, StudentID) VALUES (' + str(score.value) + ', ' + str(8) + ')' ## Databaseconnector.INSERT(SQL) ## ## #pygame.quit() def gamewon(): # sprites(aliens) == 0 #sprites.aliens == 0 message = Msg("YOU WON, YOUR SCORE WAS " + score + " WELL DONE") message.update aliens.kill() shot.kill() pygame.quit() # pre-game window invade() message = Msg("Press a key to play.") allsprites.add(aliens) key = True while key: screen.blit(back, (0,0)) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() if event.type == pygame.KEYDOWN: for item in (aliens): item.kill() key = False allsprites.update() allsprites.draw(screen) message.update() # set the loop to 40 cycles per second clock.tick(fps) # update the display pygame.display.flip() # Main Game Starts Here score = scoreClass() player = Gun() shot = Blast() invade() allsprites.add(player, aliens, shot) while done==False: screen.blit(back, (0,0)) for event in pygame.event.get(): if event.type == pygame.QUIT: done=True if life <= 0: gamewon() ## elif allsprites == 0: ## gamewon() else: # shoots laser missile if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: if shot.speed == 0: shot.speed = 7 #laser.play() if event.key == pygame.K_LEFT: player.speed = -3 if event.key == pygame.K_RIGHT: player.speed = 3 if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT: player.speed = 0 if event.key == pygame.K_RIGHT: player.speed = 0 hit = pygame.sprite.spritecollide(shot, aliens, 1) if len(hit) > 0: explosion1 = Explosion(shot.rect.centerx, shot.rect.top) score.value += 1500 shot.kill() #explode.play() shot = Blast() allsprites.add(shot, explosion1) hit2 = pygame.sprite.spritecollide(player, aliens, 1) if len(hit2) > 0: life -= 1 #explode.play() explosion2 = Explosion(player.rect.centerx, player.rect.centery) allsprites.add(explosion2) player.kill() shot.kill() if life > 0: ready = Msg("Push Harder !!.") ready.update() allsprites.update() allsprites.draw(screen) score.update() pygame.display.flip() for item in bombs: item.kill() while 1: event = pygame.event.wait() if event.type == pygame.KEYDOWN: break player = Gun() shot = Blast() allsprites.add(player, shot) if shot.rect.top <= screenrect.top: shot.kill() shot = Blast() allsprites.add(shot) if life == 2: men = lives2 if life == 1: men = lives1 if life == 3: men = lives3 if life > 0: screen.blit(men, (0,0)) allsprites.update() allsprites.draw(screen) score.update() # set the loop to "fps" cycles per second clock.tick(fps) # update the display pygame.display.flip() # close pygame pygame.quit()
This is the "pythonic" way since an empty list is False: if not enemies: print("game over") gameover() Where is the part of code that kills your aliens?