function mchk(x, y) return mget(flr(x/8),flr(y/8)) end function move(x, y, w, h, dx, dy, col) w-=1 h-=1 if dx < 0 and mchk(x+dx, y) != col and mchk(x+dx, y+h) != col then x += dx elseif dx > 0 and mchk(x+w+dx, y) != col and mchk(x+w+dx, y+h) != col then x += dx end if dy < 0 and mchk(x, y+dy) != col and mchk(x+w, y+dy) != col then y += dy elseif dy > 0 and mchk(x, y+h+dy) != col and mchk(x+w, y+h+dy) != col then y += dy end return x, y end |
As an exercise, I wrote a small general-purpose collision script and thought I'd offer it up for folks new to P8 or relatively inexperienced with programming.
This is purposefully not a one-stop solution, but it may get you going. It is probably more in the spirit of PICO-8 to come up with specified collision routines yourself. At the very least, there's some study value here.
Things to consider:
- This was built to collide bodies <= 8 pixels wide and tall. With some thoughtful fiddling you can get it to accommodate bodies of any size, but I kept it this way for brevity.
- It takes up 226 memory.
- This is made for colliding against maps only.
I think all (X+W)'s should probably be (X+W-1) and same for Y+H's.
(also you define the down() function but never use it)
what type of input are you expecting with 'col'?
the sprite number?
I don't see any fget's so it's not a flag value.
I don't understand.
I'm having trouble getting map collisions to work myself, so im interested in finding and understanding a good way of handling it.
Thanks!
(sorry for the old bump.)
@matt
Hi! I have looked at it. Mainly I have trouble understanding the demo's code. It's not as well commented as I hoped. I have trouble understanding it enough to implement it into mine with slight alterations for my project.
I was interested in this post's code because I can understand how it works easily.
I've also looked at this post, which seemed to me at first to be the best one.
https://www.lexaloffle.com/bbs/?tid=3116
But I'm still having trouble modifying it.
The problem with this code is that the player can only move while not colliding with any surface.
If you are on top of a collision tile and hold down while holding left or right, the player will not move.
I would like it to work so that if the direction you are traveling in is not blocked then you can move that way. Essentially changing your input: (1,-1) (right and down) vector into a (1,0) (only right) vector. Still allowing the input vector to be whatever it wants, such as gravity or other powerups, etc..
Does the mget(x,y) function indeed require you to divide x and y by 8 to get the cell?
Some examples do this, while others do not.
My main trouble is that my player sometimes collides with empty space, but not the actual tiles.
I assume I am calculating the mget() wrong or something.
Right now my player collides correctly with the empty tiles one tile away from my actual tiles.
I'm trying to find tutorials or more examples, but pico-8 is not very widespread yet.
mget returns the tilesheet number a map cel, so yes, you have to divide by 8.
fget gives you the flag values from a spritesheet number, so you can use fget on the number you got from mget to check the flags on that tile. This is how I usually go about flagging certain tiles for collison. I hope this brief explanation is helpful!
Also, consider looking at the Jelpi demo. It's pretty good for this sort of thing.
[Please log in to post a comment]