2-D Ping Pong Game.
Add files for the ball and bat. Enjoy!
%By vkc
function RunGame
hMainWindow = figure(...
'Color', [1 1 1],...
'Name', 'Game Window',...
'Units', 'pixels',...
'Position',[100 100 800 500]);
img = imread('ball.bmp','bmp');
[m,n,c] = size(img);
hBall = axes(...
'parent', hMainWindow,...
'color', [1 1 1],...
'visible', 'off',...
'units', 'pixels',...
'position', [345, 280, n, m] );
hBallImage = imshow( img );
set(hBallImage, 'parent', hBall, 'visible', 'off' );
ballSpeed = 3;
ballDirection = 0;
hTempBall = axes( ...
'parent', hMainWindow,...
'units', 'pixels',...
'color', 'none',...
'visible', 'off',...
'position', get(hBall, 'position' ) );
img = imread('paddle.bmp','bmp');
[m,n,c] = size(img);
hRightPaddle = axes(...
'parent', hMainWindow,...
'color', 'none',...
'visible', 'off',...
'units', 'pixels',...
'position', [650 - 10, 250 - 50, n, m] );
hRightPaddleImage = imshow( img );
set(hRightPaddleImage, 'parent', hRightPaddle, 'visible', 'off' );
targetY = 200;
t = timer( 'TimerFcn', @UpdateRightPaddleAI,...
'StartDelay', 10 );
start(t)
hLeftPaddle = axes(...
'parent', hMainWindow,...
'color', 'none',...
'visible', 'off',...
'units', 'pixels',...
'position', [50, 250 - 50, n, m] );
hLeftPaddleImage = imshow( img );
set(hLeftPaddleImage, 'parent', hLeftPaddle, 'visible', 'off' );
hBottomWall = axes(...
'parent', hMainWindow,...
'color', [1 1 1],...
'units', 'pixels',...
'visible', 'off',...
'position', [0 40 700 10] );
patch( [0 700 700 0], [0 0 10 10], 'b' );
hTopWall = axes(...
'parent', hMainWindow,...
'color', [1 1 1],...
'units', 'pixels',...
'visible', 'off',...
'position', [0 450 700 10] );
patch( [0 700 700 0], [0 0 10 10], 'b' );
rightScore = 0;
leftScore = 0;
hRightScore = axes(...
'parent', hMainWindow,...
'color', 'none',...
'visible', 'off',...
'units', 'pixels',...
'position', [650 485 50 10] );
hLeftScore = axes(...
'parent', hMainWindow,...
'color', 'none',...
'visible', 'off',...
'units', 'pixels',...
'position', [30 485 50 10] );
hRightScoreText = text( 0, 0, '0', 'parent', hRightScore,...
'visible', 'on', 'color', [1 1 1] );
hLeftScoreText = text( 0, 0, '0', 'parent', hLeftScore,...
'visible', 'on', 'color', [1 1 1] );
hQuitButton = uicontrol(...
'string', 'Quit',...
'position', [325 475 50 20],...
'Callback', @QuitButton_CallBack );
hStartButton = uicontrol(...
'string', 'Start',...
'position', [325 240 50 20],...
'Callback',@StartButton_CallBack );
playing = true;
while playing == true
UpdateBall()
UpdateLeftPaddle()
UpdateRightPaddle()
CheckForScore()
pause( 0.01 )
end
stop(t)
close( hMainWindow )
function UpdateBall
pos = get( hBall, 'position' );
ballX = pos(1,1);
ballY = pos(1,2);
ballDirection = NormalizeAngle( ballDirection );
% check for collisions with the walls
if ( ballY > 450 - 10 ) && ( ballDirection > 0 ) && ( ballDirection < 180 )
if ( ballDirection > 90 )
ballDirection = ballDirection + 2 * ( 180 - ballDirection );
else
ballDirection = ballDirection - 2 * ballDirection;
end
elseif ( ballY < 50 ) && ( ballDirection > 180 ) && ( ballDirection < 360 )
if ( ballDirection > 270 )
ballDirection = ballDirection + 2 * ( 360 - ballDirection );
else
ballDirection = ballDirection - 2 * ( ballDirection - 180 );
end
end
% check for collisions with the paddles
if ( ballDirection > 90 && ballDirection < 270 )
leftPaddlePos = get( hLeftPaddle, 'position' );
leftX = leftPaddlePos(1,1);
leftY = leftPaddlePos(1,2);
if( (ballX < leftX + 10)...
&& (ballX > leftX + 5)...
&& (ballY + 10 > leftY)...
&& (ballY < leftY + 100) )
if ( ballDirection < 180 )
ballDirection = 180 - ballDirection;
elseif( ballDirection > 180 )
ballDirection = 180 - ballDirection;
end
end
else
rightPaddlePos = get( hRightPaddle, 'position' );
rightX = rightPaddlePos(1,1);
rightY = rightPaddlePos(1,2);
if( (ballX + 10 > rightX)...
&& (ballX + 10 < rightX + 5)...
&& (ballY > rightY)...
&& (ballY < rightY + 100) )
if ( ballDirection < 90 )
ballDirection = 180 - ballDirection;
elseif( ballDirection > 270 )
ballDirection = 180 - ballDirection;
end
end
end
MoveObject( hBall, ballSpeed, ballDirection );
end
function UpdateRightPaddle()
speed = 5;
pos = get( hRightPaddle, 'position' );
rightY = pos(1,2);
if( rightY + 5 < targetY - 50 && rightY < 400 - 50 )
MoveObject( hRightPaddle, speed, 90 )
elseif( rightY - 5 > targetY - 50 && rightY > 50 )
MoveObject( hRightPaddle, speed, 270 )
end
pos = get( hRightPaddle, 'position' );
rightY = pos( 1,2);
if( rightY > 400 - 50 )
rightY = 350;
elseif( rightY < 50 )
rightY = 50;
end
if( strcmp( get( t, 'Running' ), 'off' ) )
start(t)
end
end
function UpdateRightPaddleAI( ob, data )
% calculate where the ball will colide.
tempBallDirection = NormalizeAngle( ballDirection );
if( tempBallDirection < 90 || tempBallDirection > 270 && ballSpeed > 0 )
ballPos = get( hBall, 'position' );
set( hTempBall, 'position', ballPos );
ballX = ballPos(1,1);
while( ballX < 650 - 10 )
ballPos = get( hTempBall, 'position' );
ballX = ballPos(1,1);
ballY = ballPos(1,2);
MoveObject( hTempBall, 20, tempBallDirection )
% check for temp ball collision with walls.
if ( ballY > 450 - 10 )
if ( tempBallDirection > 0 )
if ( tempBallDirection < 180 )
tempBallDirection = 360 - tempBallDirection;
end
end
elseif ( ballY < 60 )
if( tempBallDirection > 180 )
if( tempBallDirection < 360 )
tempBallDirection = 360 - tempBallDirection;
end
end
end
% line( 0, 0, 'marker', '*', 'parent', hTempBall )
% pause( 0.0005 )
end
pos = get( hTempBall, 'position' );
ballY = pos(1,2);
targetY = ballY + ( rand * 150 ) - 75;
end
end
function UpdateLeftPaddle()
scr = get( hMainWindow, 'position' );
screenX = scr(1,1);
screenY = scr(1,2);
screenH = scr(1,4);
mouse = get(0, 'PointerLocation' );
y = mouse(1,2) - screenY;
if( y > 100 && y < 400 )
paddlePos = get( hLeftPaddle, 'position' );
paddlePos(1,2) = y - 50;
set( hLeftPaddle, 'position', paddlePos );
elseif( y > 400 )
paddlePos = get( hLeftPaddle, 'position' );
paddlePos(1,2) = 400 - 50;
set( hLeftPaddle, 'position', paddlePos );
elseif( y < 100 )
paddlePos = get( hLeftPaddle, 'position' );
paddlePos(1,2) = 100 - 50;
set( hLeftPaddle, 'position', paddlePos );
end
end
function CheckForScore()
pos = get( hBall, 'position' );
xpos = pos(1,1);
ypos = pos(1,2);
if ( xpos < 5 )
set( hBallImage, 'visible', 'off' )
rightScore = rightScore + 1;
set ( hRightScoreText, 'string', num2str( rightScore ) )
pause( .5 )
ResetBall()
elseif ( xpos + 10 > 695 )
set( hBallImage, 'visible', 'off' )
leftScore = leftScore + 1;
set ( hLeftScoreText, 'string', num2str( leftScore ) )
pause( .5 )
ResetBall()
end
end
function ResetBall
pos = get( hBall, 'position' );
pos(1,1) = 345;
pos(1,2) = 255 + floor( rand*100 ) - 50;
set( hBall, 'position', pos )
ballSpeed = 4;
ballDirection = ( (rand(1) < 0.5) * 180 ) ... % 0 or 180
+ ( 45 + (rand(1) < 0.5) * -90 ) ... % + 45 or - 45
+ ( floor( rand * 40 ) - 20 ); % + -20 to 20
set( hBallImage, 'visible', 'on' )
pause(1)
end
function MoveObject( hInstance, speed, direction )
p = get( hInstance, 'position' );
x = p( 1, 1 );
y = p( 1, 2 );
x = x + cosd( direction ) * speed;
y = y + sind( direction ) * speed;
p( 1, 1 ) = x;
p( 1, 2 ) = y;
set( hInstance, 'position', p )
end
function SetObjectPosition( hObject, x, y )
pos = get( hObject, 'position' );
pos(1,1) = x;
pos(1,2) = y;
set( hObject, 'position', pos )
end
function a = NormalizeAngle( angle )
while angle > 360
angle = angle - 360;
end
while angle < 0
angle = angle + 360;
end
a = angle;
end
function QuitButton_CallBack( hObject, eventData )
playing = false;
end
function StartButton_CallBack( hObject, eventData )
set( hObject, 'visible', 'off' );
set( hLeftPaddleImage, 'visible', 'on' )
set( hRightPaddleImage, 'visible', 'on' )
ResetBall();
end
end