Log In  

I was using btnp() to fire bullets (and arrow keys for movement) but noticed that no bullets would be fired when I changed directions. The documentation claims "btnp() also returns true every 4 frames after the button is held for 15 frames." but it looks like it only returns true if no other keys changed state for 15 frames. For example, if you hold down Z and press left and right alternately you won't see btnp(4) be true.

(Incidentally, the long delay before repeat made btnp() a bad choice for my game anyway, but you do see it used in sample code, e.g. the DOM8VERSE tutorial in zine 3.)

test code

function _draw()
 cls()
 for i=0,6 do
  if btn(i) then print("x",i*8,0) end
  if btnp(i) then print("x",i*8,8) end
 end
end

P#23420 2016-06-21 20:55 ( Edited 2018-05-11 19:26)

Interesting...I guess I wouldn't have used a for loop for the button captures. I mean, there's only 6 of them. Plus you should ideally put your input checks within the _update() loop rather than _draw() - which could be part of the issue.

I've done it that way and never had any issue with my controls+shooting, and all I've made so far is shooting games.

Something like this might lead you down a better path...but it's hard to give you something more detailed without going into a full thing.

x=64

function _update()
    shoot=false

    if btn(0) then x-=1 end
    if btn(1) then x+=1 end

    if btnp(4) then shoot=true end
end

function _draw()
    print(x, 0,0, 7)
    print(shoot, 0,30, 10)
end

The other way I've done it is not to use btnp() but then apply a timer to the shooting so it only happens every X number of ticks. This will get you a more consistent firing rate rather than the weird btnp() way of firing, then waiting a few then every 4.

P#23423 2016-06-21 22:01 ( Edited 2016-06-22 02:01)

Also take a look at this example

https://www.lexaloffle.com/bbs/?tid=3367

P#23432 2016-06-22 06:45 ( Edited 2016-06-22 10:45)

any buttonpress kills the repeat of other buttons for ~15 frames. also, button repeats are all synchronized. worst part is, this is true across players!
you can test this thoroughly here:

Cart #23741 | 2016-06-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
22

I think btnp() should be considered buggy and zep should revamp it.
a few ideas:

  • btnpx() which does not repeat
  • btnr() button released
  • btnp() that does repeat each button independantly
    a case could be made about synchronizing repeat for the dpad on diagonals though.
  • btnd(player, button, first_repeat_frames, further_repeat_frames)
    define your own repeating scheme (defaults 15,4 @30 and 30,8 @60)

or... kill btnp altogether. I stopped using it and made my own by polling btn every frame. but hey, tokens!

P#23820 2016-06-29 04:58 ( Edited 2016-06-29 08:58)

biannual bump

P#34991 2017-01-05 10:01 ( Edited 2017-01-05 15:01)

triannual bump!

P#52605 2018-05-11 02:34 ( Edited 2018-05-11 06:34)

Interesting read - I am also annoyed btnp repeats after 15 frames.
It's not really ... A button press function. Funny that this problem with it kinda makes it more like what it logically should do.

P#52608 2018-05-11 07:53 ( Edited 2018-05-11 11:53)
1

I write my own debouncing code because of this bug. I have multiple btn() variants:

  • btn(): true if button is currently down, bitmask with no args (default)
  • btnp(): true on the frame a button goes down or repeats (default)
  • btnd(): true on the frame a button initially goes down
  • btnh(): number of frames the button has been held, or 0
  • btnu(): true on the frame a button finally goes up

It's really not very complex, so I might tidy my code and upload it.

@zep - I think, in windows, you need to ignore WM_KEYDOWN events that have the repeat count (lParam & 15) greater than 0. That or just use GetAsyncKeyState() to read the keyboard.

P#52615 2018-05-11 11:28 ( Edited 2018-05-11 15:39)

oh man I wish btnd was a built-in. I implement it manually in almost every cart (and I must say that is a much better name for it than the one I've been using, Felice XD)

more on topic: I've noticed this bug too! but I guess because I don't use btnp much, I kind of ignored it or assumed it might be an OS-level issue (guess I was wrong!) :p

P#52630 2018-05-11 15:26 ( Edited 2018-05-11 19:32)
1

It looks like this was fixed in v0.2.0:
Changed: btnp() delay and repeats now work independently per-button

Thanks!

P#79620 2020-07-19 19:09

Is there a clean way to set the repeat interval via btnp() or at least toggle off the auto-repeat in the current version? Perhaps through an optional parameter (numeric/boolean)?

@Felice 's set looks very nice, so maybe I'll go that direction.

However, I do feel like there should be a zero-repeat option built-in since I think that's what btnp() was probably meant for vs. btn(). It seems fundamental enough to not require writing up an input-state handler, even if that is pretty simple.

Or is using poke(0x5f5c,delay) and poke(0x5f5d,delay) in _update() actually the finalized method by design?

P#80063 2020-07-29 01:17
1

yes - added recently for that purpose

P#80074 2020-07-29 07:04

I see. Thanks for clarifying @freds72 .
I'll use the poke() method then. Masking with syntactic sugar is simple enough.

P#80107 2020-07-30 00:55 ( Edited 2020-07-30 00:56)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-18 14:20:27 | 0.024s | Q:39