Adding a Particle Effect to My Clicker Game

Adding a particle effect to my clicker game

See How to make image stay on screen in pygame?.

Use pygame.time.get_ticks() to return the number of milliseconds since pygame.init() was called. When the coin is clicked, calculate the point in time after that the text image has to be removed. Add random coordinates and the time to the head of a list:

current_time = pygame.time.get_ticks()
for event in pygame.event.get():
# [...]

if event.type == pygame.MOUSEBUTTONDOWN:
if coin_rect.collidepoint(event.pos):
pos = ... # random position
end_time = current_time + 1000 # 1000 milliseconds == 1 scond
text_pos_and_time.insert(0, (pos, end_time))

Draw the text(s) in the main application loop. Remove the text when the time has expired from the tail of the list:

for i in range(len(text_pos_and_time)):
pos, text_end_time = text_pos_and_time[i]
if text_end_time > current_time:
window.blit(text, text.get_rect(center = pos))
else:
del text_pos_and_time[i:]
break

Minimal example:

Sample Image

import pygame
import random

pygame.init()
window = pygame.display.set_mode((400, 400))
font = pygame.font.SysFont(None, 40)
clock = pygame.time.Clock()

coin = pygame.Surface((160, 160), pygame.SRCALPHA)
pygame.draw.circle(coin, (255, 255, 0), (80, 80), 80, 10)
pygame.draw.circle(coin, (128, 128, 0), (80, 80), 75)
cointext = pygame.font.SysFont(None, 80).render("10", True, (255, 255, 0))
coin.blit(cointext, cointext.get_rect(center = coin.get_rect().center))
coin_rect = coin.get_rect(center = window.get_rect().center)

text = font.render("+10", True, (0, 255, 0))
text_pos_and_time = []

run = True
while run:
clock.tick(60)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if coin_rect.collidepoint(event.pos):
pos = pygame.math.Vector2(coin_rect.center) + pygame.math.Vector2(105, 0).rotate(random.randrange(360))
text_pos_and_time.insert(0, ((round(pos.x), round(pos.y)), current_time + 1000))

window.fill(0)
window.blit(coin, coin_rect)
for i in range(len(text_pos_and_time)):
pos, text_end_time = text_pos_and_time[i]
if text_end_time > current_time:
window.blit(text, text.get_rect(center = pos))
else:
del text_pos_and_time[i:]
break
pygame.display.flip()

pygame.quit()
exit()

Pygame particle effects

I have made some major edits to your code. For starters, I cleaned up your class a great deal. Let's start with the arguments and the __init__ function.

First of all, instead of going down 500 to reset, particles go to the location that was set as their starting point. It's location that it starts out in is now chosen randomly in the __init__ function rather than in the game. I got rid of some of your unnecessary arguments as well.

In the move function of your class, I simplified quite a bit. In order for the particle to detect if it should reset, it simply sees if it's above 0. The going up is just a simple decrease of the y by 1. A change I added in is that the x changes randomly and goes to the right and left. This will make the smoke look a lot better / more realistic.

I didn't make many changes to the rest of your code. I changed your calling of the Particle class to fit the new arguments. I made a ton more particles, once again for visual effect. I also massively decreased the size of the circles drawn for (can you guess it?) visual effect. I added in a clock as well to keep the particles from going at supersonic speed.

Here is the final code. I hope you like it.

import pygame,random
from pygame.locals import *

xmax = 1000 #width of window
ymax = 600 #height of window

class Particle():
def __init__(self, startx, starty, col):
self.x = startx
self.y = random.randint(0, starty)
self.col = col
self.sx = startx
self.sy = starty

def move(self):
if self.y < 0:
self.x=self.sx
self.y=self.sy

else:
self.y-=1

self.x+=random.randint(-2, 2)

def main():
pygame.init()
screen = pygame.display.set_mode((xmax,ymax))
white = (255, 255, 255)
black = (0,0,0)
grey = (128,128,128)

clock=pygame.time.Clock()

particles = []
for part in range(300):
if part % 2 > 0: col = black
else: col = grey
particles.append( Particle(515, 500, col) )

exitflag = False
while not exitflag:
for event in pygame.event.get():
if event.type == QUIT:
exitflag = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
exitflag = True

screen.fill(white)
for p in particles:
p.move()
pygame.draw.circle(screen, p.col, (p.x, p.y), 2)

pygame.display.flip()
clock.tick(50)
pygame.quit()

if __name__ == "__main__":
main()

update

In order to add particles into your code, just do what you did in the code above. It works fine. If you wanted to do something to show the smoke starting, just put a pause time into your arguments and inhibit the movement of the smoke until that amount of time has passed. New class with that added in:

class Particle():
def __init__(self, startx, starty, col, pause):
self.x = startx
self.y = starty
self.col = col
self.sx = startx
self.sy = starty
self.pause = pause

def move(self):
if self.pause==0:
if self.y < 0:
self.x=self.sx
self.y=self.sy

else:
self.y-=1

self.x+=random.randint(-2, 2)

else:
self.pause-=1

The code you will need to create new particles:

for part in range(1, A):
if part % 2 > 0: col = black
else: col = grey
particles.append( Particle(515, B, col, round(B*part/A)) )

A and B are variables (I reccomend around 300 for A, B will be the Y value)

The new code will make particles spawn at the start location, and rise continously with no breaks. Hope you enjoy.

libgdx - trail effect with particle effect or animation

The easiest way to do this is using particle effects. it's hard to give more information since every particle effect is rather specific to its' game's needs.

I suggest you take a look at the wiki. Also, take a look at this helpful video. It has a basic usage of the particle effect editor, as well as the usage of ParticleEffect objects in libgdx code.

pygame - particle effects

You might want to just make a class made of rects that go up and randomly go to the right or left each time it is updated for the smoke. Then make a ton of them whenever you want it. I'll try to make an example code below, but I can't guarntee it will work. You can make similar classes for the other particle effects.

class classsmoke(pygame.Rect):
'classsmoke(location)'
def __init__(self, location):
self.width=1
self.height=1
self.center=location
def update(self):
self.centery-=3#You might want to increase or decrease this
self.centerx+=random.randint(-2, 2)#You might want to raise or lower this as well

#use this to create smoke
smoke=[]
for i in range(20):
smoke.append(classsmoke(insert location here))
#put this somewhere within your game loop
for i in smoke:
i.update()
if i.centery<0:
smoke.remove(i)
else:
pygame.draw.rect(screen, GREY, i)

Another option would be to make the class just a tuple, like this:

class classsmoke():
'classsmoke(location)'
def __init__(self, location):
self.center=location
def update(self):
self.center[1]-=3
self.center[0]+=random.randint(-2, 2)

#to create smoke
smoke=[]
for i in range(20):
smoke.append(classsmoke(insert location here))
#put inside game loop
for i in smoke:
i.update()
if i.centery<0:
smoke.remove(i)
else:
pygame.draw.rect(screen, GREY, (i.center[0], i.center[1], 1, 1))

Or, to avoid classes completly:

#to create smoke:
smoke=[]
for i in range(20):
smoke.append(insert location here)
#put within your game loop
for i in smoke:
i[1]-=3
i[0]+=random.randint(-2, 2)
if i[1]<0:
smoke.remove(i)
else:
pygame.draw.rect(screen, GREY, (i[0], i[1], 1, 1))

Pick your preference, and do something similar for other particle effects.

Memory Game in Pygame

Change the method hide tiles. Don't hide the tiles, but compute the time when the tile has to be hidden. Use pygame.time.get_ticks() to return the number of milliseconds since pygame.init() was called. Calculate the point in time after that the image has to be hidden. Add a method that evaluates if the time has exceeded and the tile has to be hidden

class Tile:
def __init__(self):
self.hide_time = None

# [...]

def hide_tile(self):
self.hide_time = pygame.time.get_ticks() + 1000 # 1000 milliseconds == 1 second

def hide_timed(self):
if self.hide_time != None and self.hide_time < pygame.time.get_ticks()
self.covered = True
self.hide_time = None

Add a method to Game that evaluate whether the tiles need to be hidden:

class Game:
# [...]

def hide_timed(self):
for row in self.board:
for tile in row:
tile.hide_timed()

Call hide_timed in the application loop in every frame.



Related Topics



Leave a reply



Submit