Last active
March 16, 2025 11:12
-
-
Save Achie72/ab7d86dc57e7a6d51fd56d0dcb5f2041 to your computer and use it in GitHub Desktop.
PICO-8 Particles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- inside init have a collection called particles | |
-- this is where we will store each an every particles, so we can iterate | |
-- over them in the future (aka process them one by one) | |
particles = {} | |
-- adder function, you call this anytime you want to add a new particle | |
-- to the system. This will help us centralise every modification as this | |
-- function is the only thing that you will have to modifiy. | |
function add_particle(_x, _y, _sx, _sy, _lifetime, _color, _type) | |
-- create a local temporary particle where we create the data | |
-- into this object. This is great because in the future you can access | |
-- any, so called member variables inside it | |
local part = { | |
x = _x, -- where it spawns on the x axis (horizontally) | |
y = _y, -- where i t spans on the y axis (vertically) | |
sx = _sx, --speed for the particle if they move around | |
sy = _sy, -- same but y direction | |
lifetime = _lifetime, -- how long it should live | |
color = _color, -- color to draw | |
type = _type -- type of it | |
} | |
-- for now type can be 1, and 2, 1 for pixels, 2 for exploding circles! | |
-- add the particle to our particle array | |
add(particles, part) | |
end | |
-- in update somewhere now we can | |
-- update all particles. Just call this function. We are yet again | |
-- movign this into a function so you can call it anywhere without having | |
-- to duplicate all the code inside. | |
function update_particles() | |
-- for xyz in all(table) do is basically a simple for cycle. It will take | |
-- everything in the table and place it into xyz one by one. If this sounds complicated | |
-- think of it as: | |
-- for i=1,#particles do | |
-- local particle = particles[i] | |
-- somecodeyouwant | |
-- end | |
-- they are basically the same | |
for particle in all(particles) do | |
-- now you can use particle as a name to access member variables and | |
-- use them how you like. | |
particle.x += particle.sx -- move the x direction by the speed | |
particle.y += particle.sy -- move the y direction by the speed | |
particle.lifetime -= 1 -- decrement by 1 each frame | |
-- if lifetime is over delete particle | |
if particle.lifetime <= 0 then | |
del(particles, particle) | |
end | |
--particle.color = flr(rnd(15))+1 -- this gonna generate a color between 1 and 15 | |
-- if particle.type == 1 then | |
-- particle type 1 do something else | |
-- end | |
-- here for example you can have a type 1 that is just explosion clouds | |
-- filled in circles | |
-- and type 2, which is a shockwave, which is growing faster | |
end | |
end | |
-- in draw now you can call a function that will draw our particles | |
function draw_particles() | |
for part in all(particles) do | |
--pset(part.x, part.y, part.color) | |
-- part.type = 1 would be a pixel particle | |
if part.type == 1 then | |
pset(part.x, part.y, part.color) | |
-- part.type = 2 are circles | |
elseif part.type == 2 then | |
circfill(part.x, part.y, 3, part.color) | |
end | |
-- how can you draw different things over time? | |
-- calculating with lifetime is the easiest, | |
-- for expanding stuff you want to increase the size | |
-- so for example let's have a 10/lifetime for example, where | |
-- tweaking 10 is where you can dial in the maximum size. | |
-- here you divide 10 with a smaller and smaller number due to how | |
-- lifetime is decreasing over time | |
-- circfill(part.x, part.y, 10/part.lifetime, part.colo) | |
end | |
end | |
-- with this setup all you have to do is call the add_particle function | |
-- whenever you want to create some particles. | |
-- lets's say we have a player with x and y coordinates | |
player = { | |
x = 10, | |
y = 10 | |
} | |
-- players will ahve a trail after them whenever they move | |
function _update() | |
-- move the player | |
if btn(0) then | |
player.x -= 1 | |
end | |
if btn(1) then | |
player.x += 1 | |
end | |
if btn(2) then | |
player.y -= 1 | |
end | |
if btn(3) then | |
player.y += 1 | |
end | |
-- now let's add a particle | |
-- we are not gonna move that particle, so sx, sy will be zero | |
-- let them live for 30 frames (1 second) and be white (color 7) | |
-- for now type doesn't matter as we ahven't added a code for it | |
-- add_particle(_x, _y, _sx, _sy, _lifetime, _color, _type) | |
add_particle(player.x, player.y, 0, 0, 30, 7, 1) | |
-- now let's call our particle update function | |
-- just to show, let's add some kind of explosion! | |
if btnp(4) then | |
-- add more particles, it is an explosion | |
for i=1,5 do | |
-- in an explosion not every cloud is moving | |
-- in the same direction so let's randomize that | |
-- we will use a random combination, that will | |
-- create us a random number between {-1,1} | |
-- first let's create one that is the number | |
-- random_speed = rnd(), this will be a number between 0,1 | |
-- now let's give it a direction | |
-- dir = rnd({-1,1}, here we use rnd to grab a random element from the table | |
-- which is either 1, or -1. IF we multiply these two we get a random number | |
-- between {-1,1} | |
local speed_x = rnd()*rnd({-1,1}) | |
local speed_y = rnd()*rnd({-1,1}) | |
-- 30 is lifetime, 8 is color, 2 is type | |
add_particle(player.x, player.y, speed_x, speed_y, 30, 8, 2) | |
end | |
end | |
update_particles() | |
end | |
function _draw() | |
--clear screen | |
cls() | |
-- draw our particles | |
draw_particles() | |
-- draw bright green player | |
print("😐", player.x, player.y, 11) | |
end |
If you would like to read more like this, feel free to checkout my Ko-fi articles, with many devlogs and code rundowns like this!
https://github.com/Achie72/kofi-articles
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
More PICO-8 Tutorials: https://github.com/Achie72/kofi-articles/blob/main/README.md#pico-8-tutorials