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