FPS_Sample

バージョン 1.0.0 (2.87 KB) 作成者: Hernia Baby
How to create FPS by MATLAB
ダウンロード: 14
更新 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 (2025). 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