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:


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:

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:

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:


Greedy Snake Random Walk Version

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

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~
