What is this mess

Right, I've worked out the problem. Whenever the block moves up, 'isPlayerOnTop' fails every other frame, meaning the player starts the frame already inside the block so movement is cancelled. What's causing 'isPlayerOnTop' to fail is beyond me, though. In the meantime, have a super hacky debuggy mess.