I am trying to re-create "Pong" in MATLAB, and so far I have been able to generate the figure, draw a court, draw the paddles, and draw the ball. At this point, I am trying to update the position of the paddles (move them up and down) via keyboard input. I am attempting to utilize MATLAB's built-in "KeyPressFcn" and "KeyReleaseFcn" features in order to do this, but for some reason the paddles still aren't moving. My code is below. Can anyone see what I am doing wrong?
% Create court figure, make title, set axis, draw middle dotted line and
% top/bottom lines, turn axis off
court = figure;
set(court, 'Color', 'black', 'toolbar', 'none', 'menubar', 'none');
title('ENGR 122 PONG', 'FontSize', 18, 'Color', 'w');
axis([0 14 0 12]);
line([7 7],[0 12],'LineStyle',':','LineWidth',1,'Color','yellow');
line([0 14], [12 12], 'LineStyle', '-', 'LineWidth', 3, 'Color', 'yellow');
line([0 14], [0 0], 'LineStyle', '-', 'LineWidth', 3, 'Color', 'yellow');
axis off
% Initialize inputs for left and right paddle
left_input = 0;
right_input = 0;
% Initialize ball on court
hold on
ball = plot(7, 6, 'w.', 'MarkerSize', 15);
% Initialize paddles on court, set speed
left_bottom = 5;
left_height = 2;
right_bottom = 5;
right_height = 2;
left_paddle = line([1 1], [left_bottom (left_bottom + left_height)], 'LineWidth', 5, 'Color', 'red');
right_paddle = line([13 13], [right_bottom (right_bottom + right_height)], 'LineWidth', 5, 'Color', 'blue');
% Initialize score on screen
left_score = 0;
right_score = 0;
draw_left_score = text(2, 10, num2str(left_score), 'FontSize', 25, 'Color', 'yellow');
draw_right_score = text(12, 10, num2str(right_score), 'FontSize', 25, 'Color', 'yellow');
% While neither player has scored 10 points yet
while (left_score < 10 || right_score < 10)
% Update left and right paddle values
left_bottom = updateLeft(left_input, left_bottom)
right_bottom = updateRight(right_input, right_bottom);
% Set Key listeners to figure
set(court, 'KeyPressFcn', @keyDown, 'KeyReleaseFcn', @keyUp);
% Update left and right paddle positions on figure
set(left_paddle, 'YData', [left_bottom (left_bottom + left_height)]);
set(right_paddle, 'YData', [right_bottom (right_bottom + right_height)]);
end
% Function listening for keys being pressed
function keyDown(source, event)
if event.Key == 'q'
left_input = 1;
end
if event.Key == 'a'
left_input = -1;
end
if event.Key == 'o'
right_input = 1;
end
if event.Key == 'l'
right_input = -1;
end
end
% Function listening for keys being released
function keyUp(source, event)
if event.Key == 'q'
left_input = 0;
end
if event.Key == 'a'
left_input = 0;
end
if event.Key == 'o'
right_input = 0;
end
if event.Key == 'l'
right_input = 0;
end
end
% Function updating left paddle
function left_bottom = updateLeft(left_input, left_bottom)
if left_input == 1
left_bottom = left_bottom + .05;
elseif left_input == -1
left_bottom = left_bottom - .05;
end
end
% Function updating right paddle
function right_bottom = updateRight(right_input, right_bottom)
if right_input == 1
right_bottom = right_bottom + .05;
elseif right_input == -1
right_bottom = right_bottom - .05;
end
end
I think there is a simple solution to the problem.
Call drawnow
function at the end of the while loop.
You can also add pause command like pause(0.01)
.
% While neither player has scored 10 points yet
while (left_score < 10 || right_score < 10)
% Update left and right paddle values
left_bottom = updateLeft(left_input, left_bottom);
right_bottom = updateRight(right_input, right_bottom);
% Set Key listeners to figure
set(court, 'KeyPressFcn', @keyDown, 'KeyReleaseFcn', @keyUp);
% Update left and right paddle positions on figure
set(left_paddle, 'YData', [left_bottom (left_bottom + left_height)]);
set(right_paddle, 'YData', [right_bottom (right_bottom + right_height)]);
drawnow
end
The problem is that Matlab blocks all events when tight loop is executed.
Adding drawnow
or pause
, enables Matlab respond to the event.
The problem might also be related to variables Scope Rules.
Make sure the end
statement of the main function, is at the last code line of the file.
Check the following (complete code):
function PongGame()
court = figure;
set(court, 'Color', 'black', 'toolbar', 'none', 'menubar', 'none');
title('ENGR 122 PONG', 'FontSize', 18, 'Color', 'w');
axis([0 14 0 12]);
line([7 7],[0 12],'LineStyle',':','LineWidth',1,'Color','yellow');
line([0 14], [12 12], 'LineStyle', '-', 'LineWidth', 3, 'Color', 'yellow');
line([0 14], [0 0], 'LineStyle', '-', 'LineWidth', 3, 'Color', 'yellow');
axis off
% Initialize inputs for left and right paddle
left_input = 0;
right_input = 0;
% Initialize ball on court
hold on
ball = plot(7, 6, 'w.', 'MarkerSize', 15);
% Initialize paddles on court, set speed
left_bottom = 5;
left_height = 2;
right_bottom = 5;
right_height = 2;
left_paddle = line([1 1], [left_bottom (left_bottom + left_height)], 'LineWidth', 5, 'Color', 'red');
right_paddle = line([13 13], [right_bottom (right_bottom + right_height)], 'LineWidth', 5, 'Color', 'blue');
% Initialize score on screen
left_score = 0;
right_score = 0;
draw_left_score = text(2, 10, num2str(left_score), 'FontSize', 25, 'Color', 'yellow');
draw_right_score = text(12, 10, num2str(right_score), 'FontSize', 25, 'Color', 'yellow');
% While neither player has scored 10 points yet
while (left_score < 10 || right_score < 10)
% Update left and right paddle values
left_bottom = updateLeft(left_input, left_bottom);
right_bottom = updateRight(right_input, right_bottom);
% Set Key listeners to figure
set(court, 'KeyPressFcn', @keyDown, 'KeyReleaseFcn', @keyUp);
% Update left and right paddle positions on figure
set(left_paddle, 'YData', [left_bottom (left_bottom + left_height)]);
set(right_paddle, 'YData', [right_bottom (right_bottom + right_height)]);
drawnow
end
% Function listening for keys being pressed
function keyDown(source, event)
if event.Key == 'q'
left_input = 1;
end
if event.Key == 'a'
left_input = -1;
end
if event.Key == 'o'
right_input = 1;
end
if event.Key == 'l'
right_input = -1;
end
end
% Function listening for keys being released
function keyUp(source, event)
if event.Key == 'q'
left_input = 0;
end
if event.Key == 'a'
left_input = 0;
end
if event.Key == 'o'
right_input = 0;
end
if event.Key == 'l'
right_input = 0;
end
end
% Function updating left paddle
function left_bottom = updateLeft(left_input, left_bottom)
if left_input == 1
left_bottom = left_bottom + .05;
elseif left_input == -1
left_bottom = left_bottom - .05;
end
end
% Function updating right paddle
function right_bottom = updateRight(right_input, right_bottom)
if right_input == 1
right_bottom = right_bottom + .05;
elseif right_input == -1
right_bottom = right_bottom - .05;
end
end
end