Multikey won't work

General FreeBASIC programming questions.
Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Multikey won't work

Postby Tusike » Jan 04, 2011 16:24

Hi! I'm making a game in which you have a shooter, and you accelerate it using UP/DOWN, rotate it using LEFT/RIGHT, and shoot with SPACE. Also, if you have CTRL pressed, it's rotation will be slower (this allows for better aiming whilst shooting). Now, I wanted the game to have a multiplayer mode, which would feature two shooters, and seeing as CTRL wouldn't be a very comfortable control, I decided to change it to let's say the letter "M", multikey(50) instead of multikey(29). And now it won't work as it's supposed to. I can do everything except: accelerate+shoot+rotate SLOWLY (M pressed). If I have all these pressed, it just won't rotate...

Any ideas? I'm really Π$/- off as you can imagine.
Thanks,
-Tusike

Code: Select all

sub ShooterType.move() 
   
   
    dim as double edgex, edgey 
    for count as integer = 0 to num-1
        with *object[count]
            if Game.ActiveWindow = Terrain.TD and .InWindow=Terrain.TD then                 
                if multikey(75) then
                    '*************SLOWER ROTATION
                    if multikey(29) then .direction += .rotspeedmin * dt else .direction += .rotspeedmax * dt
                    if .direction >= 2*pi then .direction -= 2*pi 'left
                     if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                end if
                if multikey(77) then
                    '*************SLOWER ROTATION
                    if multikey(29) then .direction -= .rotspeedmin * dt else .direction -= .rotspeedmax * dt
                    if .direction <= 0 then .direction += 2*pi 'right
                    if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                end if
                if multikey(72) then 'up       
                    .speed += .acceleration * dt: if .speed > Info.ShooterSpeeds(.maxspeed) then .speed = Info.ShooterSpeeds(.maxspeed)
                     if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                elseif multikey(80) then 'down
                    .speed -= .acceleration * dt: if .speed < -Info.ShooterSpeeds(.maxspeed) then .speed = -Info.ShooterSpeeds(.maxspeed)
                     if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                else       
                    if .speed >= 0 then
                        .speed -= .acceleration*2*dt
                        if .speed < 0 then .speed = 0
                    else
                        .speed += .acceleration*2*dt
                        if .speed > 0 then .speed = 0
                    end if
                end if
                if multikey(57) and t - .firerate >= .lastshot then 'space = shoot
                    if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                    .lastshot = t
                    ShooterBullets.add(.x + 8*cos(.direction), .y - 8*sin(.direction), .direction, 300, Info.ShooterRanges(.range) / 300, .damage, .InWindow)       
                end if
                .x += cos(.direction)*.speed*dt     
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex-20)/40
                    edgey = (edgey-20)/40
                    if level.grid(int(edgex), int(edgey)) > 0 or edgex < 0 or edgex > 25 then .x -= cos(.direction)*.speed*dt:exit for
                next
               
                .y -= sin(.direction)*.speed*dt
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex-20)/40
                    edgey = (edgey-20)/40
                    if level.grid(int(edgex), int(edgey)) > 0 or edgey < 0 or edgey > 19 then .y += sin(.direction)*.speed*dt:exit for
                next
            elseif Game.ActiveWindow=Terrain.RTS and .InWindow=Terrain.RTS then
                if Game.RTSSelected <> Terrain.Road and Game.RTSSelected <> Terrain.crosspoint then                   
                    if multikey(75) then
                        '*************SLOWER ROTATION
                        if multikey(29) then .direction += .rotspeedmin * dt else .direction += .rotspeedmax * dt
                        if .direction >= 2*pi then .direction -= 2*pi 'left
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    end if
                    if multikey(77) then
                        '*************SLOWER ROTATION
                        if multikey(29) then .direction -= .rotspeedmin * dt else .direction -= .rotspeedmax * dt
                        if .direction <= 0 then .direction += 2*pi 'right
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    end if
                    if multikey(72) then 'up       
                        .speed += .acceleration * dt: if .speed > Info.ShooterSpeeds(.maxspeed) then .speed = Info.ShooterSpeeds(.maxspeed) 
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    elseif multikey(80) then 'down
                        .speed -= .acceleration * dt: if .speed < -Info.ShooterSpeeds(.maxspeed) then .speed = -Info.ShooterSpeeds(.maxspeed)       
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    else       
                        if .speed >= 0 then
                            .speed -= .acceleration*2*dt
                            if .speed < 0 then .speed = 0
                        else
                            .speed += .acceleration*2*dt
                            if .speed > 0 then .speed = 0
                        end if
                    end if
                    if multikey(57) and t - .firerate >= .lastshot then 'space = shoot
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                        .lastshot = t
                        ShooterBullets.add(.x + 8*cos(.direction), .y - 8*sin(.direction), .direction, 300, Info.ShooterRanges(.range) / 300, .damage, .InWindow)       
                    end if
                end if
                .x += cos(.direction)*.speed*dt     
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex)/40
                    edgey = (edgey)/40
                    if (map.grid(int(edgex), int(edgey)) <> Terrain.free and map.grid(int(edgex), int(edgey)) <> Terrain.nobuild and map.grid(int(edgex), int(edgey)) <> Terrain.portal) _
                    or edgex < 0 or edgex > 64 then .x -= cos(.direction)*.speed*dt:exit for
                next
               
                .y -= sin(.direction)*.speed*dt
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex)/40
                    edgey = (edgey)/40
                    if (map.grid(int(edgex), int(edgey)) <> Terrain.free and map.grid(int(edgex), int(edgey)) <> Terrain.nobuild and map.grid(int(edgex), int(edgey)) <> Terrain.portal) _
                    or edgey < 0 or edgey > 48 then .y += sin(.direction)*.speed*dt:exit for
                next
            end if       
        end with
    next
end sub

[/code]
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Postby rolliebollocks » Jan 04, 2011 16:42

type this instead:

if multikey(fb.sc_m) then stuff

And make sure you include FBGFX.BI.
Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Postby Tusike » Jan 04, 2011 17:19

Nope, it still won't work.

I uploaded my whole game, please download it and see why the hell it won't work:

http://www.mediafire.com/?0l5x41wp5159bw1

You can find ShooterType.move() in the shooter.bas file, and the multikey() values in the shooter.bi

Thanks!
-Tusike

PS: the game is under developement so don't expect anything from it.:)
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Postby rolliebollocks » Jan 04, 2011 17:29

The circle surrounding the ball spins around and stuff and then I can get it to move using the arrow keys and shoot with the spacebar.

This could be a problem local to your machine. Do you have another machine to test on?

<edit>

Never mind that...

You can't use arrays in types. There's your problem.

Use a compound pointer instead.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Postby rolliebollocks » Jan 04, 2011 17:34

edited last post...
Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Postby Tusike » Jan 04, 2011 18:10

@rolliebollocks: I'm using arrays in my DataStructType located in Plix TD.bi, and never had any problems with those... It would suck if you couldn't use them since they're pretty useful. But I wish that were the problem anyway! You see first I didn't even have the array, I only typed in the scancode values themselves. Replace that sub with this one, and you'll get the same result when trying to play:

Code: Select all

sub ShooterType.move()
   
   
    dim as double edgex, edgey
    for count as integer = 0 to num-1
        with *object[count]
            if Game.ActiveWindow = Terrain.TD and .InWindow=Terrain.TD then                 
                if multikey(fb.sc_left) then
                    '*************SLOWER ROTATION
                    if multikey(fb.sc_m) then .direction += .rotspeedmin * dt else .direction += .rotspeedmax * dt
                    if .direction >= 2*pi then .direction -= 2*pi 'left
                     if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                end if
                if multikey(fb.sc_right) then
                    '*************SLOWER ROTATION
                    if multikey(fb.sc_m) then .direction -= .rotspeedmin * dt else .direction -= .rotspeedmax * dt
                    if .direction <= 0 then .direction += 2*pi 'right
                    if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                end if
                if multikey(fb.sc_up) then 'up       
                    .speed += .acceleration * dt: if .speed > Info.ShooterSpeeds(.maxspeed) then .speed = Info.ShooterSpeeds(.maxspeed)
                     if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                elseif multikey(fb.sc_down) then 'down
                    .speed -= .acceleration * dt: if .speed < -Info.ShooterSpeeds(.maxspeed) then .speed = -Info.ShooterSpeeds(.maxspeed)
                     if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                else       
                    if .speed >= 0 then
                        .speed -= .acceleration*2*dt
                        if .speed < 0 then .speed = 0
                    else
                        .speed += .acceleration*2*dt
                        if .speed > 0 then .speed = 0
                    end if
                end if
                if multikey(fb.sc_space) and t - .firerate >= .lastshot then 'space = shoot
                    if Game.TDSelected <> Terrain.shooter then Game.TDSelected = Terrain.shooter:Game.TDSelIndex=count:Game.DisableTDImprovements:EnableButtons(true)
                    .lastshot = t
                    ShooterBullets.add(.x + 8*cos(.direction), .y - 8*sin(.direction), .direction, 300, Info.ShooterRanges(.range) / 300, .damage, .InWindow)       
                end if
                .x += cos(.direction)*.speed*dt     
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex-20)/40
                    edgey = (edgey-20)/40
                    if level.grid(int(edgex), int(edgey)) > 0 or edgex < 0 or edgex > 25 then .x -= cos(.direction)*.speed*dt:exit for
                next
               
                .y -= sin(.direction)*.speed*dt
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex-20)/40
                    edgey = (edgey-20)/40
                    if level.grid(int(edgex), int(edgey)) > 0 or edgey < 0 or edgey > 19 then .y += sin(.direction)*.speed*dt:exit for
                next
            elseif Game.ActiveWindow=Terrain.RTS and .InWindow=Terrain.RTS then
                if Game.RTSSelected <> Terrain.Road and Game.RTSSelected <> Terrain.crosspoint then                   
                    if multikey(fb.sc_left) then
                        '*************SLOWER ROTATION
                        if multikey(fb.sc_m) then .direction += .rotspeedmin * dt else .direction += .rotspeedmax * dt
                        if .direction >= 2*pi then .direction -= 2*pi 'left
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    end if
                    if multikey(fb.sc_right) then
                        '*************SLOWER ROTATION
                        if multikey(fb.sc_m) then .direction -= .rotspeedmin * dt else .direction -= .rotspeedmax * dt
                        if .direction <= 0 then .direction += 2*pi 'right
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    end if
                    if multikey(fb.sc_up) then 'up       
                        .speed += .acceleration * dt: if .speed > Info.ShooterSpeeds(.maxspeed) then .speed = Info.ShooterSpeeds(.maxspeed)
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    elseif multikey(fb.sc_down) then 'down
                        .speed -= .acceleration * dt: if .speed < -Info.ShooterSpeeds(.maxspeed) then .speed = -Info.ShooterSpeeds(.maxspeed)       
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                    else       
                        if .speed >= 0 then
                            .speed -= .acceleration*2*dt
                            if .speed < 0 then .speed = 0
                        else
                            .speed += .acceleration*2*dt
                            if .speed > 0 then .speed = 0
                        end if
                    end if
                    if multikey(fb.sc_space) and t - .firerate >= .lastshot then 'space = shoot
                        if Game.RTSSelected <> Terrain.shooter then Game.RTSSelected = Terrain.shooter:Game.RTSSelIndex=count:Game.DisableRTSImprovements:EnableButtons(true)
                        .lastshot = t
                        ShooterBullets.add(.x + 8*cos(.direction), .y - 8*sin(.direction), .direction, 300, Info.ShooterRanges(.range) / 300, .damage, .InWindow)       
                    end if
                end if
                .x += cos(.direction)*.speed*dt     
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex)/40
                    edgey = (edgey)/40
                    if (map.grid(int(edgex), int(edgey)) <> Terrain.free and map.grid(int(edgex), int(edgey)) <> Terrain.nobuild and map.grid(int(edgex), int(edgey)) <> Terrain.portal) _
                    or edgex < 0 or edgex > 64 then .x -= cos(.direction)*.speed*dt:exit for
                next
               
                .y -= sin(.direction)*.speed*dt
                for i as integer = 0 to 17
                    edgex = .x + cos(i*pi/9)*12
                    edgey = .y - sin(i*pi/9)*12
                    edgex = (edgex)/40
                    edgey = (edgey)/40
                    if (map.grid(int(edgex), int(edgey)) <> Terrain.free and map.grid(int(edgex), int(edgey)) <> Terrain.nobuild and map.grid(int(edgex), int(edgey)) <> Terrain.portal) _
                    or edgey < 0 or edgey > 48 then .y += sin(.direction)*.speed*dt:exit for
                next
            end if       
        end with
    next
end sub

Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Postby Tusike » Jan 04, 2011 18:47

I tested it on another machine, it didn't work.

I thought perhaps it had something to do with inkey running as well, so I took out all Inkey's I had and replaced them with multikey; still didn't work.

It's quite interesting though. If I'm staying in place, rotate with "M" pressed, and shoot, it works. Then if I press DOWN, it starts going backwards while rotating slowly and shooting. Great. Then I press Up: it doesn't start going forwards. So it detects down, but not up...

WASD with "2" for fire and "1" for slow rotation acts differently but quite as weird as well. Perhaps I should be grateful that there is at least one combination of keys that work and that the game will be playable. Lucky me that I picked the arrow keys, space, and control in the beginning.
Fox
Posts: 353
Joined: Aug 08, 2006 13:39
Location: Lille, France
Contact:

Re: Multikey won't work

Postby Fox » Jan 04, 2011 19:30

Tusike wrote:And now it won't work as it's supposed to. I can do everything except: accelerate+shoot+rotate SLOWLY (M pressed). If I have all these pressed, it just won't rotate...


Hi,

Could be a hardware limitation of your keyboard. I remember back in my DOS days, that in games that required to use many keys simulteanously, I had to carefully choose my controls, because my keyboard was able to scan only a limited set of keypresses. You might want to try your game on various keyboards (not only on cheapest one), to see if there is any difference...
fxm
Posts: 10211
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Jan 04, 2011 20:20

It is a known problem : Multikey works very badly for fbgfx screens on Windows.
See some previous topics :
http://www.freebasic.net/forum/viewtopi ... 266#129266
http://www.freebasic.net/forum/viewtopi ... 297#130297

And it seems to depend on PC!

On my PC (portable), the "m" key alone is not even detected by Multikey on fbgfx!
Accordingly, I use the least possible "Multikey", except for some test keys (example : Shift, Ctrl, Alt)
Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Postby Tusike » Jan 04, 2011 20:46

I tried using the GetAsyncKeyState() function in the windows header to get the key states of the keyboard's characters, and it didn't work using that either... so I guess multikey isn't the only problem:)
fxm
Posts: 10211
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Jan 04, 2011 21:32

On my PC (portable) :
- In text mode (screen 0), key "m" is detected by Multikey(50) : OK
- In graphic mode (screen 12), key "m" is detected by Multikey(39) : !!!

Code: Select all

DIM I AS INTEGER
DIM K AS INTEGER

SCREEN 12
DO
  FOR I = 0 TO 255
    IF MULTIKEY(I) THEN
      IF K = 1 THEN
        PRINT " & ";
      END IF
      PRINT "MultiKey(";
      PRINT USING "###"; I;
      PRINT ")";
      K = 1
      IF I = 1 THEN
        PRINT
        EXIT DO
      END IF
    END IF
  NEXT I
  IF K = 1 THEN
    PRINT
    K = 0
  END IF
  SLEEP 25
LOOP
SLEEP


Other keyboard scancodes are different between text mode and graphic mode !
Perhaps is it linked with the language of the keyboard (French for me).

For alphabetic keys :
- Effectively, for Multikey statement, my French keyboard is considered as an English keyboard in graphic fbgfx mode.
- In text mode, no problem, my French keyboard is well recognized by Multikey.
Last edited by fxm on Jan 05, 2011 13:41, edited 3 times in total.
Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Postby Tusike » Jan 04, 2011 22:14

I don't think this has to do with the scancode values. The "M" is sometimes detected, other times not.

Check out this small example. It runs in screen 0 text mode, or run it in a graphics window if you like. Press SPACE, M, UP at the same time, then RIGHT: the RIGHT key isn't detected... Press SPACE, M, DOWN at the same time, then RIGHT: all keys are detected. weird.

Code: Select all

#include "fbgfx.bi"

'====================================================================
#include "windows.bi"
'====================================================================
'screenres 1024, 768, 24,,1
dim shared as ubyte keystate(0 to 255)
declare function refresh() as byte


    do   
        if refresh = 1 then
            screenlock
            'line (0, 0) - (1023, 767), rgb(0, 0, 0), BF
            cls
            locate 1, 1
            for i as integer = 0 to 255
                print trim(str(keystate(i)));
                if i mod 25 = 24 then print ""
            next
            screensync()
            screenunlock
        end if
        sleep 1, 1
    loop until keystate(27) = 1
system

function refresh() as byte
    dim as byte ret = 0
    for i as integer = 0 to 255
        if GetAsyncKeyState( i ) and &h8000 then
            if keystate(i) = 0 then ret = 1
            keystate(i) = 1           
        else
            if keystate(i) = 1 then ret = 1
            keystate(i) = 0
        end if     
    next
    return ret
end function
fxm
Posts: 10211
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Jan 04, 2011 22:43

- Yes, you have not the same big problem than me, because for the considered keys "Left", "Right", "Up", "Down", "Space", "M", there is no difference between an Hungary keyboard and an English keyboard (the key "M" is at the same position).

- Running your test program, I have the same bad behavior than you.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Postby KristopherWindsor » Jan 05, 2011 2:20

It was probably mentioned in those other threads, but I assume you aren't using multikey() when the screen is locked (which is bad)?
Tusike
Posts: 207
Joined: Jan 03, 2008 16:53
Location: Hungary

Postby Tusike » Jan 05, 2011 7:19

Nope, the rendering is done apart from the game's calculations, so I don't have the screen locked when checking for multikey.

Return to “General”

Who is online

Users browsing this forum: No registered users and 11 guests