You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame报错:blit方法需传入pygame.Surface而非pygame.Rect

解决Pygame中blit调用的TypeError问题

首先来拆解你遇到的错误:

TypeError: descriptor 'blit' requires a 'pygame.Surface' object but received a 'pygame.Rect'.

这个错误的核心原因很明确:

  • pygame.draw.rect()函数执行后,返回的是一个**pygame.Rect对象**——它只是用来描述你绘制的矩形的位置和尺寸,并不是一个可以被blit的Surface(图像表面)。
  • 你错误地把这个Rect对象传给了pygame.surface.Surface.blit(),而且这个调用方式本身就不对:blit是Surface实例的方法,应该在你要绘制的目标Surface(比如你的gameDisplay)上调用,而不是直接调用Surface类的方法。

再看你的W键逻辑,其实完全不需要blit这一步——pygame.draw.rect已经直接在gameDisplay上完成了绘制,额外的blit操作完全是多余的,还引发了错误。

下面是针对W键部分的修正方案,同时保留你要求的S键原有逻辑(我也会提一个小优化建议):

修正后的完整代码

import pygame
import time
pygame.init()

display_width = 1366
display_height = 768
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))
clock = pygame.time.Clock()

# 全局变量定义
x1 = 683
y1 = 384
x2 = 0
y2 = 500

def game():
    global y1  # 加上global声明,否则会创建局部变量,无法修改全局y1
    y1 = 384
    gameDisplay.fill(white)
    pygame.draw.rect(gameDisplay, red, (x1,y1,250,250), 0)
    pygame.draw.rect(gameDisplay, green, (x2,y2,100,100), 0)
    pygame.display.update()

gameStart = True
while gameStart == True:
    while True:
        for event in pygame.event.get():
            # 新增窗口退出事件处理,不然游戏窗口会无法正常关闭
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
                
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    print('Forward')
                    y1 += 1
                    # 1. 先填充背景清除上一帧的绘制,避免矩形移动留下拖影
                    gameDisplay.fill(white)
                    # 2. 重新绘制两个矩形(包括绿色的,不然会被白色背景覆盖)
                    pygame.draw.rect(gameDisplay, red, (x1,y1,250,250), 0)
                    pygame.draw.rect(gameDisplay, green, (x2,y2,100,100), 0)
                    # 3. 更新显示
                    pygame.display.update()
                    
                elif event.key == pygame.K_s:
                    print('Backward')
                    y1 -= 1
                    # 这里保留了你原有的逻辑,但建议和W键一样先填充背景再重绘,避免拖影
                    gameDisplay.fill(white)
                    pygame.draw.rect(gameDisplay, red, (x1,y1,250,250), 0)
                    pygame.draw.rect(gameDisplay, green, (x2,y2,100,100), 0)
                    pygame.display.update()
game()

关键修改点说明

  1. 移除错误的blit调用:完全删掉pygame.surface.Surface.blit(a, (x1, y1))这一行,因为pygame.draw.rect已经直接在gameDisplay上完成了绘制,不需要额外的blit操作。
  2. 添加背景填充:每次按键后先调用gameDisplay.fill(white)清除上一帧的所有内容,这样红色矩形移动时不会留下拖影;同时要重新绘制绿色矩形,不然它会被白色背景覆盖消失。
  3. 修复全局变量问题:在game函数里加上global y1声明,不然函数内的y1 = 384会创建一个局部变量,不会修改你全局定义的y1。
  4. 新增退出事件处理:添加pygame.QUIT事件的处理逻辑,否则你的游戏窗口会无法正常关闭。

内容的提问来源于stack exchange,提问作者henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:07:27