 |
Castle Paradox
|
View previous topic :: View next topic |
Author |
Message |
Camdog
Joined: 08 Aug 2003 Posts: 606
|
Posted: Thu May 04, 2006 5:17 pm Post subject: Faking a logical not?/misunderstanding of "is key press |
|
|
Hey all. I'm experiencing some funkiness in one of my scripts. Basically, it's a custom menu, and I wanted it to respond to user input nicely when scrolling around in it. A wait(1) made the response to sensitive, and a wait(2) made it too clunky, so my idea was to simply not let the last key pressed register again (making it scroll quickly if you held the button down). To emulate a "key up" check, I basically had to check when the last key pressed was no longer pressed.
Since there is no logical not in HamsterSpeak, I faked it with an xor like so:
Code: | if (key is pressed(lastPressed),xor,true) then (
#do stuff...
) |
The problem is, this logic block is firing when it shouldn't. I'm not sure if my idea is wrong or I don't understand exactly how "key is pressed()" works. A show value reveals that a held key sets lastPressed properly for a few seconds, but then the logic block is fired an it resets. I think this lag is far to long to suggest the logic block is always evaluating to true, which makes me think something is going on with "key is pressed()". Does it stop registering a key after it's been held for a few seconds? (Or maybe show value just lags a little...)
Anyway, here's the code:
Code: | #make sure holding down a key doesn't make it go nuts
variable(lastPressed)
lastPressed := 0
while(isDone == 0) do (
if(key is pressed(key:UP)) then (
if (lastPressed <> key:UP) then (
set selector location(UP)
lastPressed := key:UP
)
)
if(key is pressed(key:DOWN)) then (
if (lastPressed <> key:DOWN) then (
set selector location(DOWN)
lastPressed := key:DOWN
)
)
if(key is pressed(key:LEFT)) then (
if (lastPressed <> key:LEFT) then (
set selector location(LEFT)
lastPressed := key:LEFT
)
)
if(key is pressed(key:RIGHT)) then (
if (lastPressed <> key:RIGHT) then (
set selector location(RIGHT)
lastPressed := key:RIGHT
)
)
if(key is pressed(key:SPACE)) then (
if (lastPressed <> key:SPACE) then (
if(get hero stat(who, stat:Skill, maximum stat) >> 0) then (
set hero stat(who, stat:Skill, (get hero stat(who, stat:Skill, maximum stat) -- 1), maximum stat)
set hero stat(who, stat:Skill, (get hero stat(who, stat:Skill, maximum stat)), current stat)
upgrade skill(NPC X(0), NPC Y(0), who)
)
else (
show text box(98)
wait for text box
)
lastPressed := key:SPACE
)
)
if(key is pressed(key:COMMA)) then (
if (lastPressed <> key:COMMA) then (
#who := setWho(1)
lastPressed := key:COMMA
)
)
if(key is pressed(key:PERIOD)) then (
if (lastPressed <> key:PERIOD) then (
#who := setWho(-1)
lastPressed := key:PERIOD
)
)
if(key is pressed(key:ESC)) then (
isDone := 1
)
#reset the no "auto-fire" constraint
if(key is pressed(lastPressed),xor,true) then (
lastPressed := 0
)
show value(lastPressed)
wait
) |
Thanks for any help!
P.S. I'm using Quaternion because of stability issues. |
|
Back to top |
|
 |
Blue Pixel SPY SAPPIN MAH FISH SANDWICH

Joined: 22 Apr 2005 Posts: 621
|
Posted: Thu May 04, 2006 5:34 pm Post subject: |
|
|
for some reason this seems to belong on plot scripting forum... _________________
 |
|
Back to top |
|
 |
Iblis Ghost Cat

Joined: 26 May 2003 Posts: 1233 Location: Your brain
|
Posted: Thu May 04, 2006 6:42 pm Post subject: |
|
|
Actually there are a couple easy ways to do "not." Like:
Code: | if (key is pressed(lastPressed) == false) |
or
Code: | if (key is pressed(lastPressed) <> true) |
Your way seems like it should work too though.
For the rest of your code, it's kind of hard to tell what it's all doing. I've written a few custom menus before, and I haven't had many problems with it. Here's basically what I did:
Code: | variable (keyp)
keyp := 0
while (quit <> 1) do
(
if (key is pressed (72)) then (keyp := 1) # Up
if (key is pressed (75)) then (keyp := 2) # Left
if (key is pressed (77)) then (keyp := 3) # Right
if (key is pressed (80)) then (keyp := 4) # Down
if (key is pressed (57),or, key is pressed (28)) then (keyp:=5) # Enter/Space
wait (1)
if (keyp <> 0) then
(
if (keyp == 1) then (do stuff)
... # repeat for 2-5
wait (1)
keyp := 0
)
) |
So, I just used a variable to hold the keypress instead of checking which key was pressed every time. It works pretty well. I also add a wait that only occurs if you hit a key, so that it checks the keys every tick unless you actually press a key. It keeps one keypress from registering a bunch of times unless you hold it down. _________________ Locked
OHR Piano |
|
Back to top |
|
 |
Camdog
Joined: 08 Aug 2003 Posts: 606
|
Posted: Thu May 04, 2006 7:25 pm Post subject: |
|
|
Wowee, I must not be getting enough sleep lately. I have no idea why I didn't put this on the plotscripting forum.
Further, I have no idea why I invented such a convoluted way to fake a not when, as Iblis pointed out, there are much easier ways to do it.
Anyway...
Iblis, the problem I'm having is cosmetic rather than functional. What I'm doing right now (and what your code does) works just fine. However, my problem is that with wait set to one, the cursor moves around too fast, or, say, jumps down two spots when pushing down instead of the intended one.
If I set the wait to two, it gets a little sluggish, and tapping down twice might only result in the cursor moving down one space.
What I was hoping to accomplish was a system that responded to taps as quickly as you could push them without moving more than once if the key was held down. I tried to do this by setting a variable equal to the last key you pushed and unsetting it when you let it go (ie, when key is pressed(lastPressed) == false). However, key is pressed seems to reset lastPressed even if I'm holding down a key. So, to clarify, the script works fine, it's just not as user-friendly as I'd hoped.
[edit] I realize you address this, I was just hoping for something a little more precise than waits that wait for about the right amount of time. Also, I was wondering if there was something about is key pressed I didn't know.
If any stray admins want to move this to the plotscripting forum... |
|
Back to top |
|
 |
TMC On the Verge of Insanity
Joined: 05 Apr 2003 Posts: 3240 Location: Matakana
|
Posted: Thu May 04, 2006 11:28 pm Post subject: |
|
|
Yes, you're right, keyispressed is buggy (and has always been so). In addition, FB Game and QB Game have keyboard issues with various people. The bug in keyispressed is exposed by your use of xor, 1. It sometimes returns numbers other than 1, which is incorrect, it should always return 0 or 1. However, I'll note that
Code: | if (key is pressed(lastPressed) <> true) |
also would not work, it is not logical (but the other would). The easier way to do a logical not would have to be
Code: | if (key is pressed(lastPressed)) else ( |
This should also fix your problem.
The page for this bug, or something similiar is http://hamsterrepublic.com/bugzilla/show_bug.cgi?id=179 but there's nothing to read there. Once I make sure that my understanding of this bug is right, I'll commit a simple fix.
What're your stability issues with recent versions? Are even QB versions no good? _________________ "It is so great it is insanely great." |
|
Back to top |
|
 |
Mike Caron Technomancer

Joined: 26 Jul 2003 Posts: 889 Location: Why do you keep asking?
|
Posted: Fri May 05, 2006 8:49 am Post subject: |
|
|
A ha! I knew it! We should have a not() operator. Or, you know, just implement it like this:
Code: | define script(autonumber,not,1)
script, not, cond, begin
if(cond) then (return(false)) else (return(true))
end |
But, anyway. key is pressed() returns 1 if it's a "new" key press, and 2 if it's a repeat (or, possibly the other way around). I think that's valid behaviour. In most cases (i.e. those where you don't care what type of key press) you should always be testing "if(key is pressed())" or "if(key is pressed()==false)".
On the other hand, testing "==true" is broken. But, then, that really is a roundabout way of testing a boolean. _________________ I stand corrected. No rivers ran blood today. At least, none that were caused by us.
Final Fantasy Q
OHR Developer BLOG
Official OHRRPGCE Wiki and FAQ |
|
Back to top |
|
 |
Camdog
Joined: 08 Aug 2003 Posts: 606
|
Posted: Fri May 05, 2006 10:29 am Post subject: |
|
|
Excellent! That's exactly what I wanted to know. Thanks. |
|
Back to top |
|
 |
Moogle1 Scourge of the Seas Halloween 2006 Creativity Winner


Joined: 15 Jul 2004 Posts: 3377 Location: Seattle, WA
|
Posted: Fri May 05, 2006 11:07 am Post subject: |
|
|
Mike Caron wrote: | A ha! I knew it! We should have a not() operator. Or, you know, just implement it like this:
Code: | define script(autonumber,not,1)
script, not, cond, begin
if(cond) then (return(false)) else (return(true))
end |
But, anyway. key is pressed() returns 1 if it's a "new" key press, and 2 if it's a repeat (or, possibly the other way around). I think that's valid behaviour. In most cases (i.e. those where you don't care what type of key press) you should always be testing "if(key is pressed())" or "if(key is pressed()==false)".
On the other hand, testing "==true" is broken. But, then, that really is a roundabout way of testing a boolean. |
"not" would work much more smoothly at the compiler level.
If we could recompile the compiler, that is. _________________
|
|
Back to top |
|
 |
TMC On the Verge of Insanity
Joined: 05 Apr 2003 Posts: 3240 Location: Matakana
|
Posted: Fri May 05, 2006 8:37 pm Post subject: |
|
|
Mike Caron wrote: | But, anyway. key is pressed() returns 1 if it's a "new" key press, and 2 if it's a repeat (or, possibly the other way around). I think that's valid behaviour. In most cases (i.e. those where you don't care what type of key press) you should always be testing "if(key is pressed())" or "if(key is pressed()==false)". |
I think it should always return 1 because of the bitwise comparison operators. That "new key press" behaviour also include typematic behaviour. If it is required to know whether a press is "new", a new command should be implemented. (And it only returns 2 under QB GAME.)
Moggle1 wrote: | "not" would work much more smoothly at the compiler level. |
I agree. Don't consider implementing not as a script or command (Mike) _________________ "It is so great it is insanely great." |
|
Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|