I'm trying to make tetris in pygame and I've got collisions and movement down but, when a mask collides with a placed block, the rect I use to cover the old sprite covers parts of the placed sprite:
def replace(self):
pygame.draw.rect(board_surface,(0,0,0),(self.rect.topleft, self.rect.size))
This code is in my sprite class:
class Block(pygame.sprite.Sprite):
def __init__(self, blocks):
super().__init__()
self.random_block = randint(1,7)
self.image = blocks[self.random_block]
self.image = pygame.transform.scale(self.image,(self.image.get_width()*.4, self.image.get_height()*.4))
self.rect = self.image.get_rect()
self.rect.topleft = (300,0)
self.mask = pygame.mask.from_surface(self.image)
def replace(self):
pygame.draw.rect(board_surface,(0,0,0),(self.rect.topleft, self.rect.size))
def handle_keys(self, board_s, block, unactive_blocks):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
if self.rect.left - 60 >= 0:
self.replace(block_colours)
self.rect.x -= 60
self.draw(block_group, board_s)
elif keys[pygame.K_RIGHT] or keys[pygame.K_d]:
if self.rect.right 60 <= 600:
self.replace(block_colours)
self.rect.x = 60
self.draw(block_group, board_s)
elif keys[pygame.K_UP] or keys[pygame.K_w]:
self.replace(block_colours)
topleft = self.rect.topleft
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect()
self.rect.topleft = topleft
self.mask = pygame.mask.from_surface(self.image)
self.draw(block_group, board_s)
elif keys[pygame.K_DOWN] or keys[pygame.K_s]:
if self.rect.bottom 60 <= 1200:
self.replace(block_colours)
self.rect.y = 60
if pygame.sprite.spritecollide(block,unactive_blocks,False,pygame.sprite.collide_mask):
self.rect.y -= 60
block_sprite(blocks, block)
self.draw(block_group, board_s)
else:
block_sprite(blocks, block)
def move_every_second(self, block, unactive_blocks):
if self.rect.bottom 60 <= 1200:
self.replace(block_colours)
self.rect.y = 60
if pygame.sprite.spritecollide(block,unactive_blocks,False,pygame.sprite.collide_mask):
self.rect.y -= 60
block_sprite(blocks, block)
self.draw(block_group, board_s)
else:
block_sprite(blocks, block)
def draw(self, block_group, board_s):
print(self.rect.x,self.rect.y)
block_group.draw(board_s)
Full code at pastebin.com/59E74zBJ
CodePudding user response:
The usual and simplest method is to redraw the scene in each frame. What if the background does not have a uniform color? How are you going to restore the background if it is an image?
However, you can create a Surface from a Mask with to_surface
and blit
this Surface instead of drawing a rectangle:
cover_image = self.mask.to_surface(setcolor=(0, 0, 0, 255), unsetcolor=(0, 0, 0, 0))
board_surface.blit(cover_image, self.rect.topleft)