Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

(Help again) My main issue is that none of the functions (isColliding and handlemalletcollision) are called into the main code so it isn't doing anything.

(Help again) My main issue is that none of the functions (isColliding and handlemalletcollision) are called into the main code so it isn't doing anything. The functions are unused. They told me to add them into the main code for them to work but I'm unsure of how to do that, every time I mess around with it, my code breaks. Please help. This is a MATLAB code and please write out the full code and explain how and why you did what you did. THANK YOU. They said the main issue is in the collision part of the while loop.

My 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

I submitted this earlier but they didn't help me at all, please show how you integrated it INTO the while loop and not just fix the function itself. but also if there is an issue in the function please fix it.

Thank you

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Big Data Fundamentals Concepts, Drivers & Techniques

Authors: Thomas Erl, Wajid Khattak, Paul Buhler

1st Edition

0134291204, 9780134291208

More Books

Students also viewed these Databases questions

Question

=+b. Who would the brand be as a famous person?

Answered: 1 week ago