snake game

‘animatedline’ is really useful for animations. This script makes a snake that moves around the figure. Press the up, down, left, right keyboard buttons to direct the snake. If snake leaves the figure, the figure window closes.

% Animated Snake {Silas Henderson 12/26/2018}
% Press up,down,left,right keys. Fig closes if snake leaves fig

clear; clc; clf; global snakeVel;
% --------------------------- setup ---------------------------- %
set(gcf,'color',  [.7 .7 .9],'KeyPressFcn',@controls,.. %fig/ax      
        'units','normalized',   'position',[ .1  .1  .8 .75])

set(gca,'units','normalized',  'position',[.02 .02 .96 .96],... 
    'gridcolor',     [1 1 0],     'color',          [0 0 0],...
   'XTickLabel',          [],'YTickLabel',               [])
hold on; grid on; axis([0 100 0 100]);

dt        =     .02;
snakePos  = [50;50];                                    % snake
snakeVel  =   [1;0];
snakeLine = animatedline('MaximumNumPoints',200,...
    'color','red','linewidth',2);

% -------------------------- main loop ------------------------- %
while numel(snakePos(snakePos <   0)) + ...             % posCheck
      numel(snakePos(snakePos > 100)) == 0    
    dt = dt + .001;
    snakePos = snakePos + snakeVel*dt;
    addpoints(snakeLine,snakePos(1),snakePos(2));
    pause(.01);
end
close all;

% ------------------------ function(s) ------------------------- %
function controls(~,event)                              % buttons
global snakeVel
switch event.Key
    case 'downarrow'
        snakeVel = [ 0;-1];
    case 'uparrow'
        snakeVel = [ 0; 1];
    case 'leftarrow'
        snakeVel = [-1; 0];
    case 'rightarrow'
        snakeVel = [ 1; 0];
end
end

Advertisements

planets

The ‘multi-body problem’ is about dealing with gravity when there are a lot of objects all doing gravity at each-other. This script shows an animation of the ‘multi-body problem’. Change number of planets with ‘n=’ and animation time with ‘while toc < …’

%  planets {Silas Henderson 12/26/2018}
% [place some planets in space and see what happens]

clear; clc; clf;
% -------------------------- setup ---------------------------- %
set(gcf,'color',[.7 .7 .9])                             % figure
set(gca,'gridcolor',[1 1 0],'color',[0 0 0])            % axis
hold on; grid on; axis([-4 4 -4 4 -4 4]);

n  =                  50;                               % data
m  =      1000*rand(1,n);                     
x  = rand(3,n)-rand(3,n);     
v  =          zeros(3,n);   
dt =              .00005; 

for e = 1:n                                             % markers
    planets(e) = plot3(x(1,e),x(2,e),x(3,e),'o',...
        'markersize',m(e)/100,'markerfacecolor',rand(1,3));
end

% -------------------------- main loop ------------------------ % 
tic;
while toc < 8
    view(10*toc,30)                                     % rotate
    planets = plotUpdate(planets,x);                    % update
    [x,v]   = dataUpdate(x,v,m,dt);
    pause(.02); 
end

% ------------------------- functions ------------------------ %
function planets = plotUpdate(planets,x)                
for e = 1:length(x)
    set(planets(e),'XData',x(1,e),'YData',x(2,e),'ZData',x(3,e));
end
end

function [x,v] = dataUpdate(x,v,m,dt)                   
for i = 1:length(x)                                     % eulerSI 
    a(:,i) = zeros(3,1);
    for j = 1:length(m)                                 
        if i ~= j
            a(:,i) = a(:,i) + m(j).*(x(:,j) - x(:,i))./...
                (norm(x(:,j) - x(:,i))^3 + .5);
        end
        v(:,i) = v(:,i) + a(:,i)*dt;
        x(:,i) = x(:,i) + v(:,i)*dt;
    end
end
end

animated Q*R

Q*R decomposition breaks a matrix into 2 easier-to-digest parts. This script shows what happens when you take a pre-cooked QR and start removing rows and columns. Put the script and an image in the same folder, change the ‘image =’ line and run.

% QRAnimate {Silas Henderson,11/11/2018}
% Place image in same folder as script --> animate QR decomp.  

clear; clc; clf;
% --------------------------- setup ------------------------- %
image = 'logo.jpg';                             
A = im2double(rgb2gray(imread(image)));         % import image
n = min(size(A));  A = A(1:n,1:n);              % crop(square)

set(gcf, 'units',       'normalized', ...       % fig props
      'position',  [0.1 0.3 0.8 0.4], ...
         'color',          [.8 .8 1]);
     
[Q,R] = qr(A);                                  
colormap(gray);                                 
% ------------------------- main loop ---------------------- % 
for i = 0:6:n-1
    
    subplot(1,3,1);                             % plot Q
    imagesc(Q(:,1:n-i)<1e-4); 
    title('Q['+string(n)+'x'+string(n-i)+']');
    set(gca,'XLim', [0,n], 'YLim', [0,n])
    
    subplot(1,3,2);                             % plot R
    imagesc(R(1:n-i,:)<1e-4); 
    title('R['+string(n-i)+'x'+string(n)+']');
    set(gca,'XLim', [0,n], 'YLim', [0,n])
   
    subplot(1,3,3);                             % plot Q*R
    imagesc(Q(:,1:n-i)*R(1:n-i,:)); 
    title('Q*R'); 
    set(gca,'XLim', [0,n], 'YLim', [0,n])
    
    pause(.01);
end          

Matlab Pong

55-line Matlab Pong script. Press left and right keyboard arrows to move the block. The figure will close if block misses ball. To play again, run the script again (‘run’ or F5)

% ezPong! {Silas Henderson 12/22/2018}
% [press left and right keyboard arrows to move block]

clear; clc; clf;
% ------------------- setup ----------------------------------- %
set(gcf,'units', 'normal','position', [.1 .1 .8 .8],  ... % figure                     
  'KeyPressFcn',@controls,   'color',    [.6 .6 .8]);                                     

set(gca,'color', 'black','position',[.05 .05 .9 .9],  ... % axis 
        'XLim', [-5 100],    'YLim',       [-5 100],  ...
       'XTick',       [],   'YTick',[],'nextplot','add')
            
global blockPos; blockPos = 0;                            % block                  
blockVertices = @(x) [x-5,-2; x+5,-2; x+5, 0; x-5, 0];                     
blockObj = patch('Vertices', blockVertices(blockPos), ...
         'Faces', [1 2 3 4],'FaceColor', [.6 .8 .6]);

ballPos = [10;10];                                        % ball    
ballVel = [.5; 1];                               
ballObj = plot(ballPos(1),ballPos(2),'.', ...
             'MarkerSize',50,'color',[.8 .6 .6]);        
% ----------------------- main loop --------------------------- %        
while 0 < 1                                              
    tic;                                                  % timer   
    if ballPos(1) > 100 || ballPos(1) < 0                 % bounce
        ballVel(1) = -ballVel(1);                         
    elseif ballPos(2) > 100
        ballVel(2) = -ballVel(2);                        
    elseif ballPos(2) < 0 
        if abs(blockPos - ballPos(1)) < 5                 
            ballVel(2) = -ballVel(2);
        else                                             
            close all;                              
        end
    end 
    ballPos = ballPos + ballVel;                          % update  
    set(ballObj,'XData',ballPos(1),'YData',ballPos(2));
    set(blockObj,'Vertices',  blockVertices(blockPos));   
    pause(1/60 - toc);                                      
end       
                             
% -------------------- function(s)------------------------------ %
function controls(~, event)                               % keys           
    global blockPos                             
    switch event.Key
        case 'leftarrow'
            blockPos = blockPos - 5;            
        case 'rightarrow'
            blockPos = blockPos + 5;     
    end
end