Couldn't you just stop receiving keypresses when a UI transition begins and then re-enable input once the new UI state has been established?
Also, it's very frustrating for users when input gets dropped on the floor at times where they don't expect. Determining when to queue that input and when to forget it is a real art. Humans have subtle, complex expectations there and there's no simple solution.
A robust solution should probably use state machines coupled with generative testing, so that all of those unexpected combinations can be generated and handled before the testers try button-mashing, without relying on developers to think of and write all the individual test cases.