I am writing a simple class Block
which holds four Rect
from pygame. It has a key_press
function which would move the four Rect
when according keys are pressed. It also has a draw
function which draws the four Rect
on the screen.
The problem comes within the while loop below. Within the while loop, I want to move the block around with keys. Whenever the current block reaches the bottom of the screen, it stops there and a new block gets created. The key press functionality should now ONLY act on the new block.
However, the problem I have with the codes below is that, after the new block is created, the key press acts on BOTH of the blocks (i.e. pressing right would move both to the right).
so I guess my problem could be summed up into one question:
Why didn't the key press function act on the current block only, but both?
Thank you very much in advance!
import pygame
from pygame.rect import Rect
pygame.init()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# Set the height and width of the screen
block_size = 20
row, col = 20, 20
color = RED
size = [block_size * col, block_size * row]
screen = pygame.display.set_mode(size)
class Block(Rect):
shape = [] # hold blocks which are part of the shape
def __init__(self):
self.block1 = Rect(0, block_size, block_size, block_size)
self.block2 = Rect(0, block_size * 2, block_size, block_size)
self.block3 = Rect(0, block_size * 3, block_size, block_size)
self.block4 = Rect(0, block_size * 4, block_size, block_size)
self.shape.append(self.block1)
self.shape.append(self.block2)
self.shape.append(self.block3)
self.shape.append(self.block4)
def key_press(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
for item in self.shape:
item.move_ip(-block_size, 0)
if key[pygame.K_RIGHT]:
for item in self.shape:
item.move_ip(block_size, 0)
if key[pygame.K_UP]:
for item in self.shape:
item.move_ip(0, -block_size)
if key[pygame.K_DOWN]:
for item in self.shape:
item.move_ip(0, block_size)
def draw(self, surface):
for item in self.shape:
pygame.draw.rect(surface, color, item)
def get_bottom(self):
return self.block4.bottom
done = False
clock = pygame.time.Clock()
curr_block = Block()
while not done:
clock.tick(10)
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
screen.fill(WHITE)
curr_block.key_press()
if curr_block.get_bottom() >= block_size * row:
curr_block = Block()
curr_block.draw(screen) # draw the falling block
pygame.display.flip()
pygame.quit()
Every time when a new block is created by curr_block = Block()
, then 4 new elements are append at the end of the list self.shape
. If you only want to move the most resent blocks, then then you have to move the last 4 elements of self.shape
. The last 4 elements can be accessed by self.shape[-4:]
(See Subscriptions). For instance:
class Block(Rect):
# [...]
def key_press(self):
key = pygame.key.get_pressed()
for item in self.shape[-4:]:
if key[pygame.K_LEFT]:
item.move_ip(-block_size, 0)
if key[pygame.K_RIGHT]:
item.move_ip(block_size, 0)
if key[pygame.K_UP]:
item.move_ip(0, -block_size)
if key[pygame.K_DOWN]:
item.move_ip(0, block_size)