Code covered by the BSD License  

Highlights from
BattleShip (R)

image thumbnail

BattleShip (R)

by

 

23 Oct 2008 (Updated )

Learn and have fun with an old classic.

ship(pos,type,orientation,ax)
function obj = ship(pos,type,orientation,ax)
%  	Author: Isaac Noh
%   Copyright 2008-2009 The MathWorks, Inc.
%   Version: 1.1


% "Constructor" for pseudo object SHIP

% Define the context menu
cmenu = uicontextmenu('Parent',get(ax,'Parent'));
% Define the context menu items
item1 = uimenu(cmenu, 'Label', 'rotate');

obj.type = type;
obj.orientation = orientation;

switch obj.type
    case 'pt'
        load ships pt;
        I = pt;
    case 'destroyer'
        load ships dest;
        I = dest;
    case 'sub'
        load ships sub;
        I = sub;
    case 'battleship'
        load ships bs;
        I = bs;
    case 'carrier'
        load ships car;
        I = car;
end

for i = 1:3
    I(:,:,i) = flipud(I(:,:,i));
    if strcmp(obj.orientation, 'vertical')
        rotI(:,:,i) = rot90(I(:,:,i),-1);
    end
end

if strcmp(obj.orientation, 'vertical')
    I = rotI;
end

obj.handle = surface(zeros(2),I,...
    'FaceColor','texturemap',...
    'EdgeColor','none',...
    'CDataMapping','direct',...
    'XData',[pos(1) (pos(1)+pos(3))],...
    'YData',[pos(2) (pos(2)+pos(4))],...
    'ButtonDownFcn',@MoveShip,...
    'UIContextMenu',cmenu,...
    'Parent',ax);

set(item1,'Callback', {@rotateShip, obj.handle});

set(gcf,'CurrentObject',obj.handle);
release([],[]);

% Methods for SHIP
obj.MoveShip = @MoveShip;
obj.UpdateShipPosition = @UpdateShipPosition;
obj.rotateShip = @rotateShip;

% Definition of methods
    function MoveShip(hObject, eventdata)
        ud = get(gcf, 'userdata');
        click = get(gca,'currentpoint');
        % get the first mouse click on the surface and save it
        ud.mouseClick = [click(1,1) click(1,2)];

        % set the callback so that mouse movement affects the
        % position of the surface
        set(gcf, 'WindowButtonMotionFcn', @UpdateShipPosition);
        set(gcf, 'WindowButtonUpFcn', @release);
        set(gcf, 'userdata', ud);
    end

    function UpdateShipPosition(hObject, eventdata)

        ud = get(gcf, 'userdata');

        % get the current click and difference it with the previous position
        click = get(gca,'currentpoint');

        % return if mouse pointer is out of axes bounds
        xlim = get(gca, 'xlim');
        ylim = get(gca, 'ylim');
        if click(1,1) < xlim(1) | xlim(2) < click(1,1)
            return;
        end
        if click(1,2) < ylim(1) | ylim(2) < click(1,2)
            return;
        end

        % difference the current mouse position with the previous position
        diff = [click(1,1)-ud.mouseClick(1) click(1,2)-ud.mouseClick(2)];
        ud.mouseClick = [click(1,1) click(1,2)];
        set(gcf, 'userdata', ud);

        % Add the difference in position to the surface
        v = get(gco, {'XData','YData'});
        v{1} = v{1}+diff(1);
        v{2} = v{2}+diff(2);
        set(gco, 'XData', [v{1}], 'YData', [v{2}]);
        drawnow;

    end

    function release(hObject, eventdata)

        if strcmp(get(gco, 'Type'),'surface')
            set(gcbf, 'WindowButtonMotionFcn','');
            rawPos = get(gco, {'XData', 'YData'});

            if rawPos{1}(1) < 0
                dif = -rawPos{1}(1);
                rawPos{1} = rawPos{1} + dif;
            elseif rawPos{1}(2) > 1
                dif = 1 - rawPos{1}(2);
                rawPos{1} = rawPos{1} + dif;
            end

            if rawPos{2}(1) < 0
                dif = -rawPos{2}(1);
                rawPos{2} = rawPos{2} + dif;
            elseif rawPos{2}(2) > 1
                dif = 1 - rawPos{2}(2);
                rawPos{2} = rawPos{2} + dif;
            end

            % Snap the ships to the grid
            snapPos{1} = round(10*rawPos{1})/10;
            snapPos{2} = round(10*rawPos{2})/10;

            feature('accel','off')
            set(gco, 'XData', snapPos{1}, 'YData', snapPos{2});
            feature('accel','on')
            drawnow;

        else
            return
        end
    end

    function rotateShip(hObject, eventdata, h)
        clear rotI;
        xpos = get(h, 'XData');
        ypos = get(h, 'YData');
        set(h,'XData',[xpos(1) (xpos(1) + abs(diff(ypos)))],...
            'YData',[ypos(1) (ypos(1) + abs(diff(xpos)))]);
        I = get(h,'CData');

        for i = 1:3
            rotI(:,:,i) = rot90(I(:,:,i),1);
        end
        I = rotI;

        set(h,'CData',I);
        release(h,[]);
        drawnow;
    end

end

Contact us