Friday, 8 October 2021

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

I am having difficulty comparing two collisions that take place on different backgrounds. ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎

I am attempting to make a "memory" game in Pygame. Basically, you have to hit a balloon(s) on the first background, and then hit the same balloon(s) on the second background. If you hit the same balloon(s), you get 1 point added to your score, if you don't, some text - "you lost!"(Calls a function to display text) should appear and the game should end. The number of balloons hit also gets updated after each iteration - First you hit 1 balloon(on first background), then 1(on second background), then 2(on first background), then 2(on second background) and so on, until you hit all 7 balloons. You can refer to here if you're still confused. Essentially, I am trying to compare if the balloons hit on the first background were the same on the second background. You can refer to here.

I made a list for each background, that appends the balloons that were hit each time. Then, I am comparing the 2 lists (scene_1_balloons_popped, and scene_2_balloons_popped), to see if the contents were the same. My problem is that if I am hitting different balloons on the first background, it is displaying the "you lost!" text, and I don't understand why.

The "you lost!" text can only show up on the second background if you don't hit the same balloons as the previous background. You can hit different balloons on the first background, as long as you hit the same balloons on the second.

This takes place in my game loop

        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 = []
 

Essentially, I am checking if the length of the two lists are the same. By the way, the collisions itself are detected correctly.

Here is my full program - pay attention to the check_collisions function and the game loop (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()
    

You can download the images here: See images on REPL


Here are some examples of what should happen:

Scenario 1: If I first hit a red balloon and it goes to the next background, I should hit the red balloon again. If I do that correctly, I get 1 point. I am now back on the first background and I have two hits. I hit the orange balloon, then the blue balloon, and the background changes. Now, on the second screen, I hit the orange balloon and then the red balloon. The "you lost" text shows up because I didn't hit the same balloons as before.

Scenario 2: I hit the blue balloon first, then the blue balloon again on the next background. I get 1 point. Then on the first background again, I hit the red balloon, then the green balloon. On the next background I hit the red balloon and the green balloon again. My score goes up 1 again. I keep on hitting the same balloons as before. My final score is 7.

Scenario 3: I hit the blue balloon, then the red balloon. The "you lost" text shows up. I play again, this time I hit the red balloon, then the red balloon again. Then I hit the red balloon and the orange balloon on the first background, and on the second background I hit the blue balloon instead of the red balloon. The game ends(The "you lost" text is shown).


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



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

No comments:

Post a Comment