'Tetris remove completed lines and shift all the remaining blocks
So I wrote Tetris in pygame and all I need now is to remove the completed lines and shift all the remaining blocks. But I don't know how to implement this. Can anyone help me, please?
I tried to get the color of the different points of a line or to check collision somehow but I cant get it to work.
This is some basic setup. import random import pygame from sys import exit
pygame.init()
# window
window = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Tetris")
here are all the classes of the shapes
# classes
class Ishape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("I-rotation1png.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (104, 26))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
class Jshape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("J1.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (52, 78))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
class Lshape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("L1.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (52, 78))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
class Oshape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("O.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (52, 52))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
class Sshape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("S1.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (78, 52))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
class Tshape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("T1.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (78, 52))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
class Zshape(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("Z1.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (78, 52))
self.rect = self.image.get_rect(topleft = (484, 26))
self.mask = pygame.mask.from_surface(self.image)
self.pressed = False
self.run_once = True
self.run_once2 = True
self.run_once3 = True
self.do_stuff = True
def movement(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_d] and self.run_once:
self.rect.x += 26
self.run_once = False
if not keys[pygame.K_d]:
self.run_once = True
if keys[pygame.K_a] and self.run_once2:
self.rect.x -= 26
self.run_once2 = False
if not keys[pygame.K_a]:
self.run_once2 = True
if keys[pygame.K_s] and self.run_once3:
self.rect.y += 26
self.run_once3 = False
if not keys[pygame.K_s]:
self.run_once3 = True
def rotate(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_r]:
self.pressed = True
if not keys[pygame.K_r] and self.pressed:
self.pressed = False
self.image = pygame.transform.rotate(self.image, 90)
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
if self.do_stuff:
self.rotate()
self.movement()
here I created groups of the classes
# groups
I = pygame.sprite.GroupSingle()
I.add(Ishape())
J = pygame.sprite.GroupSingle()
J.add(Jshape())
L = pygame.sprite.GroupSingle()
L.add(Lshape())
O = pygame.sprite.GroupSingle()
O.add(Oshape())
S = pygame.sprite.GroupSingle()
S.add(Sshape())
T = pygame.sprite.GroupSingle()
T.add(Tshape())
Z = pygame.sprite.GroupSingle()
Z.add(Zshape())
# variables
running = False
clock = pygame.time.Clock()
only_base_groups = [I, J, L, O, S, T, Z]
group_list = [I, J, L, O, S, T, Z]
placed_groups = []
colors = []
current_class = random.choice(group_list)
next_class = random.choice(group_list)
score = 0
# function
def display_grid():
for y in range(155, 671, 26):
pygame.draw.line(window, "white", (380, y), (630, y))
for x in range(380, 625, 26):
pygame.draw.line(window, "white", (x, 155), (x, 665))
def add_class(group):
global placed_groups
placed_groups.append(group)
# surfaces
background = pygame.image.load("background.png").convert_alpha()
backgroundRect = background.get_rect(topleft = (0, 0))
scoreFont = pygame.font.Font(None, 40)
# timer
moveTimer = pygame.USEREVENT + 1
pygame.time.set_timer(moveTimer, 700)
this is where it should be implemented (in the main game section) while True: if running: pygame.display.update() clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == moveTimer:
current_class.sprite.rect.y += 26
window.blit(background, backgroundRect)
# score
score = score + 0.1
scoreSurf = scoreFont.render('Score: ' + str(int(score)), False, 'white')
window.blit(scoreSurf, (200, 340))
# main game
if background.get_at((383, 675)) != (38, 38, 38, 255):
print(background.get_at((383, 675)))
current_class.draw(window)
current_class.update()
add_class(current_class)
for i in placed_groups:
if placed_groups:
i.draw(window)
i.update()
if not current_class.sprite.do_stuff:
current_class = next_class
next_class = random.choice(only_base_groups)
if current_class == I:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Ishape())
elif current_class == J:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Jshape())
elif current_class == L:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Lshape())
elif current_class == O:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Oshape())
elif current_class == S:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Sshape())
elif current_class == T:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Tshape())
elif current_class == Z:
current_class = current_class.copy()
group_list.append(current_class)
current_class.add(Zshape())
# display next class
window.blit(next_class.sprite.image, (670, 170))
# collision
for group in group_list:
if group.sprite.rect.bottom >= 675:
group.sprite.rect.bottom = 675
group.sprite.do_stuff = False
for group in group_list:
if group.sprite.rect.right >= 640:
group.sprite.rect.right = 640
for group in group_list:
if group.sprite.rect.left <= 380:
group.sprite.rect.left = 380
for group in placed_groups:
if group != current_class:
if pygame.sprite.spritecollide(current_class.sprite, group, False, pygame.sprite.collide_mask):
current_class.sprite.rect.y -= 1
current_class.sprite.do_stuff = False
for group in placed_groups:
if not group.sprite.do_stuff:
if group.sprite.rect.top <= 155:
running = False
display_grid()
else:
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
running = True
group_list = [I, J, L, O, S, T, Z]
placed_groups = []
current_class = random.choice(group_list)
next_class = random.choice(group_list)
score = 0
if score > 0:
end_font = pygame.font.Font(None, 90)
end_surf = end_font.render('Your score was: ' + str(int(score)), False, 'white')
window.blit(end_surf, (70, 400))
else:
start_font = pygame.font.Font(None, 90)
start_surf = start_font.render("Press space to start the game", False, 'white')
window.blit(start_surf, (70, 400))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
