I tried using some of the code from the examples in this thread. There seems to be a solid box that is impassible near the top left of the map, but the tiles I've flagged aren't acting as solid objects. Any ideas what I'm doing wrong here?
The issue is that you handle the position of the actor differently than the sample. The sample stores the position of actors in tiles. You store them in pixels. So coordinate 2,2 in the sample is the equivalent to 16,16 in your program. Take a look how the actual sprite is drawn in the sample program and compare it to yours:
function draw_actor(a) local sx = (a.x * 8) - 4 local sy = (a.y * 8) - 4 spr(a.spr + a.frame, sx, sy) end |
Thanks, that makes sense I think. So I divided the result of solid_area() by 8 and it kinda made it work a bit more as expected, although not perfect quite yet.
The player can almost pass through solid blocks, but stops just shy of it now. I think this might have to do with the dimensions of the player (player.w, player.h). I'll keep tinkering.
only took a quick look at your code, but I noticed solid_area tests from x - w to x + w ( and y etc ), so you are testing solids like your x, y are the center of your dude, but in your _draw() you are drawing with the x, y being the top left point, so you could try replacing the solid_area with x,y ; x+w,y ; x+w,y+h ; x,y+h. For sure collision is a pain, don't give up!
I wrote a tutorial about how to do collisions the way you are attempting to do them. You can find it here: https://www.lexaloffle.com/bbs/?tid=3116
Thanks for the replies, I've been learning as much as I can about Lua and Pico-8.
I took a look at Krystman's collision cart, which seems to have sorted out what I wanted in terms of collision. I've since added the idea of collecting a certain number of items before unlocking the solution to the level:
One thing I can't seem to nail down is why keyshards seems to be increased twice for each collection, instead of once as I'd expect. Any ideas?
I noticed where you have:
if checkspot(p1.x,p1.y,2) then mset(celx, cely,0) keyshard+=1 end |
you are checking the position of your character with one value and setting the map with another. Inconsistencies tend to cause bugs, so try using something like p1.x/8, p1.y/8, where you are checking and setting using the same x, y.
Good tip, that pretty much fixed up my issue. Here's the updated cart with some sfx. Thanks to everyone who replied for helping me figure these things out.
I wanted to figure out level progression, so I whipped up something quick and dirty to try and get it working. It seems to be saving the collision data from level_0 when playing level_1. Any idea why this might be the case?
Also, if anyone could kindly point me to where I might be able to set the thumbnail of the cart, I'd be much obliged. :)
I think I fixed the collision issue, but I'm sure there is a better way to DRY this code up, and make it more robust. This is what I have so far:
One thing I want to add is rounded collisions, or soft corners. I'm assuming I need to learn more about circular collisions. Is there a good primer on this kind of code?
I'd also like to achieve moving from one screen to the next when the character hits the map limits. Ideally, the map would animate (scroll) to the next scene to give a sense of continuity in the world. Is there a simple way to animate the map like that?
I don't think what you're looking for is ACTUALLY collision with rounded corners. What you probably want is some kind of fuzziness to the collision so that you you graze a corner your character will get nudged into the right position. You could achieve that by checking the collision on more than just the 4 corners of the character. You could include positions along the edge of a character to judge if a collision is a graze or a flat impact. I don't have code for you ready, however, you gonna have to experiment yourself.
As for your second question, you seem to have the right idea. You just haven't actually drawn a second level on your map.
The animation could be achieved by slowly animating the levelx/levely values to a new position when a player completes a level or leaves the map. You could achieve that with a gamestate similar your reachgoal.
Fuzzy collision, interesting. My initial thought was that perhaps I could have the code say "eh, close enough" but I wasn't sure how to deal with what to do with the player in that situation. I'll tinker with that approach.
I've gotten rudimentary map & camera move functionality done. It's not animated, as I couldn't figure out how to do that bit just yet. I think it has something to do with a for loop in the _update function somehow, but I can't quite figure it out just yet.
I'm working on fixing collision if p1 goes beyond the camera boundaries. Right now, p1 just gets stuck in the wall if there is one in the next map area. Moving back to the previous screen works, so it's not utterly game breaking, but it's still an issue I'm working on fixing.
Updated cart with enemies, projectiles, and a bunch of other stuff.
Progress is made. Next up, some sprite work and music.
[Please log in to post a comment]