- /
-
Can It Run Doom?
on 27 Oct 2024
- 47
- 494
- 0
- 8
- 1983
Cite your audio source here (if applicable):
% Audio Source:
% Doom OST - E1M1 - At Doom's Gate
% https://youtu.be/BSsfjHCFosw
drawframe(29);
Write your drawframe function below
% This code pays homage to the legacy of DOOM,
% a game known for its impact on gaming history & its adaptability.
% and for being adapted to run on virtually any device imaginable.
% Also, I'm new to MATLAB so my code could be much better
function drawframe(f)
% function handles to reduce code length
L=@size;
r=@repmat;
g=@meshgrid;
n=@randn;
b=@abs;
% SOME USEFUL FUNCTIONS
% surf plot
s=@(X,Y,Z,C)surf(X,Y,Z,C,EdgeColor="none");
% creates the maze pattern for the door
m=@(A,B,D)occupancyMatrix(mapMaze(A,B,MapSize=L(D),MapResolution=1));
% tiles a 64x32 texture on a 2D matrix X
t=@(T,X)r(T,L(X)./[64 32]);
% to prevent rerender every frame
persistent o D
if isempty(o)
hold on;
% DEFINE GEOMETRY AND TEXTURES
% Floor Geometry
[X,Y,Z]=c(-14,17.99,.01,52);
q=b(X)<2&Y>12;
Z(q)=fix(Y(q)/2)-5;
Z(Y>24&Y>23+b(X/2))=7.1;
% Floor Texture
[j,i]=g(mod(1:512,32),mod(1:832,64));
S=24-b(i-24)==b(j-16)|48<i&i<65&j==16|16<i&i<33&~j;
S=(.1+.1*S).*(1-circshift(S,-2,2));
s(X,Y,Z,.1+r(S,[1,1,3])+r(peaks(64)/50,13,8,3)+n(L(Z))/50);
% Wall Texture 64x32
T=.6+zeros(64,32);
[j,i]=g(1:32,1:64);
T(i>29)=.6+cos(i(i>29))/4;
T(i>36&i<43)=.6;
q=mod(j+4,32)<9;
T(q)=T(q).*(.7-cos(.6*j(q))/5);
T(i>48)=.5;
T(i>56)=.4+cos(.6*i(i>56)-8)/5;
T=r(T+n(L(T))/50,[1 1 3])/2;
% Side wall geometry
[Y,Z]=c(0,51.99,0,19.99);
X=30-Y/2;
X(Y<48)=6;
X(Y<36)=10-4*(Y(Y<36)-29)/7;
X(Y<29)=10;
X(Y<28)=38-Y(Y<28);
X(Y<24)=14;
C=t(T,X); % Side wall texture
s(X,Y,Z,C); % on right
s(-X,Y,Z,C); % on left
% Stairs, platform wall and back wall
[X,Z]=c(0,11.99,.01,20);
Y=23+X/2;
Y(X<2)=11.97+2*fix(Z(X<2));
Y(Z>7)=52.3;
C=t(T,X); % Wall texture
% Stairs front texture
S=ones(96,32);
[j,i]=g(1:32,mod(1:96,16));
q=mod(i+3,16)<4;
S(q)=S(q)*.8;
S(i==7)=S(i==7)/.8;
S(i>7)=S(i>7).*(1+cos(.4*j(i>7))/6);
C(1:96,1:32,:)=(reshape([28*S 22*S 18*S],96,32,3)+n(96,32))/72;
s(X,Y-.2,Z,C); % on right
s(-X,Y-.2,Z,C); % on left
% Top wall
[X,Z]=c(-12,11.99,12,15.99);
s(X,max(24,23+b(X/2))-.2,Z,t(T,X));
% Door
[X,D,Y,C]=c(-4,4,0,8);
C=C+.25-(m(8,8,X)+m(3,1,X))/9+n(129)/50; % Door texture
o=s(X,Y,D,C); % Front door - the one that opens
s(X,52+Y,7+D,C); % Back door
% Roof
[X,Y]=c(-13.99,14,8.01,52);
Z=~~Y*14.5;
Z(Y>24&Y>23+b(X/2))=12;
Z(Y>36)=17;
s(X,Y,Z,r(reshape([6 7 5]/32,1,1,3),L(X))+(r(peaks(64),11,7,3)+n(L(Y)))/99);
% CAMERA AND OTHER SETTINGS
camproj('perspective');
axis equal;
camva(80);
% Black Bars at top and bottom
a=@(s)annotation('rectangle',[0,s,1,1/6],FaceColor='k');
a(0);
a(5/6);
end
% ANIMATION LOGIC
x=0:80; % the camera is in motion for 80 frames
% shows progress b/wetween 0 and 1,
% smoothed for eased start and stop of the camera
y=(x<17).*x.^2/2048+(16<x&x<64).*(x/8-1)/8+(63<x).*(5*x/8-17-x.^2/256)/8;
% The Y-coordinate(forward) of the camera based on the progress
Y(1:15)=-2;
Y(16:96)=y*52-2;
% The X-coordinate(right) of the camera based on Y
X=(Y-56)/3;
X(1:38)=(Y(1:38)-4)/3;
X(39:78)=4-Y(39:78)/5;
% Moving average of X to reduce jerk at turns
Xa(:)=X(:);
for i=30:83
Xa(i)=sum(X(i-5:i+5))/11;
end
% The variable to change the target of the camera
h=ones(96)/3;
h(34:43)=linspace(1/3,-.2,10);
h(44:73)=-.2;
h(74:83)=linspace(-.2,1/3,10);
% The Z-coordinate(up) of the camera to handle stairs
% and wave up-down for a walking motion
Z=2.5+max(0,min(Y(f)/2-6,7))-sin(.6*(Y(f)+2))/2;
% Move and point the camera
campos([Xa(f) Y(f) Z]);
camtarget([Xa(f)+h(f) Y(f)+1 Z])
% Open the front door
set(o,ZData=D+f/4);
end
% returns a meshgrid, height matrix & color matrix (for surf)
% for the required dimension
function [X,Y,Z,C]=c(x1,x2,y1,y2)
[X,Y]=meshgrid(x1:1/16:x2,y1:1/16:y2);
C=zeros([size(X),3]);
Z=C(:,:,1);
end