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

如何在一个函数中调用另一个函数内定义的对象方法?(Pygame场景)

如何在PyGame中正确绘制背景与线条,避免移动对象拖尾?

问题说明

我需要在draw_window函数里调用line1.draw_shape()、line2.draw_shape()等方法,让线条绘制在背景之上。目前在shape_generation函数内直接调用draw_shape时,无背景的情况下线条显示正常,但后续要添加可移动的玩家矩形,必须先绘制背景来更新屏幕所有像素,否则玩家移动时会留下拖尾。

之前尝试无背景绘制线条,不仅移动对象会留下颜色痕迹,重新生成线条位置时,旧线条也会因为像素没被背景色覆盖而残留。

原代码

import pygame
import sys
import random

WIDTH, HEIGHT = 1050, 630
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("game")
FPS = 30
GREY = (15, 15, 15)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
VEL = 5

class line:
    def __init__(self, lineX, lineY, dimensions):
        
        self.dimensions = dimensions
        
        if self.dimensions[2] == 1:
            self.lineY = lineY - HEIGHT//3
            self.lineX = lineX
        
        elif self.dimensions[2] == 2:
            self.lineX = lineX - HEIGHT//3
            self.lineY = lineY
        else:
            self.lineX = lineX
            self.lineY = lineY
            
    def draw_shape(self):
        pygame.draw.rect(WIN, BLUE, [self.lineX, self.lineY, self.dimensions[0], self.dimensions[1]] )

def shape_generation():
    LINE_DIMENSIONS = ((10, HEIGHT // 3, 1 ), (HEIGHT // 3, 10, 0), (10, HEIGHT // 3, 0), (HEIGHT // 3, 10, 2)) #NORTH, EAST, SOUTH, WEST
    line0 = line(WIDTH // 5, HEIGHT // 3, random.choice(LINE_DIMENSIONS))
    line1 = line((WIDTH // 5) * 2, HEIGHT // 3, random.choice(LINE_DIMENSIONS))
    line2 = line((WIDTH // 5) * 3, HEIGHT // 3, random.choice(LINE_DIMENSIONS))
    line3 = line((WIDTH // 5) * 4, HEIGHT // 3, random.choice(LINE_DIMENSIONS))
    line4 = line(WIDTH // 5, (HEIGHT // 3) * 2, random.choice(LINE_DIMENSIONS))
    line5 = line((WIDTH // 5) * 2, (HEIGHT // 3) * 2, random.choice(LINE_DIMENSIONS))

    
    line0.draw_shape()
    line1.draw_shape()
    line2.draw_shape()
    line3.draw_shape()
    line4.draw_shape()
    line5.draw_shape()
  
def draw_window():
    WIN.fill(GREY)
    #This is where I would like the walls to be drawn.
    pygame.display.update()

def main():
    
    clock = pygame.time.Clock()
    shape_generation()
    
    run = True
    
    while run:
        clock.tick(FPS)

        for event in pygame.event.get():
            
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                sys.exit()
              
        draw_window()
        pygame.display.update()


if __name__ == "__main__":
    main()

解决方案

核心思路是:把线条对象保存下来,在每次绘制窗口时,先填充背景,再重新绘制所有线条,这样每次刷新都会用背景覆盖旧像素,避免残留。具体修改步骤:

  1. 修改shape_generation函数,让它返回生成的所有线条对象列表,不再在函数内直接绘制
  2. 在main函数中接收这个线条列表,保存为变量
  3. 在draw_window函数中添加参数接收线条列表,遍历列表调用每个线条的draw_shape方法
  4. 移除原shape_generation内的draw_shape调用

修改后的完整代码

import pygame
import sys
import random

WIDTH, HEIGHT = 1050, 630
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("game")
FPS = 30
GREY = (15, 15, 15)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
VEL = 5

class line:
    def __init__(self, lineX, lineY, dimensions):
        
        self.dimensions = dimensions
        
        if self.dimensions[2] == 1:
            self.lineY = lineY - HEIGHT//3
            self.lineX = lineX
        
        elif self.dimensions[2] == 2:
            self.lineX = lineX - HEIGHT//3
            self.lineY = lineY
        else:
            self.lineX = lineX
            self.lineY = lineY
            
    def draw_shape(self):
        pygame.draw.rect(WIN, BLUE, [self.lineX, self.lineY, self.dimensions[0], self.dimensions[1]] )

def shape_generation():
    LINE_DIMENSIONS = ((10, HEIGHT // 3, 1 ), (HEIGHT // 3, 10, 0), (10, HEIGHT // 3, 0), (HEIGHT // 3, 10, 2)) #NORTH, EAST, SOUTH, WEST
    lines = []
    lines.append(line(WIDTH // 5, HEIGHT // 3, random.choice(LINE_DIMENSIONS)))
    lines.append(line((WIDTH // 5) * 2, HEIGHT // 3, random.choice(LINE_DIMENSIONS)))
    lines.append(line((WIDTH // 5) * 3, HEIGHT // 3, random.choice(LINE_DIMENSIONS)))
    lines.append(line((WIDTH // 5) * 4, HEIGHT // 3, random.choice(LINE_DIMENSIONS)))
    lines.append(line(WIDTH // 5, (HEIGHT // 3) * 2, random.choice(LINE_DIMENSIONS)))
    lines.append(line((WIDTH // 5) * 2, (HEIGHT // 3) * 2, random.choice(LINE_DIMENSIONS)))
    
    # 移除原函数内的绘制调用,统一放到draw_window里处理
    return lines
  
def draw_window(lines):
    WIN.fill(GREY)
    # 遍历线条列表,绘制所有线条
    for line_obj in lines:
        line_obj.draw_shape()
    pygame.display.update()

def main():
    
    clock = pygame.time.Clock()
    # 保存生成的线条列表
    lines = shape_generation()
    
    run = True
    
    while run:
        clock.tick(FPS)

        for event in pygame.event.get():
            
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                sys.exit()
              
        # 传入线条列表到draw_window
        draw_window(lines)


if __name__ == "__main__":
    main()

关键改动说明

  • shape_generation现在返回线条对象列表,不再直接绘制,让绘制逻辑统一由draw_window管理
  • draw_window先填充背景(WIN.fill(GREY)),再绘制所有线条,这样每次循环都会刷新整个屏幕,旧的线条和玩家拖尾都会被背景覆盖
  • 去掉了main函数里重复的pygame.display.update(),避免重复刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:30:54