5
\$\begingroup\$

I have drawn one tile and I would like to use it in a very small shoot'em'up I am writing for fun and learning. My aim would be to build something like Xenon 2 (vertical scrolling, a spaceship proceeding for a bit, at right and left walls that are programmatically generated so the ship can "travel" for a bit and then, in the end, meets final monster and end of the level) but I cannot think of how I can obtain this result without drawing everything manually in the map.

Not only code but also a good suggestion in topics / functions to study (all PICO-8 related, if possible) will be considered as a valid answer.

Here's a small manually generated example (walls are the grey blocks)enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ Picture added, sorry if I was not so clear @DMGregory :) \$\endgroup\$
    – Pitto
    Sep 1 '17 at 7:58
  • \$\begingroup\$ To make the walls more interesting I would like to throw a variation of the same tile every 3 / 5 tiles. But that would be the advanced part, for the moment it would be more than enough to generate always the same tile. In PICO-8 there is map() and drawmap() but I cannot understand how I can obtain this. \$\endgroup\$
    – Pitto
    Sep 1 '17 at 12:57
  • \$\begingroup\$ Let's simplify it: I need no variation. I will remove it from the question, thanks \$\endgroup\$
    – Pitto
    Sep 1 '17 at 13:28
7
\$\begingroup\$

Sounds like you want to animate the walls down the screen so that it appears as though the player's ship is moving forward.

Know that the PICO-8 Map is mainly for static backgrounds, so if you want a sprite that will be animated on the screen, it is better to draw it with code using SPR().

Walk Through:

First, you will need many wall tiles drawn on the screen, so prepare an empty table to hold the X and Y coordinates for each tile. Put this above all other code: WALLS={}

Second, you will want to add all of the tiles' (X,Y) coordinates to that table. Do this when the game initiates so in the _INIT() function.

You can use a FOR loop that iterates 17 times because 16 tiles will fit from top to bottom, and 1extra tile will start above the screen to fill in the gap when the walls move down.

FOR I=0, 16 DO

END

Inside that, you create a small table for each tile. For the left wall the X will be 0, and the Y will calculate 8 pixels lower, each time the FOR loop iterates. TILE={ X=0 , Y=8*I-8 }

Then add that to your WALLS table: ADD(WALLS, TILE). Create another tile table but this time the X will be 120 for the right wall, and add that as well.

Third, you can draw, using SPR( sprite#, x, y ), each tile onto the game screen, using a FOR key IN ALL(table) loop. Do this in the _DRAW() function.

Fourth, you can animate the walls by changing the Y coordinate of each tile at every game update so do this in _UPDATE function. Use another FOR key IN ALL(table) loop, and inside that, simply increase Y by 1: key.Y += 1

Then catch any tiles that fall off the bottom of the screen and move them above the screen, making the wall appear infinite:

FOR TILE IN ALL(WALLS) DO
    TILE.Y += 1
    IF TILE.Y >= 128 THEN
        TILE.Y = -8
    END
END

Done!

Code

walls={}

function _init()
 for i=0, 16 do --build walls
  tile={        --left tiles
   x=0,
   y=8*i-8
  }
  add(walls, tile)

  tile={        --right tiles
   x=120,
   y=8*i-8
  }
  add(walls, tile)
 end
end

function _draw()
 cls()
 for tile in all(walls) do --draw walls
  spr(1,tile.x,tile.y)
 end
end

function _update()
 for tile in all(walls) do --animate wall
  tile.y+=1
  if tile.y>=128 then
   tile.y=-8
  end
 end
end 

Run

enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.