FPS_Sample

버전 1.0.0 (2.87 KB) 작성자: Hernia Baby
How to create FPS by MATLAB
다운로드 수: 12
업데이트 날짜: 2022/5/16

라이선스 보기

If you want to change the wall, you can change pos_wall parameter.
function test_FPS
clear,clc,close all;
m=200;
% Wall Samples
% pos_wall = [50 50; 100 300; 250 200; 50 50]+100;
p = nsidedpoly(50, 'Center', [200 200], 'Radius', 100);
pos_wall = [p.Vertices;p.Vertices(1,:)];
% Player 1st position
player.pos = [10,10];
player.angle = 45;
Angle = 30;
dAngle = 10;
n = 21;
% Generate an arc and line segments
th = deg2rad(linspace(player.angle - Angle,player.angle + Angle,n))';
r = 100;
v = r.*[cos(th),sin(th)];
p2 = v + player.pos;
% Intersection calculation(1st step)
% Mapping Toolbox --> polyxpoly
% Free: https://jp.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections
x = reshape(([repelem(player.pos(1),height(p2))',p2(:,1),nan(height(p2),1) ])',[],1);
y = reshape(([repelem(player.pos(2),height(p2))',p2(:,2),nan(height(p2),1) ])',[],1);
[xi,yi,kk] = polyxpoly(x,y,pos_wall(:,1),pos_wall(:,2));
% Wall for Bird's eye view
Wallx = (1:height(p2))';
% Calculate only in front
dummy = Wallx.*(4-1) + 1;
dummy = [1 ; dummy(1:end-1)];
Wally = nan(height(p2),1);
th2 = -deg2rad(linspace(-Angle,Angle,n))';
K = 3; % Fix parameter: 4-1
%% Plot
%% 1. Bird's eye view
f = figure('Color','#AAAAAA');
ax = axes('Color','#AAAAAA');
ax.Title.String = "Bird's eye view";
text(350,350,["r:ClockWise";"e:CounterClockWise";"a:ZoomIn";"s:ZoomOut"]);
axis off
hold on
% Wall
wall = fill(ax,pos_wall(:,1),pos_wall(:,2),'k',LineStyle='none');
axis equal
ax.XLim = [0 400];
ax.YLim = [0 400];
% Player1: Position
pl = plot(ax,player.pos(1), player.pos(2),'o', ...
MarkerFaceColor='y',MarkerEdgeColor='none',...
MarkerSize=5);
% Player2: Arc
pl1 = plot(ax,p2(:,1),p2(:,2),'LineStyle','-', ...
'LineWidth',1,'Color','y');
% Player3: Line segments
for ii = 1:height(p2)
pl2(ii) = plot(ax,[player.pos(1);p2(ii,1)],...
[player.pos(2); p2(ii,2)],'LineStyle','--', ...
'LineWidth',1,'Color','y');
end
tmp1 = [xi;nan(height(p2)-length(xi),1)]';
tmp2 = [yi;nan(height(p2)-length(yi),1)]';
% Collision detection
pl3 = plot(ax,tmp1,tmp2,'o', ...
LineStyle='none', ...
MarkerFaceColor='r',MarkerEdgeColor='none',...
MarkerSize=5);
hold off
%% 2. First person perspective
f_FPS = figure('Color','#AAAAAA');
ax_FPS = axes('Color','#AAAAAA');
ax_FPS.Title.String = "First person perspective";
hold on
pl_FPS_p = stem(ax_FPS,-Wallx,Wally./2,'Marker','none','LineWidth',round(m/n),'Color','w');
pl_FPS_n = stem(ax_FPS,-Wallx,-Wally./2,'Marker','none','LineWidth',round(m/n),'Color','w');
ax_FPS.XLim = [-(height(Wallx)+1) 0];
% Wall Max Height
ax_FPS.YLim = [-1 1].*K*2;
% Visualise
ax_FPS.XTick = [];
ax_FPS.YTick = [];
ax_FPS.XAxis.Color = 'none';
ax_FPS.YAxis.Color = 'none';
hold off
%% Trigger
f.WindowButtonDownFcn = @motion;
f.WindowButtonUpFcn = @motion;
f.KeyPressFcn = @rotation;
%% Nested function
%% Rotation
function rotation(src,data,eventdata)
if strcmp(data.Key,'r')
th = th + deg2rad(dAngle);
elseif strcmp(data.Key,'e')
th = th - deg2rad(dAngle);
end
if strcmp(data.Key,'a')
r = r + 10;
elseif strcmp(data.Key,'s')
r = r - 10;
end
v = r*[cos(th),sin(th)];
movepoint;
end
%% Mouse Click
function motion(src,data,eventdata)
if strcmp(data.EventName,'WindowMousePress')
f.WindowButtonMotionFcn = @movepoint;
else
f.WindowButtonMotionFcn = '';
end
end
%% Position update
function movepoint(src,data)
pos = get(gca,'CurrentPoint');
pl.XData = pos(1,1);
pl.YData = pos(1,2);
pl1.XData = v(:,1) + pl.XData;
pl1.YData = v(:,2) + pl.YData;
player.pos = pos(1,1:2);
p2 = [pl1.XData; pl1.YData]';
Cross;
for ii = 1:length(pl2)
pl2(ii).XData = [0, v(ii,1)] + pl.XData;
pl2(ii).YData = [0, v(ii,2)] + pl.YData;
end
end
%% Collision detection
function Cross
x = reshape(([repelem(player.pos(1),height(p2))',p2(:,1),nan(height(p2),1) ])',[],1);
y = reshape(([repelem(player.pos(2),height(p2))',p2(:,2),nan(height(p2),1) ])',[],1);
[xi,yi,kk] = polyxpoly(x,y,pos_wall(:,1),pos_wall(:,2));
% Vector from plyer to cross point
tmp = [xi,yi] - player.pos;
% extract more closer point when line segment has 2 cross points
tmp = [xi, yi, (tmp(:,1).^2+tmp(:,2).^2), kk(:,1), false(length(xi),1)];
t1 = unique(tmp(:,4));
for jj = 1:length(t1)
MIN_tmp = min(tmp(tmp(:,4) == t1(jj),3));
tmp( (tmp(:,4)==t1(jj)) & (tmp(:,3)==MIN_tmp) ,end) = true;
end
% point y
idx = tmp(:,end)==true;
% extract xi and yi
tmp = tmp(idx,[1:4]);
[~,I] = sort(tmp(:,4));
tmp = tmp(I,:);
xi = tmp(:,1);
yi = tmp(:,2);
idx2 = ismember(dummy,tmp(:,4));
Wallx = (1:height(p2))';
Wally = nan(height(p2),1);
Wally(find(idx2)) = sqrt(tmp(:,3)./r.^2); %norm length
Wally = Wally.*cos(th2);
pl_FPS_p.YData = K./Wally./2;
pl_FPS_n.YData = -K./Wally./2;
pl3.XData = [xi;nan(height(p2)-length(xi),1)]';
pl3.YData = [yi;nan(height(p2)-length(yi),1)]';
end
end

인용 양식

Hernia Baby (2024). FPS_Sample (https://www.mathworks.com/matlabcentral/fileexchange/111640-fps_sample), MATLAB Central File Exchange. 검색 날짜: .

MATLAB 릴리스 호환 정보
개발 환경: R2022a
모든 릴리스와 호환
플랫폼 호환성
Windows macOS Linux
태그 태그 추가

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
버전 게시됨 릴리스 정보
1.0.0