I was asked to post my code to make the air hockey game from last year. Looking back, the code was atrocious. So I went back and rewrote it.

If you’d like to run the code, then just copy and paste the code into their own files. There are four in total, and they should be named all in lowercase. Make sure that all the files are in the same directory, and then just run “main.m”.

Index

main.m

close all
clear
clc

% ========================================================================

count = -10;        % Starting score
t = 120;            % Game length
num_pucks = 4;      % Number of pucks

% ========================================================================

h = figure;
walls = [0 500 0 500];
axis(walls);

% Initialize objects
pucks(num_pucks) = puck();
for ii = 1:num_pucks
    pucks(ii) = puck();
end
curs = cursor();
goal_1 = goal([250 450]);
goal_2 = goal([250 50]);

done = false;
won = false;

while ~done
    
    % Update the cursor's position
    curs = update(curs);
    
    % Update the pucks' position
    for ii = 1:num_pucks
        [pucks(ii) count] = update(pucks(ii), curs, walls, ...
            goal_1, goal_2, count);
    end
    
    % Plot objects
    plot(curs)
    hold on
    for ii = 1:num_pucks
        plot(pucks(ii))
    end
    plot(goal_1)
    plot(goal_2)
    hold off
    axis(walls);
    title({int2str(count); ['Time: ' num2str(t)]})
    
    % Ending conditions
    if t < 0
        done = true;
        
        if count > 0
            won = true;
        end
    end
    
    % Time decrement
    t = t - 0.1;
    
    pause(0.01)
end

if won
    disp('You Won!')
else
    disp('You Lost!')
end

close all

Return to index

puck.m

classdef puck
    properties
        x_pos
        y_pos
        x_dot
        y_dot
        on
    end
    
    methods
        function b = puck()
            b.x_pos = 250;
            b.y_pos = 250;
            

            if rand() < 0.5
                b.x_dot = floor(rand()*5 + 5);
            else
                b.x_dot = -1*floor(rand()*5 + 5);
            end
            
            if rand() < 0.5
                b.y_dot = floor(rand()*5 + 5);
            else
                b.y_dot = -1*floor(rand()*5 + 5);
            end
            
            b.on = true;
        end
        
        function [b count] = update(b, c, walls, br_1, br_2, count)
            b.x_pos = b.x_pos + b.x_dot;
            b.y_pos = b.y_pos + b.y_dot;
            
            % Wall collision
            if (b.x_pos > walls(2)) || (b.x_pos < walls(1))
                b.x_dot = -1*b.x_dot;
            end
            
            if (b.y_pos > walls(4)) || (b.y_pos < walls(3))
                b.y_dot = -1*b.y_dot;
            end
            
            % Cursor collision
            x_delt = b.x_pos - c.x_pos;
            y_delt = b.y_pos - c.y_pos;
            dist = sqrt(x_delt^2 + y_delt^2);

            if dist < 25
                b.x_dot = x_delt*10/dist;
                b.y_dot = y_delt*10/dist;
            end
            
            % Brick collision
            if (abs(b.x_pos - br_1.x_cen) < 110) && ...
                    (abs(b.y_pos - br_1.y_cen) < 4)
                count = count + 1;
                b.y_dot = -1*b.y_dot;
            end
            
            if (abs(b.x_pos - br_2.x_cen) < 110) && ...
                    (abs(b.y_pos - br_2.y_cen) < 4)
                count = count - 1;
                b.y_dot = -1*b.y_dot;
            end
        end
        
        function plot(b)
            if b.on
                plot(b.x_pos, b.y_pos, 'ro', 'markerfacecolor', 'r')
            end
        end
    end
end

Return to index

cursor.m

classdef cursor
    properties
        x_pos = 0
        y_pos = 0
    end
    
    methods
        function b = cursor()
            set(gcf, 'WindowButtonMotionFcn', @cursor.movement)
        end
        
        function b = update(b)
            pt = get(gcf, 'UserData');
            
            if ~isempty(pt)
                b.x_pos = pt(1, 1);
                b.y_pos = pt(1, 2);
            end
            
            if b.x_pos < 0
                b.x_pos = 0;
            elseif b.x_pos > 500
                b.x_pos = 500;
            end
            
            if b.y_pos < 0
                b.y_pos = 0;
            elseif b.y_pos > 250
                b.y_pos = 250;
            end
        end
        
        function plot(curs)
            plot(curs.x_pos, curs.y_pos, 'bo', 'markerfacecolor', 'b', ...
                'markersize', 25)
        end
    end
    
    methods (Static)
        function movement(src, evnt) %#ok<INUSD>
            pt = get(gca, 'CurrentPoint');
            set(gcf, 'UserData', pt);
        end
    end
end

Return to index

goal.m

classdef goal
    properties
        x_pos
        y_pos
        x_cen
        y_cen
        on
    end
    
    methods      
        function b = goal(pos)
            b.x_pos = [...
                pos(1)-100 ...
                pos(1)-100 ...
                pos(1)+100 ...
                pos(1)+100 ...
                pos(1)-100];
            b.y_pos = [...
                pos(2)-2 ...
                pos(2)+2 ...
                pos(2)+2 ...
                pos(2)-2 ...
                pos(2)-2];
            b.x_cen = pos(1);
            b.y_cen = pos(2);
            b.on = true;
        end
        
        function plot(b)
            plot(b.x_pos, b.y_pos, 'k-')
        end
    end
end

Return to index

Advertisements