Hey, who said I had to post updates only once a week?
(WARNING): Minor technobabble and and code ahead!
So previously this is how I handled non-integer movement values:
-- in each animation frame you define a movement x and y value for that frame, -- this was how you did it for integer values: movex = 1, -- but what if you wanted 1.5? you would do this: movex = {1,2}, -- it would move you 1 pixel, then 2 pixels, repeating... -- or in some cases, I had to use an even worse hack: if (GameState.ticks % 2 == 0) then movex = movex + 1; -- so it only works with X.5, not other floats, e.g. X.75 end
Pretty crappy, huh? I was recently browsing the Mega Man X section of TASVideos.org, and I came across this oh-so-helpful page:
http://tasvideos.org/GameResources/SNES/MegamanX/RAMMap.html
I then noticed this:
$7E:0BAC | 1 byte | X’s sub-pixel X-position. |
$7E:0BAD | 2 bytes | X’s X-position, in pixels. |
$7E:0BAF | 1 byte | X’s sub-pixel Y-position. |
$7E:0BB0 | 2 bytes | X’s Y-position, in pixels. |
Separate sub-pixel position values? How didn’t I think of this earlier! I immediately got to work and wrote this, which worked perfectly:
-- self.new self.subx = 0; self.suby = 0; -- self.tick if (math.floor(movex) ~= movex) then local diff; if (movex < 0) then diff = math.floor(movex)-(movex); else diff = math.ceil(movex)-(movex); end self.subx = self.subx + (diff*self.dir); if (self.subx = 1) then movex = movex + (math.clamp(self.subx, -1, 1)*self.dir); self.subx = self.subx-math.clamp(self.subx, -1, 1); end if (movex 0) then movex = math.floor(movex); end end -- i can't be lazy anymore when using floats because it isn't painful now.
Completely random unknown fact: until now, I used rounded up movement values while in the air because of the way air movement works. You probably didn’t notice this in the first update video, but it definitely felt “off” in-game.
That’s all for now.