Log In  

I design and code games part time (though I wish I could do it full time).

Cart #ultra_simple_platformer-0 | 2021-03-08 | Code ▽ | Embed ▽ | Forks ▽ | License: CC4-BY-NC-SA


Same base engine used in Bullet Ball:

This platformer base code is what my game Bullet Ball is built on. It is inspired by Super Mario Bros for the NES. This demo contains code for Super Mario style variable jumping, AABB collision (1 way platforms or full collision), and a very simple animation function.

Like many newbies, I struggled with platforming when I was learning to program and always found that my code was bloated with many unnecessary variables. I still see many newbies struggling with this. I'm also seeing many demos with verbose code and needless multiple variables.

Programming is difficult and optimizing even more so, but as a rule of thumb, you always want to have efficient, optimized code that's clear to read and understand. By efficiency, you want to use as little computer power as you can. Even though with today's ultra blazing fast processors, it seems not necessary, it's a good practice, because it also helps you simplify. It takes years to get there, but you learn.

The magical element in my code is the use of lookup tables for the use of movement and position for collision detection. Super Mario Bros used lookup tables as using mathematical equations (especially multiplication and division) would bog down the program on the NES. The NES ran at 1.79MHz with very limited ram. NES programmers had to optimize hardcore to get their games to run the way they wanted them too. SMB is a true marvel. In my own movement code, I only increment, decrement and use modulus (same as division, but the result is the remainder) for friction.

So, a quick look at the lookup tables and an explanation for them. Following that in the hidden tag is commented code. It is aimed at newbies with little experience coding. The code in the demo above is condensed down to 87 lines (sans the 2 dividing dashed lines) and can be condensed a bit more if you take out the block for 1-way platforms.

This is the speed look up table. This is used for both horizontal running and vertical jump movement.


By using a counter variable that can increment or decrement, I can then add the result to my x or y position and voila.

For example, if you wanted the player to just run right at top speed:

hv=9 --hv is horizontal velocity

So by simply changing the hv variable, I can make the player not only move left or right, but also immitate acceleration and drag. Notice how the sets of numbers count up on both sides of 0. Look at the movement function in the code below to see how this all works.

For gravity, using the speed table is super handy. If vv (vertical velocity) is less than 5, my player will move up (jumping), but go past 5 and the player starts to fall. So in my movement code, I have:

if(vv<9) vv+=1

This line runs no matter what. When holding down my jump button, vv is set to 1 and will be reset at 1 every tick until either my jump boost (see code below) runs out or I let go before it runs out, so that the player will move up. When I let go or my jump boost has hit max, then the line above is free to count up vv. This causes an arc movement and then the player falls down and will continue to move down unless stopped by a platform. Gravity.

My 2nd look up table is simply a table of multiples of 8:

for i=-1,16 do

This table helps in detecting local collision around the player. Refer to the code below to see how it works.

Feel free to use the code as a base for your projects. Be careful if you tinker with the values within the speed table. Collision can be easily thrown off and you might end up inside or going through blocks. I'm not easily available, but I'll answer any questions best I can, when I can. I'm also of the "there are no stupid questions" policy. Ask anything.

You can also look at the code in Bullet Ball to see more platformer functions and to see how my code works with the entire map space. At the moment BB's code is uncommented, but I am putting together a post-mortem post that will contain commented code.


--player variables

--movement variables
hv=5 --horizontal velocity
vv=5 --vertical velocity
surface=2 --works as a counter with friction.. the higher the number, lower the friction
boost=0 --variable jump height counter
speed={-4,-2,-1,-1,0,1,1,2,4} --this is the speed look up table. it can be used for left/right and vertical movement.

--map variables
for i=-1,16 do
    tile[i]=i*8 --look up table with multiples of 8 (8*-1 to 8*16). this is used in the collision function for horizontal and vertical coordinates.
--animation variables
set=2 --the first sprite of the current set of frames to animate.
start=0 --this works as a counter with duration.
duration=3 --length of current set of frames
frame=1 --starting frame

--test timer variables

function _update()
    --if timer==0 then

function input()
    if btn(0) then --if pressing "left", face left, count down horizontal velocity
        if(hv>1) hv-=1 
    elseif btn(1) then --"right", face right, count up horizontal velocity
        if(hv<9) hv+=1 
        friction=(friction+1)%surface --when friction%surface is 0, then if moving horizontally, count up or down until hv is 5
        if friction == 0 then
            if(hv<5) hv+=1
            if(hv>5) hv-=1
    if btn(5) then
        if boost < 6 then --variable height jump
            vv=1 --so long as boost is less than 6, keep vertical velocity at 1. speed[1]=-4, so the player will continue moving up 4 pixels
        boost=6 --if let go in mid air, set to 6 to prevent double jumping. resets to 0 when on ground

function move() --here is where the speed look up table is used for both horizontal and vertical speeds
    if(vv<9) vv+=1 --unless vv is set by another function, it will otherwise count up till 9. here is where the jump arc happens and then constant gravity.

function collision()
    anim=false --at the beginning, anim is false - this way, unless player is touching ground, player will display jump sprite.
    surface=4 --setting at 4 at the beginning allows for more natural movement in air. on ground is set to 2.
    if(x>=120) x=120 --set right side screen boundary
    if(x<=0) x=0 --set left side screen boundary
    local n1=flr(x/8) --n1 and n2 get the coordinates of the tile that the top left pixel of the player is currently inhabiting.
    local n2=flr(y/8)
    for i=n1-1,n1+1 do --now we check all the tiles around the player. in this code, this is extended 2 tiles below the player.
        for j=n2-1,n2+2 do
            if fget(mget(i,j),0) then

                --uncomment this block if you want one way platform collision------
                --[[if x < p[i]+7 and x+7 > p[i] and y <= p[j-1] and y+8 >= p[j-1] and vv>5 then 
                    -- if y < p[j] and y+8 >= p[j] then
                        -- if (not btn(5)) boost = 0
                        -- y=p[j-1]
                        -- vv=5
                    -- end
                --this block of code allows for full aabb collision---------------- 
                --top of tile
                if x < tile[i]+7 and x+7 > tile[i] and y < tile[j] and y+9 >= tile[j] and vv>5 then --note that the 'tile' look up table is used here.
                    if (not btn(5)) boost = 0 
                    y=tile[j-1] --set player position on ground
                    vv=5 --stop vertical movement
                    anim=true --now on ground, anim is true
                    surface=2 --add more friction to movement now that on ground
                --bottom of tile
                if x < tile[i]+7 and x+7 > tile[i] and y-1 <= tile[j]+7 and y+7 > tile[j]+7 then
                    if(vv<9) vv+=1 --incrementing vv here doubles time for movement to go from up to down.
                    boost=6 --set to 6 to cancel jump
                --right side of tile
                if x-1 <= tile[i]+7 and x+7 > tile[i]+7 and y < tile[j]+7 and y+7 > tile[j] then 
                --left side of tile
                if x < tile[i] and x+8 >= tile[i] and y < tile[j]+7 and y+7 > tile[j] then 

function animate()
    if anim then 
        if(hv~=5) then
            start=(start+1)%duration --when anim is set to true and hv is not 5, then run the 'running' animation
        if(hv==5) frame=0 --if hv is 5, then set frame to 'stand' frame
        frame=4 --otherwise set to jump frame

function _draw()

P#88071 2021-03-08 21:01 ( Edited 2021-03-09 04:03)

Cart #bullet_ball-1 | 2022-03-27 | Code ▽ | Embed ▽ | Forks ▽ | No License


Once upon a time, cute and fluffy street thugs decided to settle a score they had with a friendly round of street ball. Their skirmishes grew intense and it wasn’t long before weapons got involved. Their game of street ball evolved into Bullet Ball. Since then, they’ve forgotten why they were even fighting and continue their battle today.

The object of the game is to get the ball into the opposing team’s hoop. You will have an arsenal of 8 weapons and power ups to aid you or your team to victory.

You can run, jump, aim (in 8 directions), shoot and toss weapons or toss ball.

Default controls:

Player 1:


Player 2:

TAB/L SHIFT......(fire/toss)

Player 3 to Player 4: Configure your controllers how you wish.


Ctrl+R will instantly reset the game.
WARNING: if you reset your game and you made a custom map with the map editor, it will default back to the skeleton map. You will have to rebuild it. If you want to leave your current round, but keep your custom map, press ENTER and select "exit round". This will reset the game, but map selection will still have your map as the first one.

Starting a Game

Select 2 or 4 player. Set score limit if you wish. Default is 10 points to win. The game will begin with the characters in their default spawn positions on the second map, unless a custom map was made and saved. Then the game will start on the first map. The first map is blank and reserved for the map editor. The game has 11 default maps as shown:


Scroll LEFT or RIGHT to pick a level and press X. You can now select your character by pressing UP or DOWN and pressing X. Once both (or all 4 if in 4 player) players have chosen their character, the game will start. You can choose one of the following 4 badass characters: Fluffy the bunny, Muffin the mouse, Stubbs the dog, and Patchy the cat.



Get the ball in the opposing team’s hoop. The first to score 10 points wins the round.

You can only hold one item: the ball or a weapon. Once a weapon is discarded, either by touching the ball, using up ammo, or tossing it (knife and star), another weapon will immediately spawn in a random position on the map.


Powerups will also randomly spawn on the map after some time. Regular powerups restore 1 heart of health. Each character has a special powerup that will grant them full health and invincibility for 5 seconds. If the player touches a powerup that does not match the character, the powerup will act like a regular powerup and only restore 1 health.


You have 3 hearts of health. If you lose all 3, you die and respawn. When you respawn, you are invincible for 1 second.

Special Strategies

Using The Map Editor

Press Z to bring up your editor panel and press Z again to hide it.
Press X to make your selections.

Use arrow keys and X to design your map. You can erase a tile, simply by moving the cursor onto it and pressing X.

You can mix and match your tiles. You have a lot of freedom in the editor so be creative and have fun. Just remember, that if you want to share maps (via image post here), make sure they are symmetrical, so that both sides have equal chance.

NOTE: Leave at least 2 open vertical spaces at the first column of tiles (left of screen) and last (right of screen). The game code picks these spaces as spawn areas. If you make a column of blocks from the floor up to the block that holds the hoop, with no spaces, the players will end up spawning inside the blocks. This may cause a crash or other unintended effects.

FILL will set all the visible tiles to whatever tile you have selected.
SAVE will activate the map and add it to the beginning of the map list.
EXIT will go back to the main menu. If you saved your map and start a new game, your custom map will be the first choice.

P#87690 2021-02-15 22:23 ( Edited 2022-03-28 20:55)

Follow Lexaloffle:        
Generated 2022-09-26 20:22:11 | 0.058s | Q:13