Entendo acho que isso ocorre, pois quando a tecla e precionada ela so continua a fazer os movimentos sem pausa. poderia talvez adicinar uma pausa de milissegundos de um movimento para o outro.
pygame.time.delay(30)
# delay de 30 milissegundos
sugestão de onde colocar:
if key[pygame.K_LEFT] or key[pygame.K_a]:
new_posx -= 64
self.context["direction"] = "WEST"
self.frame_motion()
pygame.time.delay(30)
# adicione um em cada if
E por favor compartilhe o código se possível adoraria contribuir em um projeto como este. Além desta ajuda indicaria a deixar a parte do código responsável pelo movimento em uma função separada.