检查在一个背景上检测到的碰撞是否与在第二个背景上检测到的碰撞相同

Check if collisions detected on one background were the same collisions on the second background

我很难比较发生在不同背景下的两次碰撞。 〗 〗

我正在尝试在 Pygame 中制作一个“记忆”游戏。基本上,您必须在第一个背景上击中一个气球,然后在第二个背景上击中相同的气球。如果您击中了相同的气球,您的分数会增加 1 分,如果您没有击中,则会出现一些文本 - “你输了!”(调用一个函数来显示文本)并且游戏应该结束。每次迭代后击中气球的数量也会更新 - 首先你击中 1 个气球(在第一个背景上),然后 1 个(在第二个背景上),然后 2 个(在第一个背景上),然后 2 个(在第二个背景上)等等,直到你击中所有 7 个气球。如果您仍然感到困惑,可以参考。本质上,我试图比较在第一个背景上击中的气球在第二个背景上是否相同。可以参考这里

我为每个背景制作了一个列表,其中附加了每次被击中的气球。然后,我比较 2 个列表(scene_1_balloons_poppedscene_2_balloons_popped),看看内容是否相同。 我的问题是,如果我在第一个背景上击中不同的气球,它会显示“你输了!”文字,我不明白为什么。

《你输了!如果您没有点击与前一个背景相同的气球,文本只能显示在第二个背景上。您可以在第一个背景上击中不同的气球,只要您在第二个背景上击中相同的气球即可。

这发生在我的游戏循环中

        for b in range(min(len(scene_1_balloons_popped), len(scene_2_balloons_popped))):
            if scene_1_balloons_popped[b] != scene_2_balloons_popped[b]:
                number_incorrect += 1
        if number_incorrect > 0:
            number_incorrect = 0
            you_lost()
        elif len(scene_1_balloons_popped) == len(scene_2_balloons_popped):
            score += 1
            scene_1_balloons_popped = []
            scene_2_balloons_popped = []
 

本质上,我是在检查两个列表的长度是否相同。 顺便说一句,碰撞本身检测正确。

这是我的完整程序 - 注意 check_collisions 函数和游戏循环 (while running:).

import pygame
import random as r
import sys


pg.init()

myfont = pg.font.SysFont('arial black', 30)

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
num_hits = 0
iterator = -1

num_balloon_list = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7]
balloon_list_index = 0
scene_1_balloons_popped = []
scene_2_balloons_popped = []
number_of_balloons_popped = 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, hit, score, scoretext, bg_bool
    global num_balloon_list, balloon_list_index, num_hits
    global num_balloons, new_hit_var
    global balloon_hit, game_over, number_of_balloons_popped 
    
    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
            num_balloons -= 1
            num_hits += 1
            number_of_balloons_popped += 1
            num_hits_needed = num_balloon_list[balloon_list_index]
            game_end = balloon_list_index == len(num_balloon_list) - 1
            if num_hits == num_hits_needed and not game_end:
                num_balloons += num_hits
                num_hits = 0
                balloon_list_index += 1
                bg_bool = not bg_bool
            if bg_bool == True:
                scene_1_balloons_popped.append(i)
            elif bg_bool == False:
                scene_2_balloons_popped.append(i)
                
            break

            


            
def you_lost():
    youlost = myfont.render("YOU LOST!", 1, (0,0,0))
    message = myfont.render("Improve your memory", 1, (0,0,0))
    screen.blit(youlost, (300, 300))
    screen.blit(message, (300, 500))

        
# 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 #

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)
    scoretext = myfont.render("SCORE: "+str(score), 1, (0,0,0))
    if bg_bool == False:
        screen.blit(bg, (0, 0))
        screen.blit(scoretext, (5, 10))

      
    elif bg_bool == True:
        screen.blit(new_bg, (0,0))
        screen.blit(scoretext, (5, 10))

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

    if len(scene_1_balloons_popped) > 0 and len(scene_2_balloons_popped) > 0:
        for b in range(min(len(scene_1_balloons_popped), len(scene_2_balloons_popped))):
            if scene_1_balloons_popped[b] != scene_2_balloons_popped[b]:
                you_lost()
            else:
                score += 1
                   
    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:
                bullets_colors()
                make_bullets() 
                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()
    

您可以在这里下载图片:See images on REPL


这里有一些应该发生的例子:

场景一:如果我先打了一个红气球,它进入了下一个背景,我应该再打一次红气球。如果我做对了,我得到 1 分。我现在回到第一个背景,我有两个点击。我点击了橙色气球,然后是蓝色气球,然后背景发生了变化。现在,在第二个屏幕上,我点击了橙色气球,然后是红色气球。出现“你输了”的文字是因为我没有像以前那样打同样的气球。

场景2:我先打了蓝气球,然后在下一个背景又打了蓝气球。我得到1分。然后再次在第一个背景上,我点击了红色气球,然后是绿色气球。在下一个背景中,我再次击中了红色气球和绿色气球。我的分数又涨了1。我继续像以前一样击打相同的气球。我的最终分数是 7.

场景3:我先打蓝气球,再打红气球。出现“你输了”的文字。我又玩了一次,这次我击中了红气球,然后又是红气球。然后我在第一个背景上击中了红色气球和橙色气球,在第二个背景上我击中了蓝色气球而不是红色气球。游戏结束(显示“你输了”的文字)。


如何正确检查两个附加了碰撞的列表,以查看是否在两个背景上都击中了相同的气球?

How can I properly check between two lists appended with collisions to see if the same balloon(s) was hit on both backgrounds?

您将每次背景更改前被击中的气球附加到错误的列表中。

在更改 bg_bool 之前基于 bg_bool 添加到 balloons_popped

if gun_mask.overlap(balloon_mask, offset):
    hit = True
    # Append to balloons_popped based on bg_bool...
    if bg_bool == False:                   # Add this
        scene_1_balloons_popped.append(i)  # Add this
    elif bg_bool == True:                  # Add this
        scene_2_balloons_popped.append(i)  # Add this
    # ...and then change bg_bool if reached num_hits_needed
    num_balloons -= 1
    num_hits += 1
    number_of_balloons_popped += 1
    num_hits_needed = num_balloon_list[balloon_list_index]
    game_end = balloon_list_index == len(num_balloon_list) - 1
    if num_hits == num_hits_needed and not game_end:
        num_balloons += num_hits
        num_hits = 0
        balloon_list_index += 1
        bg_bool = not bg_bool
    # if bg_bool == True:                    # Remove this
    #     scene_1_balloons_popped.append(i)  # Remove this
    # elif bg_bool == False:                 # Remove this
    #     scene_2_balloons_popped.append(i)  # Remove this

修复分数增量

首先需要一个全局变量来追踪玩家是否输了

running = True
lost = False  # Add this

命中时,判断玩家是否输了,增加分数。

然后,根据全局变量(跨帧)显示“你输了”文本。

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

    # Notice that the following block has been indented into `if hit == True`
    if len(scene_1_balloons_popped) > 0 and len(scene_2_balloons_popped) > 0:
        for b in range(min(len(scene_1_balloons_popped), len(scene_2_balloons_popped))):
            if scene_1_balloons_popped[b] != scene_2_balloons_popped[b]:
                # you_lost()  # Replace this
                lost = True   # with this
                break         #
            # else:                                                                    # Replace this
            #     score += 1                                                           #
        if not lost and len(scene_1_balloons_popped) == len(scene_2_balloons_popped):  # with this
            score += 1                                                                 #

if lost:        # Add this
    you_lost()  # Add this