I'm currently making a tile based platformer and programming the "engine" for it. I am pretty far, but lately noticed that the player is moving faster going left than right for no apparent reason. I check for the velocity but it is as intended limited bewteen -5.5
and 5.5
. When checking for the distance bewteen the last position and current position it's visible though. When moving right the console outputs the delta position to be about 3
("about" because I made the movement depending on the delta time so it varies when the pc is running faster), but when moving left it says the difference is -4
. Is that a common bug? I tried limiting the negative velocity to a lower level when negative but that is a very janky solution and not very percise.
I know that pythons float numbers are a bit weird but I can't explain to myself why this happening.
Here is the movement code (note that this is not the whole script, but where the bug happens).
Also, limit(__value, __min, __max)
is a function I made myself for as you can tell limiting a value between two values
self.state = "stand"
# move animation
if math.fabs(self.vel.x) > 0.1:
temp = math.fabs(self.vel.x) / 30
if temp < 0.4:
temp = 0.4
self.state = "walk" + str(int(math.fmod(int(self.walk_time * temp), 2)))
self.walk_time += dt
else:
self.walk_time = 0
# gravity
if not self.is_grounded:
self.vel.y += (self.grav * (1 + float(input["down"]))) * dt
self.vel.y = limit(self.vel.y, -21, 21)
# set acc to input
self.acc.x = (float(input["right"]) - float(input["left"])) * float(not input["down"])
if input["right"] and not input["left"]:
self.dir = 1
if input["left"] and not input["right"]:
self.dir = -1
# apply acc
self.vel.x += (self.acc.x / 2)
self.vel.x = limit(self.vel.x, -self.speed, self.speed)
# handle in_air
if self.is_grounded:
self.in_air = 0
else:
self.in_air += 1 * dt
# handle jumping
if self.in_air <= 3:
if input["down"] and self.in_air <= 3:
self.state = "duck"
self.fall_time = 0
# apply friction
if self.acc.x == 0:
if self.vel.x > 0:
self.vel.x -= self.fric * dt
if self.vel.x <= self.fric:
self.vel.x = 0
if self.vel.x < 0:
self.vel.x += self.fric * dt
if self.vel.x >= -self.fric:
self.vel.x = 0
else:
if self.vel.y < 0:
self.state = "jump"
elif self.vel.y > 1:
self.state = "fall" + str(int(math.fmod(int(self.fall_time / 30), 2)))
self.fall_time += 1 * dt
if self.is_grounded:
self.can_jump = True
else:
if input["up_up"]:
self.can_jump = False
# jumping
if self.jumping == 0 and input["up"]:
if self.in_air <= 3:
self.jumping += 1 * dt
elif (0 < self.jumping <= 8) and input["up"]:
self.jumping += 1 * dt
else:
self.jumping = 0
# jump
if input["up"] and (self.in_air <= 3 or 0 < self.jumping <= 6):
self.vel.y = -8
self.state = "jump"
# collision
self.is_grounded = False
self.is_ceiled = False
self.is_walled = False
self.rect.x += self.vel.x * dt
colls = self.collision(tiles)
for tile in colls:
if self.vel.x > 0:
self.rect.right = tile.left
self.vel.x = 0
if self.vel.x < 0:
self.rect.left = tile.right
self.vel.x = 0
# check vars
if tile.right == self.rect.left or tile.left == self.rect.right:
self.is_walled = True
self.rect.y += self.vel.y * dt
colls = self.collision(tiles)
for tile in colls:
if self.vel.y > 0:
self.rect.bottom = tile.top
self.vel.y = 0
if self.vel.y < 0:
self.rect.top = tile.bottom
self.vel.y = 0
# check vars
if tile.top == self.rect.bottom:
self.is_grounded = True
self.vel.y = 0
if tile.bottom == self.rect.top:
self.is_ceiled = True
self.jumping = 99
print((self.rect.x - self.last_pos[0], self.rect.y - self.last_pos[1]))
self.last_pos = [self.rect.x, self.rect.y]
Every help is appreciated