Chronotron Flash game prototype

Do you remember Chronotron?

It’s a puzzle platform which wants you to interact with past versions of yourself to solve levels. It’s a very original game, higly recommended

chronotron

Luis Fernando Silva, author of a Box2D platform engine alternative published on the blog some time ago, created a prototype of this game

« I really liked how this prototype turned out and I hope it might help someone out. Maybe a more creative coder might even improve it!

Anyways, for the past few days, I’ve been wondering how to achieve the cool time-warped NPC that repeats all you did on a past run of a level, like on Chronotron and Mouse 10*, I was shooting some thoughts on FGL chat and the idea of using arrays to store player input in an Array and make the NPC replay it came to mind. I started discussing the idea and it gained shape as I and the chat folks talked about the possibilities.

I decided I already had a good base to start coding on, and I promotly started scripting down in Flash. At the beggining, it was hard to code this, there was some issues with the way the input was ordered on the replay array, so I had to create a function to place it in the correct order, along with an issue the way the NPC interpreted it. But after many issues, troubles, crashes and bug testing, the thing is here! And it works (almost) flawlessly! »

The main file is on the timeline and it’s fully commented:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Keyboard:
var inp:Input2 = new Input2(stage);
 
// List of NPCs:
var NPCs:Array = new Array();
 
// The array we'll store the run, with key presses and their respective intervals:
var Run:Array = new Array();
 
// The current level run time:
var Interval:int = 0;
 
// The interval limit (in frames):
var IntervalLimit:int = 300; // 300 frames = 10 seconds on 30fps
 
// This array stores the start time in which a key was pressed:
var KeyPress:Array = new Array(inp.Keys.length);
 
// Initialize it:
for(var i:int = 0; i < inp.Keys.length; i++){
	KeyPress[i] = 0;
}
 
// Loop event attachment:
stage.addEventListener('enterFrame', loop);
 
// The first element of the replay array is always the player
// position at the time the run was started being recording:
Run.push([player.x, player.y]);
 
// Loop event listener:
function loop(e:Event) : void {
	// Span the interval up:
	Interval ++;
 
	var ev:Boolean = false;
 
	// You could trim bit this later so it only captures
	// used key codes (like arrow keys, WASD, etc)
	for(var i:int = 0; i < inp.Keys.length; i++){
		// If a key is starting to be pressed now:
		if(inp.KeysInterval[i] == 1){
			// Change this key statement as being held down:
			if(KeyPress[i] == 0){
				// Start a 'key down' timer:
				KeyPress[i] = Interval;
			}
		}
		// If a key is NOT being pressed now:
		else if(inp.KeysInterval[i] == 0){
			// Checks if this key was being held down:
			if(KeyPress[i] > 0) {
				// Pushes the key, start time and interval:
				storeKeyEvent(i, KeyPress[i], Interval - KeyPress[i]);
				KeyPress[i] = 0;
 
				ev = true;
			}
		}
	}
 
	// Key event, show the array, please (remove the '&& false' to show):
	if(ev && false)
		trace(Run);
 
	// Interval over? Start over and place an NPC
	if(Interval > IntervalLimit){
		// Little trick to jump the current key state
		// to the next NPC:
		for(i = 0; i < inp.Keys.length; i++){
			if(KeyPress[i] > 0){
				storeKeyEvent(i, KeyPress[i], Interval - KeyPress[i]);
				KeyPress[i] -= Interval - 1;
			}
		}
 
		// Reset the interval:
		Interval = 0;
 
		var npc:Mc_NPC = new Mc_NPC();
 
		// Copy the run over to the NPC and init it:
		npc.Run = Run.slice();
		npc.init();
 
		// Set the label:
		npc.label.text = "NPC " + NPCs.length;
 
		// Add the NPC:
		addChild(npc);
 
		// pushes the NPC to the NPCs array:
		NPCs.push(npc);
 
		// Reset the run over:
		Run = new Array();
		Run.push([player.x, player.y]);
 
		// Reset the NPCs run, as well:
		for(i = 0; i < NPCs.length; i++){
			NPCs[i].Runtime = 0;
			NPCs[i].init();
		}
	}
 
	// Run the player:
	player.stepPlayer();
 
	// Run the NPCs:
	for(i = 0; i < NPCs.length; i++){
		NPCs[i].stepNPC();
	}
}
 
// Stores a key event on the 'time-warp' array. I use a function for this
// in order to achieve a correct ordering on the events order:
function storeKeyEvent(key:uint, start:uint, interval:uint) : void {
	// If there are no elements on the array, just push it already:
	if(Run.length == 1) {
		Run.push([key, KeyPress[key], Interval - KeyPress[key]]);
 
		return;
	}
 
	// Run the loop backwards, assuming the nearest position is at the end
	// of the array:
	for(var i:int = Run.length - 1; i >= 0; i--){
		// Checks to see the event order:
		if(i == 0 || (Run[i][1] < start)){
			// If this event happened before the event on [i], insert this event
			// after it:
			Run.splice(i+1, 0, [key, KeyPress[key], Interval - KeyPress[key]]);
 
			break;
		}
	}
}

And this is the result:

Move the main rectangle with left and right arrow keys, and when the upper timeline is over, watch for you chrono clone.

Download the source code and let me know if you improve it somehow

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (10 votes, average: 5.00 out of 5)
Loading ... Loading ...
If you found this post useful, please consider a small donation.
» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.

8 Responses

  1. Scarybug says:

    Yep, that’s pretty close to how I did it. I used OOP, Player and PastSelf both inherited from a superclass. The only difference was that Player acted on input from the keyboard and recorded it, and PastSelf acted on input from the array generated by the player. Using the time machine meant the player and past self always started at the same point, so no need to record the (x,y) coords except for the “teleport” effect that happens when you move while time is frozen.

  2. Also, some extra instructions to get the thing working correctly on a game:

    The Mc_Player is the char controlled by the player. On it, you’ll find the stepPlayer() function. Inside it, there are a few key checks placed already (left and right arrow keys).

    In order to make both NPC and player work the exact same way, just use the keyDown() event to detect and work out the controls on the stepPlayer(), and then copy the entire script over to the stepNPC() function on the Mc_NPC movieclip (leave room to call the runNPC function at the start of the loop!).

    Thanks you all!

  3. Jimbo says:

    Have you looked at your site in Firefox today?

  4. Guest says:

    There are many flash games/applications (even greeting cards) where you can Draw in flash, save the drawing (all the process not just the final result) and then load it and show the drawing process…. in those games, you record the (x, y) positions of the mouse in one array, i guess it’s something similar here? am i right?

  5. Yes, the method is almost the same.

  6. slc says:

    I want to make simple car racing game for my little brohter on cs3 flash . So that if you have simple type of scripts of game please help me by sending in my email address.

  7. David says:

    I am a little curious about Flash.
    I very dreams with games and programming in Flash. I’ve thought up to create a an online game, who also has dreams of Flash?
    Putting everything you taught him to have almost any experience to create a very good game.
    Thank you for creating the site.

  8. Sam says:

    it reminds me of Ratchet & Clank A Crack In Time, with the clank parts

Leave a Reply