I am coding a simple game and in this game you click a bubble and it pops. Well I wanted to add some more detail to it so I made 4 images for the frames and when a user clicks the bubble it does go through them just really fast. I have tried using a solution posted on here: How to slow down animation but I am still having some trouble I am new to pygame and am still learning would someone be able to help me identify where I went wrong in implementing the code?
Edit: I have made a proper example that can be tested I hope this helps better.
import pygame, random, sys, os
from pygame.locals import *
#Path to program folder
basePath = os.path.dirname(sys.argv[0]) "\\"
#Initiating pygame and the pygame mixer for audio file
pygame.init()
#setting fps lock for game and startign clock (Both are needed for fps)
fps = 30
fClock = pygame.time.Clock()
#Setting up pygame display size and window
res = pygame.display.Info()
tv = pygame.display.set_mode((res.current_w, res.current_h), pygame.FULLSCREEN)
pygame.display.set_caption("Bubble Poparoo 1.0")
#Bubble sprite class
#Bubble sprite class
class Bubble(pygame.sprite.Sprite):
def __init__(self):
#88 -Entry by my son Quintin Wargel 06:54:00 AM 07/02/22 Age 8 Months old.
#Bubble settings for setup and creation
self.radius = int((res.current_h*40)/100)
self.imFrames = [pygame.image.load(basePath "Images\\bPopF1.png").convert_alpha(),
pygame.image.load(basePath "Images\\bPopF2.png").convert_alpha(),
pygame.image.load(basePath "Images\\bPopF3.png").convert_alpha(),
pygame.image.load(basePath "Images\\bPopF4.png").convert_alpha()]
self.sImg = pygame.transform.scale(self.imFrames[0], (self.radius/2, self.radius/2))
self.rect = self.sImg.get_rect()
self.baseX = random.randint(self.radius, res.current_w)
self.way = 0
self.rect.x = self.baseX
self.rect.y = res.current_h self.radius 10
self.hide = False
self.index = 0
self.nTime = 0
self.anit = False
#Check if sprite has been clicked
def clickCheck(self, pos):
if self.rect.collidepoint(pygame.mouse.get_pos()):
#Play animation
self.anit = True
self.aGo()
def aGo(self):
if self.anit:
self.animate()
def animate(self):
tNow = pygame.time.get_ticks()
if (tNow > self.nTime):
fDelay = 40000 // 30
self.nTime = tNow fDelay
self.index = 1
print(self.index)
if self.index >= len(self.imFrames):
self.index = 0
self.anit = False
tv.blit(pygame.transform.scale(self.imFrames[self.index], (self.radius/2, self.radius/2)), (self.rect.x, self.rect.y))
def move(self):
#Placing/Moving sprite on the screen
if self.hide == False:
if self.anit == False:
tv.blit(self.sImg, (self.rect.x, self.rect.y))
else:
pass
#Bubble movment
self.rect.y -=3
if self.rect.x == self.baseX 20:
self.way = 1
elif self.rect.x == self.baseX-20:
self.way = 0
else:
pass
if self.way == 0:
self.rect.x = 1
else:
self.rect.x -= 1
#If the bubble is above the screen and out of view then resets to bottom of screen
if self.rect.y <= -self.radius-10:
self.baseX = random.randint(self.radius, res.current_w)
self.rect.x = self.baseX
self.rect.y = res.current_h self.radius 10
self.radius = random.randint(10,50)
self.hide = False
#Loop value and buuble list
go = True
sTime = 0
bList = []
#Main loop
while go:
#Reseting the background
tv.fill((0,0,0))
#event checks
for event in pygame.event.get():
if event.type == QUIT:
go = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
go = False
elif event.type == pygame.MOUSEBUTTONDOWN:
for b in bList:
b.clickCheck(event.pos)
#Every 5 seconds spawn a new bubble if there is less than 8
if pygame.time.get_ticks() > sTime:
sTime = 5000
if len(bList) < 8:
bList.append(Bubble())
#Looping through the bubble list to spawn/move them
for b in bList:
b.move()
#Update the display and fps clock.
pygame.display.update()
fClock.tick(fps)
#Closing pygame and closing all functions
pygame.quit()
sys.exit()
CodePudding user response:
The problem is that self.index
is incremented twice. Once in clickCheck
(very often) and once in animate
(delayed). Remove self.index = 1
from clickCheck
.
Your animation stops if the mouse is not on the bubble. The animation only runs once when the mouse button is clicked. Set an attribute when the mouse is on the bubble and run the animation depending on that attribute in the application loop (move
method) instead of the event loop (clickCheck
method):
class Bubble(pygame.sprite.Sprite):
def __init__(self):
# [...]
self.run_animation = False
def clickCheck(self, pos):
if self.rect.collidepoint(pygame.mouse.get_pos()):
pygame.mixer.music.play()
self.run_animation = True
def move(self):
if self.run_animation:
self.animate()
# [...]
def animate(self):
tNow = pygame.time.get_ticks()
if tNow > self.nTime:
fDelay = 4000 // 30
self.nTime = tNow fDelay
self.index = 1
if self.index >= len(self.imFrames):
self.index = 0
self.run_animation = False
self.rect.y = -self.radius-10
tv.blit(pygame.transform.scale(self.imFrames[self.index], (self.radius/2, self.radius/2)), (self.rect.x, self.rect.y))
See also How can I show explosion image when collision happens? and Spawning multiple instances of the same object concurrently in python