FPS_Sample

版本 1.0.0 (2.9 KB) 作者: Hernia Baby
How to create FPS by MATLAB
12.0 次下载
更新时间 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