尝试通过编写一些游戏来学习更多python,只是通过一些youtube教程进行工作。这是从youtube上的俄罗斯方块教程编写的。我已经改变了一切,查看了最终代码,但仍然无法解决此错误。
这是错误
Traceback (most recent call last):
File "C:/Users/Ellis/PycharmProjects/firstprojectever/what is your name.py", line 418, in <module>
main_menu(win)
File "C:/Users/Ellis/PycharmProjects/firstprojectever/what is your name.py", line 407, in main_menu
draw_text_middle(win, "Press Any Key To Play", 60, (255, 255, 255))
File "C:/Users/Ellis/PycharmProjects/firstprojectever/what is your name.py", line 209, in draw_text_middle
surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), top_left_y + play_height / 2 - label.get_height() / 2))
AttributeError: 'tuple' object has no attribute 'blit'
Process finished with exit code 1
这是我的代码
import pygame
import random
# creating the data structure for pieces
# setting up global vars
# functions
# - create_grid
# - draw_grid
# - draw_window
# - rotating shape in main
# - setting up the main
"""
10 x 20 square grid
shapes: S, Z, I, O, J, L, T
represented in order by 0 - 6
"""
pygame.font.init()
# GLOBALS VARS
s_width = 800
s_height = 700
play_width = 300 # meaning 300 // 10 = 30 width per block
play_height = 600 # meaning 600 // 20 = 20 height per block
block_size = 30
top_left_x = (s_width - play_width) // 2
top_left_y = s_height - play_height
# SHAPE FORMATS
S = [['.....',
'......',
'..00..',
'.00...',
'.....'],
['.....',
'..0..',
'..00.',
'...0.',
'.....']]
Z = [['.....',
'.....',
'.00..',
'..00.',
'.....'],
['.....',
'..0..',
'.00..',
'.0...',
'.....']]
I = [['..0..',
'..0..',
'..0..',
'..0..',
'.....'],
['.....',
'0000.',
'.....',
'.....',
'.....']]
O = [['.....',
'.....',
'.00..',
'.00..',
'.....']]
J = [['.....',
'.0...',
'.000.',
'.....',
'.....'],
['.....',
'..00.',
'..0..',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'...0.',
'.....'],
['.....',
'..0..',
'..0..',
'.00..',
'.....']]
L = [['.....',
'...0.',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..0..',
'..00.',
'.....'],
['.....',
'.....',
'.000.',
'.0...',
'.....'],
['.....',
'.00..',
'..0..',
'..0..',
'.....']]
T = [['.....',
'..0..',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..00.',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'..0..',
'.....'],
['.....',
'..0..',
'.00..',
'..0..',
'.....']]
shapes = [S, Z, I, O, J, L, T]
shape_colors = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)]
# index 0 - 6 represent shape
class Piece(object):
def __init__(self, x, y, shape):
self.x = x
self.y = y
self.shape = shape
self.color = shape_colors[shapes.index(shape)]
self.rotation = 0
def create_grid(locked_positions: object = {}) -> object:
grid = [[(0, 0, 0) for x in range(10)] for x in range(20)]
for i in range(len(grid)):
for j in range(len(grid[i])):
if (j, i) in locked_positions:
c = locked_positions[(j, i)]
grid[i][j] = c
return grid
def convert_shape_format(shape):
positions = []
format = shape.shape[shape.rotation % len(shape.shape)]
for i, line in enumerate(format):
row = list(line)
for j, column in enumerate(row):
if column == '0':
positions.append((shape.x + j, shape.y + i))
for i, pos in enumerate(positions):
positions[i] = (pos[0] - 2, pos[1] - 4)
return positions
def valid_space(shape, grid):
accepted_pos = [[(j, i) for j in range(10) if grid[i][j] == (0, 0, 0)] for i in range(20)]
accepted_pos = [j for sub in accepted_pos for j in sub]
formatted = convert_shape_format(shape)
for pos in formatted:
if pos not in accepted_pos:
if pos[1] > -1:
return False
return True
def check_lost(positions):
for pos in positions:
x, y = pos
if y < 1:
return True
return False
def get_shape():
return Piece(5, 0, random.choice(shapes))
def draw_text_middle(text, size, color, surface):
font = pygame.font.SysFont("comicsans", 30, bold=True)
label = font.render("comicsans", 1, (255,255,255))
surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), top_left_y + play_height / 2 - label.get_height() / 2))
def draw_grid(surface, grid):
sx = top_left_x
sy = top_left_y
for i in range(len(grid)):
pygame.draw.line(surface, (128, 128, 128), (sx, sy + i * block_size), (sx + play_width, sy + i * block_size))
for j in range(len(grid[i])):
pygame.draw.line(surface, (128, 128, 128), (sx + j * block_size, sy),
(sx + j * block_size, sy + play_height))
def clear_rows(grid, locked):
inc = 0
for i in range(len(grid) - 1, -1, -1):
row = grid[i]
if (0, 0, 0) not in row:
inc += i
ind = i
for j in range(len(row)):
try:
del locked[(j, i)]
except:
continue
if inc > 0:
for key in sorted(list(locked), key=lambda x: x[1])[::-1]:
x, y = key
if y < ind:
newKey = (x, y + inc)
locked[newKey] = locked.pop(key)
return inc
def draw_next_shape(shape, surface):
font = pygame.font.SysFont('Arial', 30)
label = font.render('Next Shape', 1, (255, 255, 255))
sx = top_left_x + play_width + 50
sy = top_left_y + play_height / 2 - 100
format = shape.shape[shape.rotation % len(shape.shape)]
for i, line in enumerate(format):
row = list(line)
for j, column in enumerate(row):
if column == '0':
pygame.draw.rect(surface, shape.color,
(sx + j * block_size, sy + i * block_size, block_size, block_size), 0)
surface.blit(label, (sx + 10, sy - 30))
def update_score(nscore):
score = max_scores()
with open('scores.txt', 'r') as f:
lines = f.readlines()
score = lines[0].strip()
with open('scores.txt', 'w') as f:
if int(score) > nscore:
f.write(str(score))
else:
f.write(str(nscore))
def max_scores():
with open('scores.txt', 'r') as f:
lines = f.readlines()
score = lines[0].strip()
return score
def draw_window(surface, grid, score=0, last_score=0):
surface.fill((0, 0, 0))
pygame.font.init()
font = pygame.font.SysFont('comicsans', 60)
label = font.render('Tetris', 1, (255, 255, 255))
surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), 30))
# current score
font = pygame.font.SysFont('Arial', 30)
label = font.render('Score: ' + str(score), 1, (255, 255, 255))
sx = top_left_x + play_width + 50
sy = top_left_y + play_height / 2 - 100
surface.blit(label, (sx + 30, sy + 160))
# last score
label = font.render('High Score: ' + last_score, 1, (255, 255, 255))
sx = top_left_x - 200
sy = top_left_y + 200
surface.blit(label, (sx + 30, sy + 160))
for i in range(len(grid)):
for j in range(len(grid[i])):
pygame.draw.rect(surface, grid[i][j],
(top_left_x + j * block_size, top_left_y + i * block_size, block_size, block_size), 0)
pygame.draw.rect(surface, (255, 0, 0), (top_left_x, top_left_y, play_width, play_height), 5)
draw_grid(surface, grid)
# pygame.display.update()
def main(win):
last_score = max_scores()
locked_positions = {}
grid = create_grid(locked_positions)
change_piece = False
run = True
current_piece = get_shape()
next_piece = get_shape()
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 0.27
level_time = 0
score = 0
while run:
grid = create_grid(locked_positions)
fall_time += clock.get_rawtime()
level_time += clock.get_rattime()
clock.tick()
if level_time / 1000 > 5:
if fall_speed > 0.12:
fall_speed -= 0.005
if fall_time / 1000 > fall_speed:
fall_time = 0
current_piece.y += 1
if not (valid_space(current_piece, grid)) and current_piece.y > 0:
current_piece.y - 1
change_piece = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
current_piece.x -= 1
if not (valid_space(current_piece, grid)):
current_piece.x += 1
if event.key == pygame.K_RIGHT:
current_piece.x += 1
if not (valid_space(current_piece, grid)):
current_piece.x -= 1
if event.key == pygame.K_DOWN:
current_piece.y += 1
if not (valid_space(current_piece, grid)):
current_piece.y -= 1
if event.key == pygame.K_UP:
current_piece.rotation += 1
if not (valid_space(current_piece, grid)):
current_piece.rotation -= 1
shape_pos = convert_shape_format(current_piece)
for i in range(len(shape_pos)):
x, y = shape_pos[i]
if y > -1:
grid[y][x] = current_piece.color
if change_piece:
for pos in shape_pos:
p = (pos[0], pos[1])
locked_positions[p] = current_piece.color
current_piece = next_piece
next_piece = get_shape()
change_piece = False
score += clear_rows(grid, locked_positions) * 10
draw_window(win, grid, score, last_score)
draw_next_shape(next_piece, win)
pygame.display.update()
if check_lost(locked_positions):
draw_text_middle(win, 'BETTER LUCK NEXT TIME GAMER!', 80, (255, 255, 255))
pygame.display.update()
pygame.time.delay(1500)
run = False
update_score(score)
def main_menu(win):
run = True
while run:
win.fill((0, 0, 0))
draw_text_middle(win, "Press Any Key To Play", 60, (255, 255, 255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
main(win)
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
感谢您提供任何反馈意见,不确定是怎么回事。我正在通过基于项目的学习来学习python,所以我还是菜鸟。随意残酷