Question: Create a structure chart with the following MATLAB code: function air_hockey_rink() % figure and axes fig = figure('Name', 'Air Hockey', 'NumberTitle', 'off', 'KeyPressFcn', @keypress_callback); ax

Create a structure chart with the following MATLAB code:

function air_hockey_rink()

% figure and axes

fig = figure('Name', 'Air Hockey', 'NumberTitle', 'off', 'KeyPressFcn', @keypress_callback);

ax = axes('XLim', [0, 100], 'YLim', [0, 50], 'Position', [0, 0, 1, 1]);

axis off; hold on; axis equal;

% rink definitions

rectangle('Position', [10, 5, 80, 40], 'EdgeColor', 'b', 'LineWidth', 2, 'FaceColor', 'w');

% middle line definition

line([50, 50], [5, 45], 'Color', 'k', 'LineWidth', 2);

% Circle in the middle of the rink

circleRadius = 5; % Set the radius of the circle

circleDiameter = circleRadius * 2;

circleX = 50 - circleRadius; % X position

circleY = 25 - circleRadius; % Y position

rectangle('Position', [circleX, circleY, circleDiameter, circleDiameter], 'Curvature', [1, 1], 'EdgeColor', 'k', 'LineWidth', 2);

% goal definitions

goalWidth = 12;

rectangle('Position', [10, 20, 3, goalWidth], 'EdgeColor', 'b', 'FaceColor', 'b');

rectangle('Position', [87, 20, 3, goalWidth], 'EdgeColor', 'r', 'FaceColor', 'r');

% mallets and puck

userMallet = rectangle('Position', [20, 25, 6, 6], 'Curvature', [1, 1], 'FaceColor', 'b');

oppMallet = rectangle('Position', [75, 25, 6, 6], 'Curvature', [1, 1], 'FaceColor', 'r');

puck = rectangle('Position', [47.5, 22.5, 5, 5], 'Curvature', [1, 1], 'FaceColor', [0.5, 0.5, 0.5]);

% scores

user_Score = 0;

opp_Score = 0;

% score board

scoreText = text(50, 2, 'Score: 0 - 0', 'HorizontalAlignment', 'center', 'FontSize', 14, 'FontWeight', 'bold');

% movement variables

malletSpeed = 2;

puckSpeed = [0, 0]; % initial speed in x and y directions

puckState = 'stationary'; % puck is still

% opponent movement

oppDirection = 1; % 1 for right, -1 for left

oppSpeed = 0.75; % speed of the opponent's mallet

% keypress_callback function

function keypress_callback(~, event)

switch event.Key

case 'leftarrow'

% prevent moving left beyond the left boundary

userMallet.Position(1) = max(userMallet.Position(1) - malletSpeed, 10);

case 'rightarrow'

% calculate the right boundary for the mallet

rightBoundary = 50 - userMallet.Position(3); % prevent from crossing middle line

newPosX = min(userMallet.Position(1) + malletSpeed, rightBoundary);

userMallet.Position(1) = newPosX;

case 'uparrow'

userMallet.Position(2) = min(userMallet.Position(2) + malletSpeed, 40);

case 'downarrow'

userMallet.Position(2) = max(userMallet.Position(2) - malletSpeed, 5);

end

end

% main game loop

while ishandle(fig)

% update puck position if it's 'moving'

if strcmp(puckState, 'moving')

puck.Position(1:2) = puck.Position(1:2) + puckSpeed;

end

% collision with walls

if puck.Position(1) <= 10 || puck.Position(1) >= 85

puckSpeed(1) = -puckSpeed(1);

end

if puck.Position(2) <= 5 || puck.Position(2) >= 40

puckSpeed(2) = -puckSpeed(2);

end

% move opponent mallet up and down

oppMallet.Position(2) = oppMallet.Position(2) + oppSpeed * oppDirection;

if oppMallet.Position(2) <= 5 || oppMallet.Position(2) >= 40

oppDirection = -oppDirection;

end

% collision with usermallet

if strcmp(puckState, 'moving') || strcmp(puckState, 'stationary')

if abs(puck.Position(1) - userMallet.Position(1)) < 5 && ...

abs(puck.Position(2) - userMallet.Position(2)) < 5

puckSpeed = [1,-1];

puckState = 'moving';

end

end

% collision with oppmallet

if abs(puck.Position(1) - oppMallet.Position(1)) < 5 && ...

abs(puck.Position(2) - oppMallet.Position(2)) < 5

% trigger a bounce off the opponent's mallet

puckSpeed = [-1, randi([-1,1])];

puckState = 'moving';

end

% goal detection

if puck.Position(1) <= 13 && puck.Position(2) > 20 && puck.Position(2) < 30

opp_Score = opp_Score + 1;

resetPuck();

elseif puck.Position(1) >= 82 && puck.Position(2) > 20 && puck.Position(2) < 30

user_Score = user_Score + 1;

resetPuck();

end

% update score display

scoreText.String = sprintf('Score: %d - %d', user_Score, opp_Score);

% pause

pause(0.03);

end

% reset puck

function resetPuck()

% place the puck in front of the user/opponent who was scored upon

if user_Score > opp_Score

% place the puck near the opponent

puck.Position = [75, 25, 5, 5];

else

% place the puck near the player

puck.Position = [25, 25, 5, 5];

end

puckSpeed = [0, 0]; % puck is still until hit by the mallet

puckState = 'stationary';

end

end

% collision detection function

function isColliding = isCollisionDetected(puck, mallet)

distance = sqrt((puck.position.x - mallet.position.x)^2 + (puck.position.y - mallet.position.y)^2);

isColliding = distance < (puck.radius + mallet.radius);

end

% handleMalletCollision function

function [newVp, newVb] = handleMalletCollision(puck, mallet)

% extract position and velocity components of puck and mallet

xp1 = puck.position.x;

yp1 = puck.position.y;

Vp1 = puck.velocity;

Vp1_mag = norm(Vp1);

xb1 = mallet.position.x;

yb1 = mallet.position.y;

Vb1 = mallet.velocity;

Vb1_mag = norm(Vb1);

rp = puck.radius; % puck radius

rb = mallet.radius; % mallet radius

% calculate angles for collision

theta = -atan2(yb1 - yp1, xb1 - xp1);

alpha = atan2(Vb1(2), Vb1(1));

beta = atan2(Vp1(2), Vp1(1));

% Remove any overlap between puck and blocker

xp2 = xb1 - (rp + rb) * cos(theta);

yp2 = yb1 + (rp + rb) * sin(theta);

% calculate normal and tangential components of velocity before collision

Vb1n = Vb1_mag * cos(theta + alpha);

Vb1s = Vb1_mag * sin(theta + alpha);

Vp1n = Vp1_mag * cos(theta + beta);

Vp1s = Vp1_mag * sin(theta + beta);

% masses of puck and mallet

mp = puck.mass;

mb = mallet.mass;

% total momentum and kinetic energy before the collision

P1n = mp * Vp1n + mb * Vb1n;

KE1 = 0.5 * mp * Vp1_mag^2 + 0.5 * mb * Vb1_mag^2;

% coefficients for the quadratic equation

a = mp^2 + mp * mb / mb;

b = -2 * P1n * mp / mb;

c = P1n^2 / mb + mp * Vp1s^2 + mb * Vb1s^2 - 2 * KE1;

% solve the quadratic equation for Vp2n

Vp2n = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a);

% new velocity of the blocker in the normal direction

Vb2n = (P1n - mp * Vp2n) / mb;

% new velocities in the tangential direction

Vp2s = Vp1s;

Vb2s = Vb1s;

% calculate the final speeds and angles

Vp2_mag = sqrt(Vp2n^2 + Vp2s^2);

beta2 = atan2(Vp2s, Vp2n) - theta;

Vb2_mag = sqrt(Vb2n^2 + Vb2s^2);

alpha2 = atan2(Vb2s, Vb2n) - theta;

% convert back to x and y components

newVp = [Vp2_mag * cos(beta2), Vp2_mag * sin(beta2)];

newVb = [Vb2_mag * cos(alpha2), Vb2_mag * sin(alpha2)];

end

% reset puck position after a goal

function resetPuck()

puck.position.x = 50;

puck.position.y = 25;

puck.velocity = [0, 0];

end

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!