【问题标题】:Check if collisions detected on one background were the same collisions on the second background检查在一个背景上检测到的碰撞是否与第二个背景上的相同碰撞
【发布时间】:2021-11-25 07:48:53
【问题描述】:

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

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

我为每个背景制作了一个列表,其中附加了每次击中的气球。然后,我比较两个列表(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:我撞到蓝色气球,然后撞到红色气球。 “你输了”的文字出现了。我又玩了一次,这次我打红气球,然后又打红气球。然后我在第一个背景上击中了红色气球和橙色气球,在第二个背景上我击中了蓝色气球而不是红色气球。游戏结束(显示“你输了”)。


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

【问题讨论】:

    标签: python list pygame collision


    【解决方案1】:

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

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

    在更改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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      • 2019-04-30
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多