EDIT:
Please see @Bluescrn's answer to this question; he elaborates on weaknesses in replaying controls rather than movement vectors or position.
--
You're on the right track. Here's the approach I'd use:
Controllers
Create a Controller class which receives keyboard input and passes it on to your character. However, also have a Controller record exactly when the significant keys (e.g. arrows, jump, etc) were pressed and when they were released. It would store up this sort of information:
actions[0].milliseconds = 400 actions[0].action = right pressed
actions[1].milliseconds = 1000 actions[1].action = jump pressed
actions[2].milliseconds = 1300 actions[2].action = jump released
actions[3].milliseconds = 2500 actions[3].action = jump pressed
actions[4].milliseconds = 3000 actions[4].action = jump released
actions[5].milliseconds = 5330 actions[5].action = right released
A Controller has two modes:
- Record: Receives keyboard input. Records input in the list. Hands the character input based on keyboard state.
- Replay: Ignores keyboard input. Advances through the list according to milliseconds elapsed since the level began. Hands the character input based on the recorded keyboard state at the current moment.
Characters
When your Character object is constructed, it creates a fresh Controller for itself. The Character can be in one of two modes at any time:
- Active: There is only ever one active Character and it is the one you control. When the Character is in Active mode, its Controller is in Record mode. By default when a Character is constructed it is in Active mode.
- Ghost: This is the one that replays your past actions. When a Character enters Ghost mode, it changes its appearance and sets its Controller to Replay mode.
Levels
A freshly started level
When you start the level, create a single Character. Now the level begins and the player does his thing.
When time resets
When the level resets, do three things:
- Tell the current Active Character to enter Ghost mode.
- Create a new Character.
- Call all Characters to Reset themselves. This will place them back at the starting position with no movement, etc. They will in turn tell their Controllers to reset to millisecond 0 with no keys pressed.
Then the level begins and the player does his thing.