【问题标题】:Pygame Tetris IssuePygame俄罗斯方块问题
【发布时间】:2017-05-08 15:30:54
【问题描述】:

我一直在为 Python 3.6 中的 Pygame 编写一个非常初级的俄罗斯方块版本。到目前为止,唯一的特点是方块下落,使它们下落得更快,左右移动,当一个方块撞到地面时,一个新的生成。

但是,有问题。当第一个方块落地时,方块会在屏幕顶部无限生成。我搜索了代码并将其展示给了我的朋友,但我们找不到问题所在。我废弃了代码并重写了它,但问题仍然存在。这里有人看吗?

谢谢

附: 我很确定代码的前 2/3 不是问题。

import pygame, random

screen = pygame.display.set_mode((400,600))
pygame.display.set_caption("Tetris")
done = False
fast = False
locked = False
fallingblocks = []
setblocks = []
clock = pygame.time.Clock()
fallcooldown = 0

class Block:

  def __init__(self, x, y, color):
    self.x = x
    self.y = y
    self.color = color
    fallingblocks.append(self)
    self.rect = pygame.Rect(self.x + 1, self.y, 23, 25) #game only cares if falling block collides on the top or bottom, not side

  def fall(self):
    self.y += 25

  def move(self):
    if pressed[pygame.K_a] or pressed[pygame.K_LEFT]: self.x -= 25
    if pressed[pygame.K_d] or pressed[pygame.K_RIGHT]: self.x += 25

  def drawblock(self): #just to make it look nice
    pygame.draw.rect(screen, self.color[0], pygame.Rect(self.x,self.y,25,25))
    pygame.draw.polygon(screen, self.color[1], ((self.x,self.y),(self.x+3,self.y+3),(self.x+21,self.y+3),(self.x+24,self.y)))
    pygame.draw.polygon(screen, self.color[2], ((self.x,self.y),(self.x+3,self.y+3),(self.x+3,self.y+21),(self.x,self.y+24)))
    pygame.draw.polygon(screen, self.color[3], ((self.x,self.y+24),(self.x+3,self.y+21),(self.x+21,self.y+21),(self.x+24,self.y+24)))
    pygame.draw.polygon(screen, self.color[4], ((self.x+24,self.y+24),(self.x+21,self.y+21),(self.x+21,self.y+3),(self.x+24,self.y)))

def spawn():
  blocknum = random.randint(0,6)

  if blocknum == 0:
    #I block
    colors = [(129,184,231),
    (179,223,250),
    (146,202,238),
    (76,126,189),
    (96,157,213)]

    Block(175,0,colors)
    Block(175,25,colors)
    Block(175,50,colors)
    Block(175,75,colors)
  elif blocknum == 1:
    #J block
    colors = [(77,110,177),
    (149,178,229),
    (104,145,203),
    (49,63,136),
    (63,85,158)]

    Block(200,0,colors)
    Block(200,25,colors)
    Block(200,50,colors)
    Block(175,50,colors)
  elif blocknum == 2:
    #L block
    colors = [(219,127,44),
    (243,191,122),
    (229,158,69),
    (166,71,43),
    (193,98,44)]

    Block(175,0,colors)
    Block(175,25,colors)
    Block(175,50,colors)
    Block(200,50,colors)  
  elif blocknum == 3:
    #O block
    colors = [(248,222,49),
    (246,243,139),
    (245,235,86),
    (183,160,54),
    (213,190,55)]

    Block(175,0,colors)
    Block(175,25,colors)
    Block(200,0,colors)
    Block(200,25,colors)
  elif blocknum == 4:
    #S block
    colors = [(156,195,76),
    (204,218,127),
    (174,208,79),
    (109,157,75),
    (140,183,93)]

    Block(175,0,colors)
    Block(175,25,colors)
    Block(200,0,colors)
    Block(150,25,colors)   
  elif blocknum == 5:
    #Z block
    colors = [(204,42,40),
    (226,138,132),
    (213,90,69),
    (151,34,42),
    (181,37,43)]

    Block(175,0,colors)
    Block(225,25,colors)
    Block(200,0,colors)
    Block(200,25,colors)
  else:
    #T block
    colors = [(147,68,149),
    (187,145,194),
    (156,101,167),
    (108,45,123),
    (128,47,135)]

    Block(175,0,colors)
    Block(175,25,colors)
    Block(200,0,colors)
    Block(150,0,colors)

spawn()

#Pretty sure that everything above here is not the issue

while not done: #main loop

  screen.fill((0,0,32))
  pressed = pygame.key.get_pressed()

  for fallingblock in fallingblocks:
    fallingblock.drawblock()
    fallingblock.move()

  for setblock in setblocks:
    setblock.drawblock()

  if fallcooldown >= 50: #makes all pieces fall at once
    for fallingblock in fallingblocks:
      fallingblock.fall()
    fallcooldown = 0
  pygame.display.flip()

  if pressed[pygame.K_SPACE]: #if you want the piece to go the ground instantly
    fast = True

  if fast: fallcooldown = 50 #falling movements
  elif pressed[pygame.K_DOWN]: fallcooldown += 8 #goes faster
  else: fallcooldown += 1 #default speed

  for fallingblock in fallingblocks:
    for setblock in setblocks:
      if fallingblock.rect.colliderect(setblock.rect): #if fallingblock collides with setblock
        locked = True
    if fallingblock.y >= 575 and not locked: #if block hits the bottom
      locked = True

  if locked: #if block is in final state
    setblocks += fallingblocks 
    fallingblocks = []
    spawn()
    locked = False

  clock.tick(50)
  pygame.display.flip()

  for event in pygame.event.get():
      if event.type == pygame.QUIT:
          done = True

【问题讨论】:

    标签: python python-3.x pygame tetris


    【解决方案1】:

    问题是由Blockfall 方法引起的。您只更改y 属性,但从不移动块的rect,因此它实际上一直停留在屏幕顶部。所以删除x, y 属性,只使用self.rect.xself.rect.y,或者设置self.rect.y = self.y

    为了调试代码,我首先在if locked: 行上方打印了print(locked, len(fallingblocks), len(setblocks)),以确认在第一个方块接触地面后locked 始终为True。然后我尝试用setblocks 注释掉碰撞检测,连续产卵停止了。下一步是打印设置块和下降块的矩形,它显示矩形的 y-pos 始终为 0 或 25,并且从未改变。我查看了fall 方法中的移动代码,发现矩形没有移动。

    还有更多问题,但我认为您应该先尝试继续调试,如果仍有问题,请提出新问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-30
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多