So I want to make a sound effect that only plays when a direction is pushed, and the trouble that I'm running into is that:
- using (btn(input)) loops the sound so fast it almost crashes PICO-8
- using (btnp(input)) only plays it when the button is first pressed
How do I make it so it plays consistently while pressing a direction, and loops at a normal speed? I tried making a timer that gets added to while a direction is pushed, but the only way I could find to do it was i+=1 which only added 1 a single time. Is a timer the right way to go or is there a more efficient way?
function move_player() newx=p.x newy=p.y if (btn(⬅️)) then newx-=.1 p.sprite=d.left sfx(0) elseif (btn(➡️)) then newx+=.1 p.sprite=d.right sfx(0) elseif (btn(⬆️)) then newy-=.1 p.sprite=d.up sfx(0) elseif (btn(⬇️)) then newy+=.1 p.sprite=d.down sfx(0) end
Here's a snippet of my code if it helps. Thanks!
'sfx' and 'music' are functions to start playing something right now. If you call 'btn' from '_update', then 30 times per second the condition will be true, and the sound effect will be restarted. For music, a common technique is to use a flag (a variable that can be true or false), so that the code inside 'then' does not call 'music' directly but just sets the flag to true, then other code in '_udpate' can call 'music' if the flag is true and music isn’t already playing. For an sfx, I don’t know if that technique is suitable: sfx don’t loop so you would need a timer in addition to the flag. Idea 1: make a looping music track with your sfx and use the technique I described. Idea 2: use 'stat' to check if sound is already playing and call 'sfx' only if not: https://pico-8.fandom.com/wiki/Stat#.7B16.E2.80.A626.7D_Sound_and_music_status
(Cosmetic note about your code: you should dedent at else/elseif/end, so that blocks are easy to see. Helps for changing code later and for spotting mistakes like forgotten 'end'!)
Rather than tying it to inputs, it'd be a generally better idea to tie it to the visuals. For example, if you have the character walking, then playing a footstep sound when the sprite changes which foot is on the ground would work.
If the character that the sound is for doesn't have any visible source for the sound, or if the sound is constant (like a robot's motor), then I suggest giving the character a variable that keeps track of the time that has passed since the sound was played. That way the movement can just determine whether the sound should be playing while said variable determines whether it needs to be triggered again.
function checksfx() local i=stat(16) if i>-1 then elseif (btn(0)) then sfx(0) elseif (btn(1)) then sfx(0) elseif (btn(2)) then sfx(0) elseif (btn(3)) then sfx(0) end end
Which works great for my purpose. It's a little tough to sync the walk animation to the sound, but I think it works okay.
[Please log in to post a comment]