Posts: 63
Threads: 10
Joined: Jan 2003
Since this forum has rekindled my playing with QB 4.5, I decided to try writing a very simple game, in the "Bomber" style.
The only problem I'm having though, is overcoming the delay after a key is pressed and held. Its the same thing that is desirable when typing, but NOT good in controlling a "ship".
The only key-press commands I really know are INKEY$ and INPUT$(1).
Does anyone have any ideas on how to get around this?
Thanks all, Dex
Posts: 749
Threads: 4
Joined: Jun 2002
That's one of the reasons to use a custom keyboard handler. There are lots of different "versions" for multikey handlers floating around there, check out the following authors: Milo Sedlacek, Joe Huber Jr., Eric Carr. I also tried Exposed Dreams' zKbh, and that works really nice.
img]http://usuarios.vtr.net/~disaster/sigs/annoyizer.php[/img]
Posts: 63
Threads: 10
Joined: Jan 2003
Thanks Hex, but are these, perhaps posts prior to the great cracker-crash?
I'm not getting any search results for any of those names.
:???: Dex
Posts: 3,368
Threads: 195
Joined: Jan 2003
You *can* overcome the annoying beep that comes with pressing out of the buffer by adding
after the user presses a key.
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."
Visit www.neobasic.net to see rubbish in all its finest.
Posts: 63
Threads: 10
Joined: Jan 2003
Thanks agamemnus for that tip, but thats not actually my problem. I don't get any "beeps", just a delay after the first keypress.
For instance, I press the left arrow, my ship jumps ahead one "position" then pauses the standard key-delay time, then continues on smoothly. Each time I change direction, or start-and-stop, I have the same delay.
But, I'll keep searching.
Dex
Posts: 3,368
Threads: 195
Joined: Jan 2003
well.. that feeds empty stuff in the buffer, so maybe it will run smoother.
Also are you using an IF I$ <> "".... END IF loop?
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."
Visit www.neobasic.net to see rubbish in all its finest.
Posts: 6,419
Threads: 74
Joined: Mar 2002
Nope. You can read port &H60 for a simple, single-keypress keyboard handler. Now the codes are not ascii, but scancodes. A complete list of scancodes is in QB help:
Code: ScanCodeOfLastKeyPressed% = INP(&H60)
NotUsed$=INKEY$ ' This clears keyboard
The response at port &H60 is immediate.
Posts: 749
Threads: 4
Joined: Jun 2002
Yeah, Dex, but sometimes the almighty Google is the one who needs to be asked, not only the forum. :roll: Since you at least made the effort to search for these keywords, well... here we go with a classic: the legendary multikey code by Milo Sedlacek, with some sample code. MEGAMAN, TAKE NOTES ABOUT THIS ROUTINE!
Code: DECLARE SUB KEYTEST ()
DECLARE FUNCTION MULTIKEY (T)
'ASM Interrupt & support code by Milo Sedlacek
'Demo by Joe Huber Jr.
'MULTIKEY - main routine
' Usage:
' X = MULTIKEY(T)
' where t can equal -1,-2, and 1-128
' t = -1: IMPORTANT!!! Make sure you pass this value to
' the function before -2 and 1-128! It turns the
' interrupt on so you can start reading keys.
' Returns: nothing
' t = -2: EXTREMELY IMPORTANT!!!!!!!!
' ALWAYS pass this before you end your program!
' If you don't, your computer won't be able to
' read your keyboard & you'll have to reset!
' i.e., CTRL-ALT-DEL won't work!!
' Returns: nothing
' t = keycode (1-128): Returns status of a key.
' Returns: 1 or 0 where
' 1 = pressed
' 0 = unpressed
'
'KEYTEST - helps you find new keycodes
' Usage:
' CALL KEYTEST or KEYTEST
' This will show all 128 keycodes & their statuses.
' Press & hold a key & a 1 will appear somewhere.
' The number that the 1 is by will be the keycode
' for that key. Simple!
'Demo code:
'Use arrows to turn & accelerate
'Press space to come to a total stop
'Hit ESC to exit
Z = MULTIKEY(-1) ' Initalize ASM & hook interrupt
SCREEN 12
CLS
X = 320
Y = 240
cPI = (3.141592654# / 180)
ANGLE = 0
RADIUS = 5
SPEED = .2
DO
IF MULTIKEY(77) THEN ANGLE = ANGLE - 7 ' Left
IF MULTIKEY(75) THEN ANGLE = ANGLE + 7 ' Right
IF MULTIKEY(72) THEN ' Up
VX = VX + (SIN(cPI * ANGLE) * SPEED)
VY = VY + (COS(cPI * ANGLE) * SPEED)
END IF
IF MULTIKEY(80) THEN ' Down
VX = VX - (SIN(cPI * ANGLE) * SPEED)
VY = VY - (COS(cPI * ANGLE) * SPEED)
END IF
IF MULTIKEY(57) THEN ' Space
VX = 0
VY = 0
END IF
IF ANGLE > 360 THEN ' Wrap-around angle
ANGLE = 0 + (ANGLE - 360)
END IF
IF ANGLE < 0 THEN
ANGLE = 360 - (0 + ANGLE)
END IF
IF X < 0 + RADIUS THEN VX = -VX ' Bounce limits
IF X > 640 - RADIUS THEN VX = -VX
IF Y < 0 + RADIUS THEN VY = -VY
IF Y > 480 - RADIUS THEN VY = -VY
X = X + VX ' Move it
Y = Y + VY
X2 = X + SIN(cPI * ANGLE) * RADIUS ' White dot calc
Y2 = Y + COS(cPI * ANGLE) * RADIUS ' ditto
VX = VX * .998 ' Friction
VY = VY * .998 ' ditto
CIRCLE (XX, YY), RADIUS, 0 ' Erase
PSET (XX2, YY2), 0
PSET (XX, YY), 0
CIRCLE (X, Y), RADIUS, 4 ' Draw
PSET (X2, Y2), 15
PSET (X, Y), 4
XX = X: YY = Y: YY2 = Y2: XX2 = X2
WAIT &H3DA, 8 ' Wait to vert. retarce
WAIT &H3DA, 8, 8
LOOP UNTIL MULTIKEY(1) = 1 ' Hit ESC to exit
Z = MULTIKEY(-2) 'Unhook interrupt
END
SUB KEYTEST
SCREEN 0
CLS
Z = MULTIKEY(-1)
DO
X = 1
Y = 1
FOR I = 1 TO 128
TEST = MULTIKEY(I)
LOCATE Y, X
PRINT USING "## =###"; TEST; I
IF Y < 23 THEN
Y = Y + 1
ELSE
Y = 1
X = X + 9
END IF
NEXT I
LOOP WHILE MULTIKEY(1) = 0
Z = MULTIKEY(-2)
END
END SUB
FUNCTION MULTIKEY (T)
STATIC kbcontrol%(), kbmatrix%(), Firsttime, StatusFlag
IF Firsttime = 0 THEN 'Initalize
DIM kbcontrol%(128)
DIM kbmatrix%(128)
code$ = ""
code$ = code$ + "E91D00E93C00000000000000000000000000000000000000000000000000"
code$ = code$ + "00001E31C08ED8BE24000E07BF1400FCA5A58CC38EC0BF2400B85600FAAB"
code$ = code$ + "89D8ABFB1FCB1E31C08EC0BF2400BE14000E1FFCFAA5A5FB1FCBFB9C5053"
code$ = code$ + "51521E560657E460B401A8807404B400247FD0E088C3B700B0002E031E12"
code$ = code$ + "002E8E1E100086E08907E4610C82E661247FE661B020E6205F075E1F5A59"
code$ = code$ + "5B589DCF"
DEF SEG = VARSEG(kbcontrol%(0))
FOR I% = 0 TO 155 ' Load ASM
d% = VAL("&h" + MID$(code$, I% * 2 + 1, 2))
POKE VARPTR(kbcontrol%(0)) + I%, d%
NEXT I%
I& = 16 ' I think this stuff connects the interrupt with kbmatrix%()
N& = VARSEG(kbmatrix%(0)): l& = N& AND 255: h& = ((N& AND &HFF00) \ 256): POKE I&, l&: POKE I& + 1, h&: I& = I& + 2
N& = VARPTR(kbmatrix%(0)): l& = N& AND 255: h& = ((N& AND &HFF00) \ 256): POKE I&, l&: POKE I& + 1, h&: I& = I& + 2
DEF SEG
Firsttime = 1
END IF
SELECT CASE T
CASE -1
IF StatusFlag = 0 THEN
DEF SEG = VARSEG(kbcontrol%(0))
CALL ABSOLUTE(0) ' Run interrupt
DEF SEG
StatusFlag = 1
END IF
CASE -2
IF StatusFlag = 1 THEN
DEF SEG = VARSEG(kbcontrol%(0)) ' Turn off interrupt
CALL ABSOLUTE(3)
DEF SEG
StatusFlag = 0
END IF
CASE 1 TO 128
MULTIKEY = kbmatrix%(T) ' Return status
CASE ELSE
MULTIKEY = 0 ' User Stupidity Error
END SELECT
END FUNCTION
img]http://usuarios.vtr.net/~disaster/sigs/annoyizer.php[/img]
Posts: 63
Threads: 10
Joined: Jan 2003
Thanks Hex, (and Nathan), I'll try these codes out as soon I get home.
Its funny, I actually did search Google for "Exposed Dreams", 'cause it sounded like a web page and/or company, but it didn't occur to me to check the individual names there.
Thanks again, Dex
Posts: 54
Threads: 16
Joined: Jan 2003
Mmmmm...., I tried to understand the code as I'm coping with a similar problem. But since I don't understand the peek, poke ( and a lot of other commands) I prefer to use simple ones. INKEY is slow. Another problem is that when I'm using two or four inkeys, only the first does work somewhat properly. The others are very difficult to get to work. Why is that?
|