Borrar filtros
Borrar filtros

How to deal with KeyPressFcn recording multiple key presses within a loop?

13 visualizaciones (últimos 30 días)
Hello there,
I'm trying to make a simple game in MATLAB, and I am using KeyPressFcn and KeyReleaseFcn callbacks to get player input from within a loop. It looks something like this:
boxfig=figure;
drawnow
akey='a';
set(boxfig,'KeyPressFcn',{@Key_Down,akey},'KeyReleaseFcn',{@Key_Up,akey});
lrshift=0;
kk=1;
while kk<2
drawnow
fprintf([num2str(lrshift) '\n']);
end %kk
function Key_Down(~,event,leftkey)
if strcmp(event.Key,leftkey), assignin('base','lrshift',1); end
end
function Key_Up(~,event,leftkey)
if strcmp(event.Key,leftkey), assignin('base','lrshift',0); end
end
The code sets lrshift to 1 when the a-key is pressed, and to 0 when it's not pressed, and then prints the value of lrshift. However, the loop obviously runs faster than one can press and release a key, so it always records multiple subsequent key-presses. I would like the program to set lrshift to 1 once only when the key is first pressed, and then immediately back to 0 until the key has been released and is pressed again. At the moment, the output looks something like this:
0
0
0
0
1 %<- a-key pressed
1
1
1
1
0 %<- a-key released
0
0
1 %<- a-key pressed
1
1
1
1
0 %<- a-key released
0
0
I would like it to look like:
0
0
0
0
1 %<- a-key pressed
0
0
0
0
0 %<- a-key released
0
0
0
1 %<- a-key pressed
0
0
0
0
0 %<- a-key released
0
0
I have tried to disable the callback to KeyPressFcn after the key is first pressed within the loop, but the result is still the same:
while kk<2
if lrshift==1
set(boxfig,'KeyPressFcn',[],'KeyReleaseFcn',{@Key_Up,akey});
else
set(boxfig,'KeyPressFcn',{@Key_Down,akey},'KeyReleaseFcn',{@Key_Up,akey});
end
drawnow
fprintf([num2str(lrshift) '\n']);
end %kk
Pausing for a short time is not an option since the game is still doing other things in the background.
I would be grateful if anyone could help me with this! Is KeyPressFcn even the right way to go about it?
Thank you :)

Respuesta aceptada

Anmol Dhiman
Anmol Dhiman el 27 de Jul. de 2020
Hi Lp,
Update your Key_Down function as below for a workaround
function Key_Down(~,event,leftkey)
if strcmp(event.Key,leftkey)
lrshift = 1;
fprintf([num2str(lrshift) '\n']);
assignin('base','lrshift',0);
end
end
Regards,
Anmol Dhiman
  1 comentario
lp18692
lp18692 el 29 de Jul. de 2020
Thank you Anmol!
Your workaround does work in the example I provided, but in the real code I needed the main loop to do other things besides printing the value, and letting it all happen within the function seemed messy. I have since gotten it to work this way:
boxfig=figure;
drawnow
akey='a';
set(boxfig,'KeyPressFcn',{@Key_Down,akey},'KeyReleaseFcn',{@Key_Up,akey});
lrshift=0;
kk=1;
down1=0; up1=1;
while kk<2
drawnow
if downl==1 && upl==1
lrshift=1;
downl=0;
end
fprintf([num2str(lrshift) '\n']);
lrshift=0;
end %kk
function Key_Down(~,event,leftkey)
if strcmp(event.Key,leftkey), assignin('base','downl',1); end
end
function Key_Up(~,event,leftkey)
if strcmp(event.Key,leftkey), assignin('base','upl',1); end
end
This way lrshift is immediately set back to 0 and the code waits for the button to be released before it can be set to 1 again.
Thanks and kind regards!

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Environment and Settings en Help Center y File Exchange.

Productos


Versión

R2017a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by