MATLAB Recreation of Douyin’s Popular Snake Cutting Game

Please respect original work. If reprinting, please indicate the link and author: slandarer

It’s been a few days, and I’ve missed you all. The Spring Festival is approaching, and I anticipate being busy, so I decided to finish and publish this tutorial in advance. I was considering what snake year code to write, and suddenly remembered that I had recreated the super popular Apple Snake game on Douyin last year. This year, the game has a new snake cutting mode, which is quite fun, so I recreated it again. The gameplay involves using the arrow keys ↑↓←→ to move the snake to eat the blocks on the right side, making both sides equal. However, considering gravity, it’s not that simple:

MATLAB Recreation of Douyin's Popular Snake Cutting Game
MATLAB Recreation of Douyin's Popular Snake Cutting Game

Since the .mat files are required, the code alone won’t run, so I’ve uploaded all the files to a cloud drive:

  • https://pan.baidu.com/s/1j2KKUvWdxbY4ria0DYYs4g?pwd=slan

I created 15 levels, and after completing them, a blessing for the Snake Year will be displayed in the command window. Can you guess how the command line blessing is outputted and where the text information is hidden? Additionally, it’s worth mentioning that since the Douyin screenshots were unclear, I created the materials for this mini-game myself using PPT:

MATLAB Recreation of Douyin's Popular Snake Cutting Game

Moreover! I also wrote a piece of code to change the snake’s head image. You can replace the snake’s head with your friend’s avatar hiahiahiahia:

MATLAB Recreation of Douyin's Popular Snake Cutting Game

This head-changing feature supports images with transparency. For convenience, I didn’t do any cropping; just replace the head.png file in the folder with your friend’s avatar, and run changeHead.m to change the head with one click! Have fun playing~

Other Games

Apple Snake

The Apple Snake I wrote last year is also in the folder:

MATLAB Recreation of Douyin's Popular Snake Cutting Game
MATLAB Recreation of Douyin's Popular Snake Cutting Game

Greedy Snake Random Walk Version

MATLAB Recreation of Douyin's Popular Snake Cutting Game
function snake1
% Set the coordinate area to black and hide ticks and tick labels
set(gca,'XTick',[],'YTick',[],'XColor','none','YColor','none',...
    'XLim',[.5,40.5],'YLim',[.5,40.5],'DataAspectRatio',[1,1,1],'Color','k','NextPlot','add')
% Initialize head, food, initial direction, and initialize plotting function
head=[5,5];body=[5,5;4,5;3,5;2,5];d=[1,0];food=[10,10];
plotHdl=scatter(gca,[food(1);body(:,1)],[food(2);body(:,2)],120,'w','filled');
% Set the snakefcn function to be called when the mouse moves in the window
set(gcf,'WindowButtonMotionFcn',@snakefcn);
% Define a timer that calls the snakegame function at fixed intervals
start(timer('ExecutionMode','FixedRate','Period',1/8,'TimerFcn',@snakegame))
    function snakefcn(~,~)
        % (Mouse position - Snake head position) to calculate the snake's moving direction
        xy=get(gca,'CurrentPoint');
        d=xy([1,3])-body(1,:);
        d=d./norm(d);
    end
    function snakegame(~,~)
        % Modulus operation: exceeding 40 reduces 40, less than 1 adds 40
        % For example, 43-> mod(41+40-1,40)+1=1, -1-> mod(0+40-1,40)+1=40
        % This way, the snake can go through walls
        head=mod(body(1,:)+d+40-1,40)+1; 
        body=[head;body];
        if norm(food-head)<1 % If the head touches the food
            % New position generated for the food
            food=randi(40,[1,2]);
        else
            % Add one segment to the head and remove one segment from the tail, making it look like it's moving
            body(end,:=[]);
        end
        % Refresh the graphics according to changes in snake and food positions
        set(plotHdl,'XData',[food(1);body(:,1)],'YData',[food(2);body(:,2)]);
    end
end

Greedy Snake Back-and-Forth Head Change Version

MATLAB Recreation of Douyin's Popular Snake Cutting Game
function snake2
set(gca,'XTick',[],'YTick',[],'XColor','none','YColor','none',...
    'XLim',[.5,25.5],'YLim',[.5,25.5],'DataAspectRatio',[1,1,1],'Color','k','NextPlot','add')
head=[5,5];body=[5,5;4,5;3,5;2,5];d=[1,0];food=[10,10];
dSet=[0,-1;-1,0;1,0;0,1];[xSet,ySet]=meshgrid(1:25);xySet=[xSet(:),ySet(:)];
snakeHdl=scatter(gca,body(:,1),body(:,2),120,'w','filled','s');
foodHdl=scatter(gca,body(:,1),body(:,2),120,'w','filled','o');
set(gcf, 'KeyPressFcn', @snakefcn)
game=timer('ExecutionMode','FixedRate','Period',1/8,'TimerFcn',@snakegame);
start(game);
    function snakefcn(~,event)
        % Convert downarrow,leftarrow,rightarrow,uparrow
        % to 1,2,3,4
        % Then convert to [0,-1],[-1,0],[1,0],[0,1]
        dn = dSet(floor((abs(event.Key(1))-99)^(1/2.01)),:);
        % If the new direction is opposite to the old direction, keep the old direction; otherwise, use the new direction
        d = dn + 2.*d.*(all(dn+d==0));
    end
    function snakegame(~,~)
        head=mod(body(1,:)+d+25-1,25)+1; 
        if ~isempty(intersect(head,body,'row'))
            set(snakeHdl,'CData',[.9,0,0]);stop(game)
        end
        body=[head;body];
        if food==head
            xyDiff=setdiff(xySet,body,'row');
            if ~isempty(xyDiff)
                food=xyDiff(randi(size(xyDiff,1),1),:);
            else
                stop(game)
                text(gca,13,13,'You Win','FontSize',18,'FontWeight',...
                    'bold','Color','r','HorizontalAlignment','center')
            end
        else
            body(end,:=[]);
        end
        set(snakeHdl,'XData',body(:,1),'YData',body(:,2));
        set(foodHdl,'XData',food(1),'YData',food(2));
    end
end

Conclusion

Here is the compressed package of all the above files again:

  • https://pan.baidu.com/s/1j2KKUvWdxbY4ria0DYYs4g?pwd=slan

Wishing everyone a prosperous Snake Year in advance! May everything go smoothly and may the God of Wealth and the God of Research bless you! Hope you enjoy MATLAB~

MATLAB Recreation of Douyin's Popular Snake Cutting Game

Leave a Comment