- on Sun 07 July 2019
Particle systems can be used to simulate "fuzzy" phenomena --- fire, water, explosions, stars etc.
I knew that I wanted to explosions in the game that I am developing so I began by developing the following simple particle system.
Setup Virtual Environment and Install libtcod
mkdir particle_system
cd ./particle_system
Create and activate virtual environment
python3 -m venv venv
source ./venv/bin/activate
Install tcod
pip3 install tcod
Download the console font.
wget https://raw.githubusercontent.com/TStand90/roguelike_tutorial_revised/master/arial10x10.png
A Simple Particle System in Python
Create a file called particle_system.py.
Put the following code into particle systems.py:
import tcod as libtcod
import random
import time
screen_width = 80
screen_height = 50
window_title = "A Particle System"
max_particle_moves = 100
particles_per_update = 2
red_lt = libtcod.Color(251,73,52) #gruvbox lt red
class Particle:
def __init__(self, x, y, vx, vy, colour):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.colour = colour
self.moves = 0
def is_dead(self):
if self.moves > max_particle_moves:
return True
else:
return False
def move(self):
self.x += self.vx
self.y += self.vy
self.moves += 1
def draw(self):
libtcod.console_set_char_background(
0,
self.x,
self.y,
self.colour,
libtcod.BKGND_SET
)
class ParticleSystem:
def __init__(self, x, y):
self.origin = x, y
self.particles = []
def update(self):
x, y = self.origin
for p in self.particles:
p.move()
if p.is_dead():
self.particles.remove(p)
def add_particles(self, number):
for i in range(0, number):
vx = random.randint(-2, 2)
vy = random.randint(-2, 2)
p = Particle(self.origin[0], self.origin[1], vx, vy, red_lt)
self.particles.append(p)
def draw(self):
for p in self.particles:
p.draw()
def main():
libtcod.console_set_custom_font(
"arial10x10.png", libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD
)
libtcod.console_init_root(
screen_width,
screen_height,
window_title,
False,
)
ps = ParticleSystem(20, 20)
while not libtcod.console_is_window_closed():
libtcod.console_clear(0)
ps.draw()
ps.update()
ps.add_particles(particles_per_update)
time.sleep(.1)
libtcod.console_flush()
key = libtcod.console_check_for_keypress()
if key.vk == libtcod.KEY_ESCAPE: break
if __name__ == "__main__":
main()
Run it
python ./particle_system.py
It is not very exciting right now but it is a base from which a more rich system might be built.