Log In  

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!

P#98842 2021-10-19 01:09

:: merwok

'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'!)

P#98844 2021-10-19 01:25

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.

P#98850 2021-10-19 05:28

@merwok @kimiyoribaka Thank you very much!
I should have specified it was for footsteps. I ended up going with

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.

P#98851 2021-10-19 05:39
:: merwok

(Your first 'elseif' should be 'if' though)

P#98860 2021-10-19 14:54

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2022-01-20 16:57:34 | 0.061s | Q:17