1

im tryin to make a platformer base to use for future projects, but when travelling in positive directions, the collision is seemingly not detected until a full pixel further than it should be

 ``` local xd=n.x+n.speed.x+n.w/2*sgn(n.speed.x) local yd=n.y+n.speed.y+n.h/2*sgn(n.speed.y) n.grounded=false n.walled=false if fget(mget(xd\8,(n.y+n.h/2)\8))==1 or fget(mget(xd\8,(n.y-n.h/2)\8))==1 then n.x=xd\8*8+(n.speed.x>0 and -1-n.w/2 or 8+n.w/2) n.walled=true n.speed.x=0 end if fget(mget((n.x+n.w\2)\8,yd\8))==1 or fget(mget((n.x-n.w\2)\8,yd\8))==1 then n.y=yd\8*8+(n.speed.y>0 and -1-n.h/2 or 8+n.h/2) n.grounded=true n.speed.y=0 end n.x+=n.speed.x n.y+=n.speed.y```

negative velocity position readings(continuously accelerating by -0.005 pixels/second/second)
INFO: y=10
INFO: y=10
INFO: y=10
INFO: y=10
INFO: y=10
positive velocity position readings(continuously accelerating by 0.005 pixels/second/second)
INFO: y=29.7242
INFO: y=29.8109
INFO: y=29.9025
INFO: y=29.999
INFO: y=29

negative velocity position readings(given a constant velocity of -0.005 pixels/second while pressed against wall)
INFO: y=10
INFO: y=10
INFO: y=10
INFO: y=10
INFO: y=10
positive velocity position readings(given a constant velocity of 0.005 pixels/second while pressed against wall)
INFO: y=29.9844
INFO: y=29.9883
INFO: y=29.9922
INFO: y=29.9961
INFO: y=29

this happens at any speed/width/height combination, and the readings are from the last 5 frames before a collision is registered
i have a feeling this is because of flooring but i dont know how i would fix it :3

P#135108 2023-09-29 17:15 ( Edited 2023-09-29 17:16)

ok, x,y are the centre of the sprite/hitbox?

ok, when for example, the sprite is placed on 4x4 and your sprite has a with/height of 8x8, this means in your code the left xleft=x-w\2=0 and xright=x+w\2=8. which means, that the right side is outside of the box. When you paint a 8x8 sprite on 0x0, it will be drawn on 0x0 to 7x7.

I think, thats is your problem...

I would redesign the code complete by something like this:

 ```check={ sprpos={x=-3,y=-3}, -- drawing position left={{x=-3,y=-3},{x=-3,y=4}}, right={{x=4,y=-3},{x=3,y=4}}, top={{x=-3,y=-3},{x=4,y=-3}}, bottom={{x=-3,y=4},{x=4,y=4}} }```

And use this check-table to get the position of test and sprite drawing. Also you can alternate the test-points a little bit away from the corners, when your Sprite is not full squared.
use for the position-check something like

 ```for pos in pairs(check.left) do if collision_on_pos then collisioncode break -- we don't need to check other points end end```

so you can add more checkpoints, if needed (bigger sprite, unusual form).

P#135142 2023-09-30 06:34 ( Edited 2023-09-30 06:34)

oh and two important thinks. Your speed should not be greater than 8, otherwise it is possible to "skip" a block and jump through a barrier.

speed=mid(-8,speed,8)

should do the trick.

and you check if the sprite-flag 0 (value 0x01) is set and all others are not set.
When you later want to add a "ice"-block, you can use the sprite-flag1 here (value 0x02)
But you can give the ice-block both flags 0&1 (0x01 | 0x02 = 0x03).

When you change your
mflag()==1
to
mflag()&1 == 1
you handle here your ice block and default block for collision. You check so only the flag 0 with the value (0x01)

P#135144 2023-09-30 06:44

x and y are the center on purpose, and i dont really want to have that many tables for each "class", as that would quickly inflate cartridge size

P#135162 2023-09-30 17:37

`\`(back slash) is rounded to an integer with `flr()`.
When dealing with positive and negative values, the result will be biased toward lower values.

 ```10.5 -> 10 -10.5 -> -11 ```

Have you tried doing +0.5 before `flr()` or switching between `flr()` and `ceil()` depending on positive or negative?

P#135181 2023-09-30 23:29
1

oh shit i thought flr() was towards 0 not just down that'll probably fix it! thx!!

P#135329 2023-10-03 07:06

 ```cls() function dwn(i,d) return i>0 and flr(i/d) or ceil(i/d) end function up(i,d) return i<0 and flr(i/d) or ceil(i/d) end function l(i) b=" "..tostr(i) return sub(b,#b-2) end str="" for i=-2,2,0x.4 do a=tostr(i).." " str..= sub(a,1,5).. l(ceil(i)).. l(flr(i)).. l((i\1)).. l(sgn(i)*ceil(abs(i))).. l(sgn(i)*flr(abs(i))).. l(dwn(i,1)).. l(up(i,1)).. "\n" end print(str) printh(str,"@clip") ```
 ```-2 -2 -2 -2 -2 -2 -2 -2 -1.75 -1 -2 -2 -2 -1 -1 -2 -1.5 -1 -2 -2 -2 -1 -1 -2 -1.25 -1 -2 -2 -2 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -0.75 0 -1 -1 -1 0 0 -1 -0.5 0 -1 -1 -1 0 0 -1 -0.25 0 -1 -1 -1 0 0 -1 0 0 0 0 0 0 0 0 0.25 1 0 0 1 0 0 1 0.5 1 0 0 1 0 0 1 0.75 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1.25 2 1 1 2 1 1 2 1.5 2 1 1 2 1 1 2 1.75 2 1 1 2 1 1 2 2 2 2 2 2 2 2 2 ```
P#135335 2023-10-03 10:16

thanks for the comprehensive list! can i ask why you put .25 in hex?

P#135347 2023-10-03 14:31

my first version was .2 - but thats a little problem. .2 is in hex 0x0.3333
in binar-system .2 is not a good value. The table would have rounding-errors in the first column. So i typed 0x0.2 to get a good value.

It is the same problem like 1/3 in our 10-system, it would be 0.3333333333333

P#135356 2023-10-03 17:55