Reputation: 109
I'm making a pacman game and I have the basics working at the moment, but I can't get the pac pellets to respawn after they have all been eaten. At the moment I have it set up that after a pac pellet is eaten it is removed from the list of pacpellets. When the list is empty it is refilled and then told to redraw all pac pellets onto the screen. It goes though all the correct functions and everything, I've checked with print statements, but pygame.draw.rect
isn't working and I can't figure out why.
import pygame
import os
import sys
import copy
#intialise the game
pygame.init()
myfont = pygame.font.SysFont("monospace", 15)
screen = pygame.display.set_mode((448, 576))
done = False
score=0
y = 416
x = 232
#sets up clock and loads pacman image
clock = pygame.time.Clock()
PACMANSPRITE = pygame.image.load("pacman.png").convert_alpha()
PACMAN_MAP = pygame.image.load("pacman_map.png").convert_alpha()
#gets pacman intro music, sets music to lower volume then plays it
pygame.mixer.music.load('pacman_beginning.WAV')
pygame.mixer.music.set_volume(0.01)
pygame.mixer.music.play(0)
#box class, used for boxes to border pacmans map
class boxcollisions(pygame.sprite.Sprite):
def __init__(self, x, y):
self.y = y
self.x = x
self.rect = pygame.Rect(self.x, self.y, 12, 12)
self.colour = (0, 128, 255)
def draw(self, screen):
pygame.draw.rect(screen, self.colour, self.rect)
class pointclass(pygame.sprite.Sprite):
def __init__(self, x, y):
self.y = y
self.x = x
self.rect = pygame.Rect(self.x, self.y, 12, 12)
self.colour = (255, 204, 153)
self.score=0
def draw(self, screen):
pygame.draw.rect(screen, self.colour, self.rect)
#pacmans class
class pacman(pygame.sprite.Sprite):
def __init__(self, image, x, y):
self.image = image
self.y=416
self.x=216
self.currentx=self.x
self.currenty=self.y
self.rect = self.image.get_rect()
self.rect.left = self.x
self.rect.top = self.y
self.rect.width=16
self.rect.height=16
# move pacman
def movement(self):
pressed= pygame.key.get_pressed()
if pressed[pygame.K_UP]:
self.y -= 2
if pressed[pygame.K_DOWN]:
self.y += 2
if pressed[pygame.K_LEFT]:
self.x -= 2
if pressed[pygame.K_RIGHT]:
self.x += 2
self.rect.left = self.x
self.rect.top = self.y
def draw(self, surface):
# blit yourself at your current position
surface.blit(self.image, (self.x, self.y))
self.currentx=self.x
self.currenty=self.y
def outofbounds(self):
self.y=self.currenty
self.x=self.currentx
self.rect.left = self.x
self.rect.top = self.y
#spawn pellets function
def spawnpellets(pointspawns):
broken=0
abc=0
efg=0
px=0
py=-16
for row in pointspawns:
#y co ordinate
py=py+16
for n in row:
#x co ordinate
n=n-1
px=n*16
point=(pointclass(px, py))
#used to draw points
point.draw(screen)
if pygame.sprite.collide_rect(sprite, point):
removepellets(pointspawns, row, n , py)
global score
score+=1
allpelletsremoved(pointspawns, copyofpointspawns)
def allpelletsremoved(pointspawns, copyofpointspawns):
total=0
print()
print('start of allpelletsremoved')
for row in pointspawns:
print('have gone through a row')
if not row:
total+=1
print('current total: ', total)
#if total =5 it means all rows are emtpy and thereofr all pellets have been eaten
if total==5:
pointspawns= copy.deepcopy(copyofpointspawns)
spawnpellets(pointspawns)
def removepellets(pointspawns, row, n, py):
collidedx=n+1
collidedy=py/16
collidedy=int(collidedy)
tempindex=row.index(collidedx)
del pointspawns[collidedy][tempindex]
#pointspawns[int(collidedy)].insert(collidedx,0)
#co-ordinates for boxes to set up map boundaries
boxboundaries=[
[],
[],
[],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],
[1,14,15,28], #5
[1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
[1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
[1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
[1,28],
[1,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,28], #10
[1,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,28],
[1,8,9,14,15,20,21,28],
[1,2,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,27,28],
[1,2,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,27,28],
[6,8,9,20,21,23], #15
[6,8,9,11,12,13,14,15,16,17,18,20,21,23],
[1,2,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28],
[1,11,12,13,14,15,16,17,18,28],
[1,2,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28],
[6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28], #20
[6,8,9,20,21,23],
[6,8,9,11,12,13,14,15,16,17,18,20,21,23],
[1,2,3,4,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,25,26,27,28],
[1,14,15,28],
[1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28], #25
[1,3,4,5,6,8,9,10,11,12,14,15,17,18,19,20,21,23,24,25,26,28],
[1,5,6,23,24,28],
[1,2,3,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,26,27,28],
[1,2,3,5,6,8,9,11,12,13,14,15,16,17,18,20,21,23,24,26,27,28],
[1,8,9,14,15,20,21,28], # 30
[1,3,4,5,6,7,8,9,10,11,12,14,15,17,18,19,20,21,22,23,24,25,26,28],
[1,3,4,5,6,7,8,9,10,11,12,14,15,17,18,19,20,21,22,23,24,25,26,28],
[1,28],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],
]
#point spawn locations, temporarily not using it as collecting
#all points would be to difficult to test
pointspawns1=[
[],
[],
[],
[],
[2,3,4,5,6,7,8,9,10,11,12,13,16,17,18,19,20,21,22,23,24,25,26,27], #5
[2,7,13,16,22,27],
[2,7,13,16,22,27],
[2,7,13,16,22,27],
[2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],
[2,7,10,19,22,27], #10
[2,7,10,19,22,27],
[2,3,4,5,6,7,10,11,12,13,16,17,18,19,22,23,24,25,26,27],
[7,22],
[7,22],
[7,22], #15
[7,22],
[7,22],
[7,22],
[7,22],
[7,22], #20
[7,22],
[7,22],
[7,22],
[2,3,4,5,6,7,8,9,10,11,12,13,16,17,18,19,20,21,22,23,24,25,26,27],
[2,7,13,16,22,27], #25
[2,7,13,16,22,27],
[2,3,4,7,8,9,10,11,12,13,16,17,18,19,20,21,22,25,26,27],
[4,7,10,19,22,25],
[4,7,10,19,22,25],
[2,3,4,5,6,7,10,11,12,13,16,17,18,19,22,23,24,25,26,27],
[2,13,16,27], # 30
[2,13,16,27],
[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],
]
#temporary point spawn locations, used so it easier to test when they are all eaten
pointspawns=[
[],
[],
[],
[],
[2,3,4,5,6,7,8,9,10,11,12,13,16,17,18,19,20,21,22,23,24,25,26,27], #5
]
#makes a copy of pointspawns to reset pointspawns for later
copyofpointspawns= copy.deepcopy(pointspawns)
#instances the pacman class
sprite = pacman(PACMANSPRITE, x ,y)
#main game loop
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.quit()
sys.exit()
screen.fill((0,0,0))
screen.blit(PACMAN_MAP, (0, 0))
#moves pacman
sprite.movement()
#spawn pellets
spawnpellets(pointspawns)
#builds the boxes
bx=0
by=-16
for row in boxboundaries:
#y co ordinate
by=by+16
for n in row:
#x co ordinate
n=n-1
bx=n*16
box=(boxcollisions(bx, by))
#used to draw boxes for visual repsentation
#box.draw(screen)
if pygame.sprite.collide_rect(sprite, box):
sprite.outofbounds()
#draws pacman
sprite.draw(screen)
#draws score to screen
label = myfont.render("HIGH SCORE:", 1, (255,255,255))
screen.blit(label, (180, 0))
labelscore = myfont.render(str(score), 1, (255,255,255))
screen.blit(labelscore, (180, 16))
pygame.display.flip()
clock.tick(60)
Upvotes: 1
Views: 302
Reputation: 20438
I would do something like this: Define a function that creates a sprite group and fills it with the pellet sprites, then return it and assign it to a variable in the main function. When the pellets
group is empty, just call this function again and assign the new group to the old variable and the pellets will appear again.
import pygame as pg
class Player(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((30, 30))
self.image.fill(pg.Color('yellow'))
self.rect = self.image.get_rect(center=pos)
self.vel = pg.math.Vector2(0, 0)
self.pos = pg.math.Vector2(pos)
def update(self):
self.pos += self.vel
self.rect.center = self.pos
class Pellet(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((10, 6))
self.image.fill(pg.Color('turquoise'))
self.rect = self.image.get_rect(center=pos)
def create_map():
"""Create a sprite group filled with Pellet sprites."""
group = pg.sprite.Group()
for i in range(10):
group.add(Pellet((50, 20*i+50)))
return group
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
player = Player((100, 300), all_sprites)
pellets = create_map()
all_sprites.add(pellets)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_d:
player.vel.x = 5
elif event.key == pg.K_a:
player.vel.x = -5
elif event.key == pg.K_w:
player.vel.y = -5
elif event.key == pg.K_s:
player.vel.y = 5
elif event.type == pg.KEYUP:
if event.key == pg.K_d:
player.vel.x = 0
elif event.key == pg.K_a:
player.vel.x = 0
elif event.key == pg.K_w:
player.vel.y = 0
elif event.key == pg.K_s:
player.vel.y = 0
all_sprites.update()
hit_pellets = pg.sprite.spritecollide(player, pellets, True)
for pellet in hit_pellets:
print('Yum!')
if not pellets: # If the pellets group is empty.
print('No food left. Respawing food!')
pellets = create_map() # Recreate the group.
all_sprites.add(pellets) # And add them to the general group.
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Upvotes: 1
Reputation: 1
If your sure that pygame.rect.draw is not working than try using the draw function I use it and it works. Look here for more on the draw function
https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Group.draw
and some example code
Displaying platforms using strings (Pygame)
I dont know to much about your long lists you have but you could make it shorter is you used string lists (also in the example code). Hope I could help.
Upvotes: 0