Pygame如何在达到指定气球碰撞次数后按规则切换背景
问题原因
你原有代码的背景切换逻辑存在错误:每次命中气球时会遍历整个num_balloon_list,每遍历一个元素就切换一次背景,所以命中1次就会触发多次背景切换,和你要的累计命中指定次数再切换的逻辑完全不符。
修改方案
你需要新增变量记录当前背景下的累计命中次数,每次命中后判断是否达到当前阶段要求的次数,达到后再切换背景、切换到下一阶段的要求次数。
需要修改的部分如下:
- 新增全局变量、初始化字体
在变量定义区域新增current_hits变量,同时补全字体初始化代码(你原有代码未初始化myfont会触发报错):
# 原有变量定义后新增: current_hits = 0 # 补全字体初始化 myfont = pg.font.SysFont(None, 32) scoretext = myfont.render("SCORE: " + str(score), 1, (0, 0, 0))
- 替换
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
- 修正分数显示逻辑
原有代码只有在第二个背景下才显示分数,如果需要两个背景都显示分数,修改主循环里的背景绘制逻辑:
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
相关产品推荐
相关产品推荐

