python - pygame 在矩形消失后不会重新绘制矩形

标签 python pygame draw pacman drawrectangle

我正在制作一个吃 bean 人游戏,目前我已经具备了基础知识,但我无法让吃 bean 人颗粒在全部被吃掉后重生。目前,我已设置为在吃完 pac 颗粒后,它将从 pacpellets 列表中删除。当列表为空时,它会被重新填充,然后被告知将所有 pac 颗粒重新绘制到屏幕上。它检查了所有正确的函数和所有内容,我已经用 print 语句检查过,但是 pygame.draw.rect 不起作用,我不明白为什么。

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)

最佳答案

我会做这样的事情:定义一个函数,创建一个 Sprite 组并用颗粒 Sprite 填充它,然后返回它并将其分配给主函数中的变量。当pellets组为空时,只需再次调用此函数并将新组分配给旧变量,颗粒就会再次出现。

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()

关于python - pygame 在矩形消失后不会重新绘制矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45970399/

相关文章:

android - 如何减少 unity3d 中的绘图调用

ios - 如何在 ios 中绘制具有角度和距离的线

python - 在 Pandas 中,如何在 DataFrame 中排在前十组数据?

python - 用于收集 numpy 数组的高效查找表

python - 如何在pygame中添加闪烁的光标?

python - 打字机效果 Pygame

Android drawBitmap(...) 方法很慢?

python - 使用 Pandas 为每个过滤器识别列中最接近的值

python - 如何将 4 位数据加载到 numpy 数组中

python - 让子弹朝玩家面对的方向发射