I'm building a simple game to play around with Pico-8 and having a great time so far. Nothing special but I decided to try out the map editor and place a few collision-enabled tiles around the screen.
There are a few things that are confounding me at present:
the co-ordinate system in the map editor. Am I just missing the tooltip that tells you what the x/y is of a cel the mouse is presently over?
- Drawing a map to the screen. The pico8.txt file says I can use the map function to draw regions of the map to the screen. I can then use mget to get a tile out of the map and fget to get flags. I gathered this much from reading the jelpi source.
However I can't seem to figure out how the map co-ordinate space is mapped onto the screen co-ordinate space. Jelpi's collision code is very simple but I can't seem to replicate it; my screen space is off from the map space and I can't figure out how they line up or translate from one to the other (ie: my player is in screen co-ordinates and I need to use a bare-bones AABB search along the X axis to find collision-enabled tiles.
I feel like I'm just missing some key concept here (could be that it's also pretty late).
Showing the coordinates of the map square under the cursor would be nice. Instead, if you hold down space, it shows you some numbers that are not very useful at all. (I think it tells you which 8x8 group of map cells the UL corner of the map editor window is displaying.)
- Maybe it would help to talk over the basics? At least how I see them..
SCREEN coordinates is just the pixels on the screen. The upper left one is 0,0, the lower right one is 127,127, that's it.
WORLD coordinates are generally what your objects are swimming around in. Player.X and Player.Y will be in world coordinates. The screen is a window onto a 128x128 part of the world, as controlled by the CAMERA() function. When you use the drawing functions you are really drawing to world coordinates, and just hoping the camera picks them up and puts them into the right screen coordinates. Of course, if the camera is at 0,0 then world coordinates and screen coordinates are the same thing.
If you are using Pico-8's map stuff in the most straightforward way where the map is the map of the world, then:
MAP coordinates are closely tied to world coordinates, generally you do FLR(X/8),FLR(Y/8) to tell you which map square a world pixel is inside. To see where in the world a map square belongs, you just do the opposite: MX8, MY8. (I like to preface map coordinate variables with M.)
So how to assemble this on screen:
- Position the camera so it's on the player. A super cheesy form of this is:
Something like that should probably be at the top of your _DRAW() function.
You need to save the camera position in variables because you want to draw the part of the world that the camera is looking at. There's no GET_CAMERA()
- Draw the visible part of the map.
gives you the map tile that is visible in the upper left corner of the screen. It might be partially off screen.
gives you the world coordinate where that map square goes.
So the call to MAP() would look like:
MAP(FLR(CAM_X/8), FLR(CAM_Y/8), -- upper left map square FLR(CAM_X/8)*8, FLR(CAM_Y)*8, -- world coordinate to draw to 17,17) -- 17 because the camera may not be exactly on a map square
You can use temp variables like MX,MY=FLR(CAM_X/8),FLR(CAM_Y/8) to make that more readable.
- Draw other stuff on top of the map.
That is very helpful, thank you!
So the final two parameters to MAP are a "block of cels" you can select from the map. Are they referring to the individual 8x8 pixel "fragments" painted from the spritesheet or the 8x8 block of such fragments?
And I assume that it's based off of the first two co-ordinates to the function...
MAP(10, 10, PLAYER.X, PLAYER.Y, 10, 10)
Would select the "tiles" as <LEFT,TOP>,<RIGHT,BOTTOM> or <10,10>,<20,20> from the map... and if I rendered to the screen co-ordinates 0,30 I'd have to offset on the Y axis into world space.
Sound about right?
I think I was getting confused because it was late, I have kids who don't let me sleep much, and I couldn't figure out the co-ordinate system of the map from the UI so I was plugging numbers into MAP() until it looked right and then got upset when my collision code wasn't working.
All clear as mud now methinks.
Can't wait until I want to try rendering non-quadrilateral maps.
Yes that MAP call would take the rect of map cells from 10,10 to 19,19, and blit them at world coordinates starting at PLAYER.X, PLAYER.Y, down to PLAYER.X+108-1, PLAYER.Y+108-1. It would look like a big chunk of map was stuck to the player at the upper left corner.
[Please log in to post a comment]