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
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).
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)
You must add then additional code to check.
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)
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
\
(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?
oh shit i thought flr() was towards 0 not just down that'll probably fix it! thx!!
choose your poisen:
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 |
thanks for the comprehensive list! can i ask why you put .25 in hex?
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
[Please log in to post a comment]