I'm attempting to create a fully-fledged platformer game with Picotron, and I'm encountering some collision detection issues. You see, I followed Nerdy Teachers' platformer collision tutorial since I figured the code would work with Picotron (it technically being an advanced PICO-8 after all). And I'm correct, but something is seriously wrong. When I tested the collision code, this is what I was presented with:
Now I think this is happening due to one or more of the following reasons:
- The code was designed with 8x8 sprites in mind when my player character is in a 16x24 resolution and the tiles are 16x16 sprites.
- The code wasn't made with Picotron in mind (since the Nerdy Teachers tutorial I followed predates Picotron by quite a while).
- I've just been a complete idiot and made a mistake in the code that is causing this whole kerfuffle.
I've provided the code for the collision system and player physics below, as well as the player's table and physics variables. If anyone can help me rewrite or optimize the code to work with Picotron, then that would be a great help and I sincerely thank you for your assistance. <3
-- Player variables player={ sp=16, x=20, y=44, w=16, h=24, dx=0, dy=0, max_dx=2, max_dy=3, acc=0.5, boost=4, anim=0, running=false, jumping=false, falling=false, landed=false, flipx=false, health=3, lives=2 } -- Physics variables gravity=0.3 friction=0.85 |
-- Collision system (thanks nerdy teachers :D) function collide_map(obj,aim,flag) -- obj = table needs x,y,w,h -- aim = left,right,up,down local x=obj.x local y=obj.y local w=obj.w local h=obj.h local x1=0 local y1=0 local x2=0 local y2=0 if aim=="left" then x1=x-1 y1=y x2=x y2=y+h-1 elseif aim=="right" then x1=x+w y1=y x2=x+w+1 y2=y elseif aim=="up" then x1=x+1 y1=y-1 x2=x+w-1 y2=y elseif aim=="down" then x1=x y1=y+h x2=x+w y2=y+h end --pixels to tiles conversion x1/=8 x2/=8 y1/=8 y2/=8 if fget(mget(x1,y1), flag) or fget(mget(x1,y2), flag) or fget(mget(x2,y1), flag) or fget(mget(x2,y2), flag) then return true else return false end end function player_update() --Physics player.dy+=gravity player.dx*=friction --Controls --Moving status if btn(0) then player.dx-=player.acc player.running=true player.flipx=true end if btn(1) then player.dx+=player.acc player.running=true player.flipx=false end --Sliding status if player.running and not btn(0) and not btn(1) and not player.falling and not player.jumping then player.running=false player.sliding=true end --Jumping status if btnp(5) and player.landed==true then player.dy-=player.boost player.landed=false end --Check collision on the y-axis if player.dy>0 then player.falling=true player.landed=false player.jumping=true if collide_map(player,"down",0) then player.landed=true player.falling=false player.dy=0 player.y-=(player.y+player.h)%8 end elseif player.dy<0 then player.jumping=true if collide_map(player,"up",1) then player.dy=0 end end --Check collision on the x-axis if player.dx<0 then if collide_map(player,"left",1) then player.dx=0 end elseif player.dx>0 then if collide_map(player,"right",1) then player.dx=0 end end --Stop sliding if player.sliding then if abs(player.dx)<.2 or player.running==true then player.dx=0 player.sliding=false end end player.x+=player.dx player.y+=player.dy end |
(Keep in mind that this is all Picotron code)
I'm not sure, but I think the problem is caused by the map's collision detection.
x1/=8 x2/=8 y1/=8 y2/=8 if fget(mget(x1,y1), flag) or fget(mget(x1,y2), flag) or fget(mget(x2,y1), flag) or fget(mget(x2,y2), flag) then return true |
I can't tell from the code, but I think the map chip is not 8x8 pixels.
This is all just my speculation, but I hope it will help solve the problem.
@sugarflower is right, map tiles are 16x16 pixels (they actually take on the resolution of sprite 0, but that's 16x16 by default).
[Please log in to post a comment]