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

Pygame开发求助:生成随机变色形状、添加计数器及设置分散生成点

Pygame形状收集游戏解决方案

问题背景

我正在开发一款Pygame游戏,核心需求如下:

  • 玩家需要收集指定颜色的形状,收集次数随机(1-5次)
  • 屏幕上固定生成10个形状,每15秒刷新一次(旧形状消失,生成新形状)

当前遇到的问题:

  1. 生成的形状全部扎堆在一起,不知道怎么设置不同生成位置且不改变形状尺寸
  2. 不知道如何实现每15秒自动切换目标颜色并刷新形状
  3. 需要添加收集进度的计数器功能

原代码如下:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:17:33