JITTU VARGHESE
JITTU VARGHESE

Reputation: 543

Value Is being counted more than intended in Pygame

Ballon pic
Ballon pic

In this code the problem lies in the Check_Health(). Whenever I run the game it reduces the lives to extremely low numbers which is not intended. I only want each balloon to reduce my lives by one when they exit the screen. Specifically in the first wave lives should be reduced to 95, but when the program is run, it reduces to -405. Anyone know why?

import pygame
import sys
import os
import random
import time

pygame.init()
WIDTH, HEIGHT = 800,600
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()
bg_music = []
#for r,d,f in os.walk("Music"):
    #bg_music.append(f)
i = 0
Lives = 100
balloon_sprite = pygame.image.load("Logo.png")
rounds = [[5,50], [6,40], [8,40], [15,30], [15,20]]
FPS = 60
a3 = True
a1 = a2= False
bloons = []

'''def music_play():
    global i
    if not(pygame.mixer.music.get_busy()):
        pygame.mixer.music.load('Music/'+bg_music[0][i])
        pygame.mixer.music.play()
        i = random.randint(0,len(bg_music)-1)'''

class Button:
    def __init__(self, x_center, y_center, text, size, text_col, bg_col):
        self.x = x_center
        self.y = y_center
        self.size = size
        self.text_col = text_col
        self.bg_col = bg_col
        self.hit = False
        font = pygame.font.Font('freesansbold.ttf', self.size)
        self.text = font.render(text, True, self.text_col, self.bg_col)
        self.textRect = self.text.get_rect()
        self.textRect.center = (self.x, self.y)
        win.blit(self.text, self.textRect)

    def Check_Collision(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            pos_mouse = event.pos
            if self.textRect.collidepoint(pos_mouse):
                self.hit = True
                
    def Start(self):
        global run1
        if (self.hit):
            run1 = False

    def Quit(self):
        if (self.hit):
            sys.exit()

    def fast_forward(self):
        global a1,a2,a3, FPS
        if(self.hit):
            if a1:
                FPS = 120
                a1=a3 = False
                a2 = True
            elif a2:
                FPS = 240
                a3 = True
                a1 = a2 = False
            elif a3:
                FPS = 60
                a1 = True
                a2 = a3 = False



class Balloon:
    def __init__(self, x,y,health, dests, speed):
        self.health = health
        self.dests = dests
        self.x = x
        self.y = y
        self.count = 0
        self.speed = speed
    def draw_Balloon(self):
        global balloon_sprite
        win.blit(balloon_sprite, pygame.Rect((self.x, self.y), (balloon_sprite.get_width(), balloon_sprite.get_height())))
        if not(self.count==len(self.dests)):
            if self.x == self.dests[self.count][0]:
                if self.y== self.dests[self.count][1]:
                    self.count+=1
                else:
                    if self.y< self.dests[self.count][1]:
                        self.y+=self.speed
                    else:
                        self.y-=self.speed
            else:
                if self.x< self.dests[self.count][0]:
                    self.x+=self.speed
                else:
                    self.x-=self.speed

    def Check_Health(self, pos):
        global Lives
        if self.x == pos[0]:
            if self.y == pos[1]:
                Lives-= self.health

def Main():
    def Check_Close(event):
        if event.type == pygame.QUIT:
            sys.exit()

    global run1
    running = True
    run1 = run2 = True
    while running:
        while run1:
            start_bt = Button(WIDTH//2, HEIGHT//2, "Start", 32, (255,255,0), (0,0,0))
            quit_bt = Button(WIDTH-25, HEIGHT-25, "QUIT", 16, (255,255,0), (0,0,0))
            clock.tick(FPS)

            for event in pygame.event.get():
                Check_Close(event)
                start_bt.Check_Collision(event)
                start_bt.Start()
                quit_bt.Check_Collision(event)
                quit_bt.Quit()
            pygame.display.update()
            #music_play()

        win.fill((255,255,255))
        while run2:
            for j in rounds:
                bloons = []
                for i in range(j[0]):
                        bloons.append(Balloon(0,(-(j[1])*i) ,1, ([0,50], [528,50], [528,500], [150,500], [150,300], [700,300], [700,-100]), 1))
                while run2:
                    win.fill((0,0,0))
                    clock.tick(FPS)
                    for bloon in bloons:
                        bloon.draw_Balloon()
                        bloon.Check_Health([700,-100])
                    Fast_For_bt = Button(WIDTH-25, HEIGHT-25, "[>>]", 16, (255,255,0), (0,0,0))
                    Lives_lb = Button(WIDTH//2, HEIGHT-25, f"Lives : {Lives}", 16, (255,255,0), (0,0,0))
                    for event in pygame.event.get():
                        Check_Close(event)
                        Fast_For_bt.Check_Collision(event)
                        Fast_For_bt.fast_forward()
                    #music_play()
                    pygame.display.update()
                    if ((bloons[-1].x == 700) and (bloons[-1].y ==-100)):
                        break

Main()
 

Upvotes: 1

Views: 35

Answers (1)

Rabbid76
Rabbid76

Reputation: 210968

The issue is caused because Lives is decremented every time the condition is fulfilled. If the condition is met in successive frames, Lives is decremented once per frame. You have to avoid decrementing Lives several times in a row.
When the Lives is decremented, set a state (self.hit). Don't decrement Lives when self.hit is set. Reset self.hit when the condition is no longer met:

class Balloon:
    def __init__(self, x,y,health, dests, speed):
        # [...]

        self.hit = False

    def Check_Health(self, pos):
        global Lives
        if self.x == pos[0] and self.y == pos[1]:
            if not self.hit:
                Lives -= self.health
            self.hit = True
        else:
            self.hit = False

Upvotes: 1

Related Questions