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

Pygame如何在达到指定气球碰撞次数后按规则切换背景

问题原因

你原有代码的背景切换逻辑存在错误:每次命中气球时会遍历整个num_balloon_list,每遍历一个元素就切换一次背景,所以命中1次就会触发多次背景切换,和你要的累计命中指定次数再切换的逻辑完全不符。

修改方案

你需要新增变量记录当前背景下的累计命中次数,每次命中后判断是否达到当前阶段要求的次数,达到后再切换背景、切换到下一阶段的要求次数。
需要修改的部分如下:

  1. 新增全局变量、初始化字体
    在变量定义区域新增current_hits变量,同时补全字体初始化代码(你原有代码未初始化myfont会触发报错):
# 原有变量定义后新增:
current_hits = 0
# 补全字体初始化
myfont = pg.font.SysFont(None, 32)
scoretext = myfont.render("SCORE: " + str(score), 1, (0, 0, 0))
  1. 替换check_collisions函数中的背景切换逻辑
    删掉原有错误的for循环遍历逻辑,替换为计数判断逻辑:
def check_collisions(x, y):
    global hit_var
    global hit
    global score
    global scoretext
    global bg_bool
    global num_balloon_list, balloon_list_index, current_hits

    for i in range(num_balloons):
        gun_rect = gun.get_rect(topleft=(x, y))
        gun_mask = pg.mask.from_surface(gun)

        balloon_rect = colors[i].get_rect(topleft=(balloon_list[i], y - 100))
        balloon_mask = pg.mask.from_surface(colors[i])

        offset = (balloon_rect.x - gun_rect.x), (balloon_rect.y - gun_rect.y)
        if gun_mask.overlap(balloon_mask, offset):
            hit = True
            # 累计当前背景的命中次数
            current_hits += 1
            # 判断是否达到当前阶段要求的命中次数
            if balloon_list_index < len(num_balloon_list) and current_hits >= num_balloon_list[balloon_list_index]:
                # 切换背景
                bg_bool = not bg_bool
                # 进入下一阶段,重置当前命中计数
                balloon_list_index += 1
                current_hits = 0
                # 所有阶段执行完后可以按需重置序列,需要的话打开注释即可
                # if balloon_list_index >= len(num_balloon_list):
                #     balloon_list_index = 0

            hit_var = i
            score += 2
            scoretext = myfont.render("SCORE: " + str(score), 1, (0, 0, 0))
            print(f'hit balloon: {i}')
            break
  1. 修正分数显示逻辑
    原有代码只有在第二个背景下才显示分数,如果需要两个背景都显示分数,修改主循环里的背景绘制逻辑:
while running:
    clock.tick(60)

    if not bg_bool:
        screen.blit(bg, (0, 0))
    else:
        screen.blit(new_bg, (0, 0))
    # 分数统一在背景绘制后渲染,所有背景都显示
    screen.blit(scoretext, (5, 10))

完整修改后代码

import pygame as pg
import random as r
import sys

pg.init()

bg = pg.image.load('bg.jpg')  # Background Image #
bg = pg.transform.scale(bg, (688, 387))
new_bg = pg.image.load('new_bg.jpg')
new_bg = pg.transform.scale(new_bg, (688, 387))

radius = 30
diameter = 2 * radius

num_balloons = 7
bullets_colors_ls = []
iterator = -1

num_balloon_list = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7]
balloon_list_index = 0
current_hits = 0

def create_balloons():
    global balloon_list
    global colors

    for i in range(num_balloons):
        while True:
            candidate = r.randint(0, 500)
            if all(abs(candidate - x) >= diameter for x in balloon_list):
                break
        balloon_list.append(candidate)


def draw_balloons(y):
    for i in range(num_balloons):
        screen.blit(colors[i], (balloon_list[i], y - 50))


def check_collisions(x, y):
    global hit_var
    global hit
    global score
    global scoretext
    global bg_bool
    global num_balloon_list, balloon_list_index, current_hits

    for i in range(num_balloons):
        gun_rect = gun.get_rect(topleft=(x, y))
        gun_mask = pg.mask.from_surface(gun)

        balloon_rect = colors[i].get_rect(topleft=(balloon_list[i], y - 100))
        balloon_mask = pg.mask.from_surface(colors[i])

        offset = (balloon_rect.x - gun_rect.x), (balloon_rect.y - gun_rect.y)
        if gun_mask.overlap(balloon_mask, offset):
            hit = True
            current_hits += 1
            if balloon_list_index < len(num_balloon_list) and current_hits >= num_balloon_list[balloon_list_index]:
                bg_bool = not bg_bool
                balloon_list_index += 1
                current_hits = 0
                # 走完序列后重置的逻辑按需打开
                # if balloon_list_index >= len(num_balloon_list):
                #     balloon_list_index = 0

            hit_var = i
            score += 2
            scoretext = myfont.render("SCORE: " + str(score), 1, (0, 0, 0))
            print(f'hit balloon: {i}')
            break


# Vars #
x = 0
y = 250
velocity = 5
score = 0
hit = False
bg_bool = False
testvar1 = True
clock = pg.time.Clock()

screen = pg.display.set_mode((688, 387))  # Size of the screen #
caption = pg.display.set_caption("Remember")  # Title of the window #
# 初始化字体
myfont = pg.font.SysFont(None, 32)
scoretext = myfont.render("SCORE: " + str(score), 1, (0, 0, 0))

balloon_list = []
b1 = pg.image.load('balloons/1.png').convert_alpha()
b1 = pg.transform.scale(b1, (63, 131))
b2 = pg.image.load('balloons/2.png').convert_alpha()
b2 = pg.transform.scale(b2, (63, 131))
b3 = pg.image.load('balloons/3.png').convert_alpha()
b3 = pg.transform.scale(b3, (63, 131))
b4 = pg.image.load('balloons/4.png').convert_alpha()
b4 = pg.transform.scale(b4, (63, 131))
b5 = pg.image.load('balloons/5.png').convert_alpha()
b5 = pg.transform.scale(b5, (63, 131))
b6 = pg.image.load('balloons/6.png').convert_alpha()
b6 = pg.transform.scale(b6, (63, 131))
b7 = pg.image.load('balloons/7.png').convert_alpha()
b7 = pg.transform.scale(b7, (63, 131))
colors = [b1, b2, b3, b4, b5, b6, b7]

gun = pg.image.load('game-gun.png').convert_alpha()
gun = pg.transform.scale(gun, (150, 150))

create_balloons()

pg.display.flip()  # Updating #

running = True  # Game loop bool #

while running:  # Game loop #
    clock.tick(60)

    if not bg_bool:
        screen.blit(bg, (0, 0))
    else:
        screen.blit(new_bg, (0, 0))
    screen.blit(scoretext, (5, 10))

    if hit == True:
        r.shuffle(balloon_list)
        hit = False

    for event in pg.event.get():
        if event.type == pg.QUIT:
            pg.quit()
            sys.exit()
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_ESCAPE:
                running = False

            if event.key == pg.K_SPACE:
                check_collisions(x, y)

    draw_balloons(y)

    keys = pg.key.get_pressed()
    x += keys[pg.K_RIGHT] - keys[pg.K_LEFT] * velocity
    x -= keys[pg.K_LEFT] - keys[pg.K_RIGHT] * velocity

    screen.blit(gun, (x, y))
    pg.display.update()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:06:03