Confetti

Particles as copies of a cube rather than as quads, spawned three hundred at a time by hand instead of by the second.


    
main.lua
local natiny = require("natiny")

natiny.backend.init(arg and arg[1] or natiny.backend.AUTO)

local win = natiny.window.create("Natiny - Confetti", 960, 640)
natiny.window.set_scale_mode(win, natiny.window.SCALE_MODE_STRETCH)

local BG = natiny.color.from_hex("#151E2C")

local platform = natiny.resource.load("common/models/platform.glb")
natiny.model.create(natiny.mesh.load(platform))
natiny.resource.destroy(platform)

local BURST = 300

-- Every particle is a copy of one small cube, turning about an axis of its
-- own.  Nothing is emitted by the second: the rate is zero and each burst is
-- asked for by hand.
local confetti = natiny.particles.create(900)
natiny.particles.set_mesh(confetti, natiny.mesh.cube(1))
natiny.particles.set_rate(confetti, 0)
natiny.particles.set_shape(confetti, natiny.particles.SHAPE_SPHERE, 0.12)
natiny.particles.set_speed(confetti, 2.0, 4.5)
natiny.particles.set_lifetime(confetti, 1.6, 2.6)
natiny.particles.set_size(confetti, 0.04, 0.09)
natiny.particles.set_sizes(confetti, { 1, 1, 0 })
natiny.particles.set_spin(confetti, 180, 720)
natiny.particles.set_gravity(confetti, 0, -4.5, 0)
natiny.particles.set_damping(confetti, 0.8)
natiny.particles.set_color(confetti,
                           natiny.color.from_hex("#E9FF7AFF"),
                           natiny.color.from_hex("#5AD2FFFF"))

local camera = natiny.camera.create()
natiny.entity.set_position(camera, natiny.entity.SPACE_WORLD, 0, 1.4, 3.4)
natiny.entity.look_at(camera, 0, 0.8, 0)
natiny.camera.set_fov(camera, 50.0)
natiny.camera.set_clip(camera, 0.1, 100.0)

local time = 2.0

natiny.backend.loop(function(dt)
    time = time + dt

    if time >= 2.0 or natiny.input.get_key_pressed(natiny.input.KEY_SPACE) then
        time = 0
        -- A burst comes out of wherever the emitter stands at that moment.
        natiny.entity.set_position(confetti, natiny.entity.SPACE_WORLD,
                                   (math.random() - 0.5) * 1.6, 1.1,
                                   (math.random() - 0.5) * 1.6)
        natiny.particles.emit(confetti, BURST)
    end

    natiny.window.bind(win, function()
        natiny.render.clear(BG)
        natiny.camera.bind(camera, function()
            natiny.render.tag("model")
            natiny.render.tag("particles")
        end)
    end)
end)

natiny.backend.shutdown()