Log In  


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

1


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?


1

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]