instead of writing things like this
if event == E_LEFT {
player.x += 10
} else if event == E_RIGHT {
player.x -= 10
} else if .... {
...
}
split it up into "decide what to do" and "do the thing", and don't overwrite the current state until you're done, either:
if event == E_LEFT {
action = ACTION_MOVE_LEFT
} else if ... {
....
}
var player_next = player
if action == ACTION_MOVE_LEFT {
player_next.x += 10
} else if .... {
...
}
player = player_next
why?
if you don't split things up this way, eventually the order in which your if statements appear in the file becomes very important, and very, very fragile. you'll often end up in situations like the following:
- two event handlers run, and one clobbers the other, leading to players being stuck in one state unintentionally
- one event handler runs after another, and uses the new game state for calculations instead of the current state, and all hell breaks loose
- generally fixing any bug in the event loop means causing three new ones to appear
the usual solution to problems like this is to move bits of the event handler around until you luck out on the correct ordering of operations, and pray for a merciful death, or an early release date.
the better solution is to structure the code such that the ordering of individual parts no longer matters:
event = next_event()
action = next_action(state, event)
state = next_state(state, action)
with code like this, it's impossible for an event handler to work on anything but the current state. it's impossible for two events to accidentally overwrite one another's changes. it's also a hell of a lot easier to maintain. it does take a bit more code, but you'll save so much time.
this doesn't just apply to gamedevs, either. storing the current and next value in the same variable always causes tears. that's why you should split up the "decide what to do" from the "do the thing", and don't overwrite the current state until you're done.
you won't hate the code as much
