Random Update #1

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.

Leave a Reply

Your email address will not be published. Required fields are marked *