Castle Paradox Forum Index Castle Paradox

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Gamelist   Review List   Song List   All Journals   Site Stats   Search Gamelist   IRC Chat Room

Faking a logical not?/misunderstanding of "is key press

 
Post new topic   Reply to topic    Castle Paradox Forum Index -> HELP!
View previous topic :: View next topic  
Author Message
Camdog




Joined: 08 Aug 2003
Posts: 606

PostPosted: Thu May 04, 2006 5:17 pm    Post subject: Faking a logical not?/misunderstanding of "is key press Reply with quote

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
View user's profile Send private message
Blue Pixel
SPY SAPPIN MAH FISH SANDWICH




Joined: 22 Apr 2005
Posts: 621

PostPosted: Thu May 04, 2006 5:34 pm    Post subject: Reply with quote

for some reason this seems to belong on plot scripting forum...
_________________
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger
Iblis
Ghost Cat




Joined: 26 May 2003
Posts: 1233
Location: Your brain

PostPosted: Thu May 04, 2006 6:42 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Camdog




Joined: 08 Aug 2003
Posts: 606

PostPosted: Thu May 04, 2006 7:25 pm    Post subject: Reply with quote

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
View user's profile Send private message
TMC
On the Verge of Insanity




Joined: 05 Apr 2003
Posts: 3240
Location: Matakana

PostPosted: Thu May 04, 2006 11:28 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Mike Caron
Technomancer




Joined: 26 Jul 2003
Posts: 889
Location: Why do you keep asking?

PostPosted: Fri May 05, 2006 8:49 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website MSN Messenger
Camdog




Joined: 08 Aug 2003
Posts: 606

PostPosted: Fri May 05, 2006 10:29 am    Post subject: Reply with quote

Excellent! That's exactly what I wanted to know. Thanks.
Back to top
View user's profile Send private message
Moogle1
Scourge of the Seas
Halloween 2006 Creativity Winner
Halloween 2006 Creativity Winner



Joined: 15 Jul 2004
Posts: 3377
Location: Seattle, WA

PostPosted: Fri May 05, 2006 11:07 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website AIM Address
TMC
On the Verge of Insanity




Joined: 05 Apr 2003
Posts: 3240
Location: Matakana

PostPosted: Fri May 05, 2006 8:37 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Castle Paradox Forum Index -> HELP! All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
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