Somewhere in December 2011, I borrowed my friend’s smartphone and played DoodleJump in it. The gameplay is quite simple. Basicly, you are controlling a doodler to reach higher altitude by jumping from one stepping pad to another stepping pad. Somewhere along the game, you’ll also come across a blackhole that you must avoid or an enemy that you can shoot or jump on. The game is endless and you only die if you fall to the bottom of your screen or you touch the black hole or the enemy. Unfortunately, the game turned out to be pretty addicting for me and I ended up playing it until my friend’s battery died (Sorry dude:D).
At first, I didn’t have any intention to make a DoodleJump game in MATLAB, but drafting the MATLAB code for Congklak game drove me crazy and I needed a break. So, why not make this game. It is simple and easy to code anyway. So, earlier this week, I started creating DoodleJump on MATLAB and here it is, DoodleJump on MATLAB.
While I only used simple graphic such as a circle for the doodler and the black hole and straight lines for the stepping pad, I made the game as similar as I can with the original DoodleJump. The stepping pad appears randomly and there is a black hole that will kill the doodler instantly if it touches it. Too bad I can’t make an enemies that the doodler can shot or jumped on. It will make the code too complicated and I’m afraid that this will cause lag in the gameplay, So, I decided to leave the enemy concept and probably updated it later.
In my previous post about my MATLAB Fun Toolbox, I never explained the algorithm of the code that I made. I just simply put it in my MATLAB Fun Toolbox page, show some screenshot or video in the post, and then leave it there. But, starting this year, I’m gonna share a little bit about the algorithm of my codes and hopes that you can understand or learns new things from it.
For the general gameplay, basicly I uses while command to perform endless loop run the gameplay. This while loop will end when the user hit ‘Quit’ button in the user interface or when the doodler dies (by falling down to the bottom of the screen or touching the black hole). Inside this loop, doodler’s position is calculated and updated based on its movement speed every one loop. Its horizontal movement speed is controlled by player while its vertical speed is affected and reduced by the gravity. In every one loop, doodler’s position is checked. If it is stepping on a stepping pad when it is moving downwards, a vertical speed boost is given, causing doodler to jump (Yeah, that’s why this game is calle DoodleJump) and move upwards until its vertical speed is fully decayed by the gravity. The doodler’s position is also checked to see whether it touches black hole. If it does, the loop is stopped and the game is over. After doodler’s position is determined, I uses scatter function to draw the doodler and the black hole and line function to draw the stepping line.
Here is a peek of the part of my code that shows you how to run the loop for DoodleJump’s gameplay.
playstat=1; while playstat %Decaying doodle's horizontal speed if decelstat if u_doodle>0 udot_doodle=-doodledecel; elseif u_doodle<0 udot_doodle=doodledecel; end end %Calculating doodle's position u_doodle=u_doodle+(udot_doodle*timestep); v_doodle=v_doodle-(gravity*timestep); x_doodle=x_doodle+(u_doodle*timestep); y_doodle=y_doodle+(v_doodle*timestep); %Anticipating screen cross if x_doodle<-0.5*fieldwidth x_doodle=x_doodle+fieldwidth; elseif x_doodle>0.5*fieldwidth x_doodle=x_doodle-fieldwidth; end %Sliding the view upwards if y_doodle>height+(0.5*fieldheight) height=y_doodle-(0.5*fieldheight); set(heighttext,'String',num2str(height)) end %Determining if doodle steps on a paddle if (v_doodle<0)&&... (isdoodleatpaddle(x_doodle,y_doodle,v_doodle,paddle)) v_doodle=doodlejump; end %Updating paddle (generating paddle at higher height) paddle=updatepaddle(paddle,height); %Updating trap (generating trap at higher height) trap=updatetrap(trap,height); %Updating game difficulty difficultymultiplier=exp(-height/difficultyupdateinterval); %Checking if doodle touches trap if norm([x_doodle-trap(1),y_doodle-trap(2)])<=trapradius playstat=0; end %Checking if doodle falls down to the bottom line if y_doodle<height-1 playstat=0; end %Displaying animation drawgame %Delaying animation pause(timestep) end
Random Generation of Stepping Pad
The cool thing a bout DoodleJump (which also makes it kinda hard to code) is how the stepping paddle and the blackhole is randomly generated and placed. If you have played the game, you may also notice that the stepping paddles become less and less at higher altitude. To accomodate this, notice that I incorporate a variable called difficultymultiplier, whose value is adjusted and getting smaller as the height goes up. This will affect random paddle generation that was done bu updatepaddle function.
To randomly generate a paddle, I simply uses rand function (a function to generate random number). For the first time (before the loop is executed), generatepaddle function was called to generate paddles randomly at the first screen. To make things simpler, a paddlecache variable was used to determine how many paddles that the game will remember and the vertical distance between each paddle was fixated to 1. The following shows you the contents of generatepaddle function. Notice that here, for every vertical distance of 1, there is a 80% chance that a paddle will be generated there and they are placed randomly in some where in x direction.
function paddle=generatepaddle() paddle=zeros(paddlecache,2); paddle(:,1)=1:paddlecache; for count=1:size(paddle,1) decision=rand; if decision<0.8 paddle(count,2)=(rand*(fieldwidth-paddlewidth))-... (0.5*(fieldwidth-paddlewidth)); else paddle(count,2)=NaN; end end end
As the game progresses, the screen will scrolls upwards as the doodler reach higher height (see sliding the view upwards in the game loop). This means that the paddles at the bottom of the screen will not be visible anymore, while on the other hand, new paddles at the upper height must be generated and placed. So, to keep the number of paddles to be remembered by MATLAB the same, the most bottom paddle must be deleted when it leaves the screen and new paddle must be generated and placed randomly at the upper screen. To do this, updatepaddle function was written as shown below. Note that the upper paddle also generated randomly and placed randomly, however, unlike in generatepaddle function where paddle generation possibility is 80%, in this function, paddle generation possibility is adjusted by difficultymultiplier variable. This way, the paddle generation possibility will become less and less as the height goes up, causing more difficulty for player. Unfortunately, somewhere along the game, paddle generation possibility will become small enough that sometimes there are no paddle generated for a certain vertical distance. To be fair to the player, a paddle must be generated automatically if there is no paddle generation after a certain vertical distance. This was done to ensure that player always have stepping pad to reach higher height. To accomodate this, forcing paddle generation section was written in updatepaddle function.
function paddle=updatepaddle(paddle,height) %Randomly generating paddle at the next height if height+paddlecache>paddle(paddlecache)+1 paddle(1:paddlecache-1,:)=paddle(2:paddlecache,:); paddle(paddlecache,1)=paddle(paddlecache-1,1)+1; decision=rand; if decision<(paddlechance*difficultymultiplier) paddle(paddlecache,2)=(rand*(fieldwidth-paddlewidth))-... (0.5*(fieldwidth-paddlewidth)); else paddle(paddlecache,2)=NaN; end end %Forcing paddle generation after n height unit if sum(isnan(paddle(... paddlecache-nopaddlelimit+1:paddlecache,2)))==... nopaddlelimit paddle(paddlecache,2)=(rand*(fieldwidth-paddlewidth))-... (0.5*(fieldwidth-paddlewidth)); end end
Checking if the Doodler Steps on Stepping Pad
One other thing that is also quite tricky is how to determine whether a doodler lands in a stepping pad or not. The first idea that comes to my mind are defining all paddles as polygon and use inpolygon function to check whether the doodler is inside one of the polygons. Unfortunately, this will take too much processing time because it checks all paddles that are remembered by MATLAB. To simplify things, I decided only to check for the paddle that is closest to the doodler. I also doesn’t use inpolygon function as I intended at first. Instead, I define the paddles as a point with certain width and do the checking with simple line intersection concept as show below.
function stat=isdoodleatpaddle(x_doodle,y_doodle,v_doodle,paddle) stat=false; %Finding the closest paddle from doodle y_=floor(y_doodle); %Determining if doodle will land on the paddle if y_doodle+(v_doodle*timestep)<=y_ x_=paddle(paddle(:,1)==y_,2); if abs(x_doodle-x_)<0.5*paddlewidth stat=true; end end end
Fiuh, that’s all the explaination about my DoodleJump code. I hope you don’t get confused with it. As usual, I’m gonna share the code in my MATLAB Fun Toolbox page and you can download it or modify it as you like. The visualization of the game is still too simple and I hope that I’ll have the time to improve the game’s visualization. In the mean time, enjoy the game…