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

25 views (last 30 days)
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 :)

Accepted Answer

Anmol Dhiman
Anmol Dhiman on 27 Jul 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 Comment
lp18692
lp18692 on 29 Jul 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!

Sign in to comment.

More Answers (0)

Categories

Find more on Startup and Shutdown in Help Center and File Exchange

Products


Release

R2017a

Community Treasure Hunt

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

Start Hunting!