Pygame开发求助:生成随机变色形状、添加计数器及设置分散生成点
Pygame形状收集游戏解决方案
问题背景
我正在开发一款Pygame游戏,核心需求如下:
- 玩家需要收集指定颜色的形状,收集次数随机(1-5次)
- 屏幕上固定生成10个形状,每15秒刷新一次(旧形状消失,生成新形状)
当前遇到的问题:
- 生成的形状全部扎堆在一起,不知道怎么设置不同生成位置且不改变形状尺寸
- 不知道如何实现每15秒自动切换目标颜色并刷新形状
- 需要添加收集进度的计数器功能
原代码如下:
import pygame import random import time pygame.init() SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 size = ((300,250,50,50)) clock = pygame.time.Clock() FPS = 150 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Game") #colors black = (0,0,0) white = (255,255,255) red = (255,0,0) green = (0,255,0) blue = (0,0,255) random_color = [red, green, blue] #random shape_number = random.randint (1,5) shape_color = random.choice(random_color) #shapes player = pygame.Rect(size) shape = pygame.Rect(size) shape1 = pygame.Rect(size) shape2 = pygame.Rect(size) shape3 = pygame.Rect(size) shape4 = pygame.Rect(size) shape5 = pygame.Rect(size) shape6 = pygame.Rect(size) shape7 = pygame.Rect(size) shape8 = pygame.Rect(size) shape9 = pygame.Rect(size) shape10 = pygame.Rect(size) shape_color = random.choice(random_color) counter = "You have to get ", shape_number, " ", shape_color, " colored shapes" runWindow = True while runWindow: pygame.draw.rect(screen, (white), player) pygame.draw.rect(screen, (shape_color), shape) pygame.draw.rect(screen, (shape_color), shape1) pygame.draw.rect(screen, (shape_color), shape2) pygame.draw.rect(screen, (shape_color), shape3) pygame.draw.rect(screen, (shape_color), shape4) pygame.draw.rect(screen, (shape_color), shape5) pygame.draw.rect(screen, (shape_color), shape6) pygame.draw.rect(screen, (shape_color), shape7) pygame.draw.rect(screen, (shape_color), shape8) pygame.draw.rect(screen, (shape_color), shape9) pygame.draw.rect(screen, (shape_color), shape10) key = pygame.key.get_pressed() if key[pygame.K_a] == True: player.move_ip(-1, 0) if key[pygame.K_w] == True: player.move_ip(0, -1) if key[pygame.K_d] == True: player.move_ip(1, 0) if key[pygame.K_s] == True: player.move_ip(0, 1) if player == shape: pygame.draw.rect(screen, (shape_color), shape) for event in pygame.event.get(): if event.type == pygame.QUIT: runWindow = False clock.tick(FPS) pygame.display.update() screen.fill(black) continue pygame.quit()
完整修改代码
import pygame import random pygame.init() # 屏幕设置 SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Shape Collector") # 颜色定义 BLACK = (0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) COLORS = [RED, GREEN, BLUE] # 形状设置 SHAPE_SIZE = 50 SHAPE_COUNT = 10 # 玩家设置 PLAYER_SPEED = 5 player = pygame.Rect(SCREEN_WIDTH//2 - SHAPE_SIZE//2, SCREEN_HEIGHT//2 - SHAPE_SIZE//2, SHAPE_SIZE, SHAPE_SIZE) # 字体初始化(用于显示文字) pygame.font.init() FONT = pygame.font.SysFont(None, 40) # 游戏状态变量 target_color = random.choice(COLORS) target_count = random.randint(1, 5) collected = 0 shapes = [] last_refresh_time = pygame.time.get_ticks() REFRESH_INTERVAL = 15000 # 15秒,单位毫秒 # 生成形状的函数 def generate_shapes(): new_shapes = [] for _ in range(SHAPE_COUNT): # 随机生成位置,确保形状完全在屏幕内 x = random.randint(0, SCREEN_WIDTH - SHAPE_SIZE) y = random.randint(0, SCREEN_HEIGHT - SHAPE_SIZE) # 随机分配颜色 color = random.choice(COLORS) new_shapes.append(pygame.Rect(x, y, SHAPE_SIZE, SHAPE_SIZE)) new_shapes.append(color) # 每个形状后面跟着它的颜色,成对存储 return new_shapes # 初始化生成形状 shapes = generate_shapes() run = True clock = pygame.time.Clock() FPS = 60 # 降低FPS更合理,原150过高 while run: clock.tick(FPS) current_time = pygame.time.get_ticks() # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: run = False # 15秒刷新逻辑 if current_time - last_refresh_time >= REFRESH_INTERVAL: shapes = generate_shapes() target_color = random.choice(COLORS) target_count = random.randint(1, 5) collected = 0 # 刷新后重置收集计数 last_refresh_time = current_time # 玩家移动控制 keys = pygame.key.get_pressed() if keys[pygame.K_a] and player.left > 0: player.x -= PLAYER_SPEED if keys[pygame.K_d] and player.right < SCREEN_WIDTH: player.x += PLAYER_SPEED if keys[pygame.K_w] and player.top > 0: player.y -= PLAYER_SPEED if keys[pygame.K_s] and player.bottom < SCREEN_HEIGHT: player.y += PLAYER_SPEED # 碰撞检测与收集逻辑 i = 0 while i < len(shapes): shape_rect = shapes[i] shape_color = shapes[i+1] if player.colliderect(shape_rect): # 如果是目标颜色,计数加1并移除该形状 if shape_color == target_color: collected += 1 # 移除形状和对应的颜色 del shapes[i] del shapes[i] # 收集完成后直接刷新 if collected >= target_count: shapes = generate_shapes() target_color = random.choice(COLORS) target_count = random.randint(1, 5) collected = 0 last_refresh_time = current_time else: # 非目标颜色,仅移除形状 del shapes[i] del shapes[i] else: i += 2 # 每两个元素是一组(矩形+颜色) # 绘制内容(先填充背景,再画所有元素) screen.fill(BLACK) # 绘制玩家 pygame.draw.rect(screen, WHITE, player) # 绘制所有形状 i = 0 while i < len(shapes): pygame.draw.rect(screen, shapes[i+1], shapes[i]) i += 2 # 绘制文字信息 color_name = ['红','绿','蓝'][COLORS.index(target_color)] target_text = FONT.render(f"目标: 收集 {target_count} 个 {color_name} 色形状", True, WHITE) collected_text = FONT.render(f"已收集: {collected}", True, WHITE) screen.blit(target_text, (10, 10)) screen.blit(collected_text, (10, 50)) # 更新屏幕 pygame.display.flip() pygame.quit()
代码解释
问题1:解决形状扎堆问题
原代码所有形状共用同一个初始坐标,导致完全重合。修改方案:
- 固定
SHAPE_SIZE变量确保所有形状尺寸一致 - 编写
generate_shapes()函数,循环生成10个形状,每个形状的x/y坐标通过random.randint()随机生成,范围限制在0到屏幕尺寸-形状尺寸之间,保证形状不会超出屏幕 - 用列表成对存储形状矩形和颜色,替代原代码中10个单独的形状变量,简化维护
问题2:实现15秒刷新逻辑
使用Pygame时间模块实现定时刷新:
- 定义
REFRESH_INTERVAL = 15000(15秒,单位毫秒) - 每次循环用
pygame.time.get_ticks()获取当前时间,对比last_refresh_time,当时间差达到15秒时,重新生成形状、随机新的目标颜色和收集次数,重置收集计数并更新刷新时间
问题3:添加收集计数器功能
- 新增
collected变量记录已收集数量,target_count和target_color记录当前任务要求 - 用
player.colliderect(shape_rect)进行碰撞检测(原代码用==判断矩形相等是错误逻辑) - 碰撞到目标颜色形状时,计数加1并移除该形状;收集达标后直接触发刷新
- 用Pygame字体模块渲染任务提示和收集进度,通过
screen.blit()绘制到屏幕上
其他优化点
- 将FPS降至60,减少资源占用同时保证流畅度
- 给玩家移动添加边界检测,避免移出屏幕
- 修复原代码绘制顺序错误(先填充背景再绘制元素,避免内容被覆盖)
内容的提问来源于stack exchange,提问作者CorruptedNightFall0
相关产品推荐
相关产品推荐

