Tuesday 15 May 2012

Replaying

Quick note: There was a disaster with boxSlide, in which I lost all of the files. I was incredibly dismayed by it, but I can't hang onto it forever, I guess.

Anyway, since that, I've been going back to basics and learning new things. I'm going to write about one of the fun things I've been doing recently:

For boxSlide, one of my main advertising points was the ability to watch a replay of the level. Now, you may think that creating a replay of someone's actions could be quite difficult - perhaps because you're thinking it's something to do with saving actual footage of the event. There is a much more logical way around this.
Basically, you store keystroke data. This means that when the player presses a certain key on the keyboard, this data is logged (I use an array to store this data). Here's an example:

-----------------------------------------------------------------------------------

var keyInput:Array = new Array();

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);

function keyPressed(Event:KeyboardEvent):void{
        if(Event.keyCode == 37){
                keyInput.push("left");
                trace(keyInput);  
        }else if(Event.keyCode == 39){
                keyInput.push("right");
                trace(keyInput);   
        } else if(Event.keyCode == 38){
                keyInput.push("up");
                trace(keyInput);   
        } else if(Event.keyCode == 40){
                keyInput.push("down");
                trace(keyInput);   
        }
}

-----------------------------------------------------------------------------------

This code would simply add either "left", "right", "up" or "down" depending on what key is pressed to the array, and then the array is traced (similar to printing in other languages). However, this isn't very effective, as if you hold down any of the keys, the corresponding value is constantly pushed into the array. For instance, if I held down the left array key for an extended amount of time, I'd find the array to look like this:

left,left,left,left,left,left,left,left,left etc.

To counter this, you can add a simple if condition:

-----------------------------------------------------------------------------------

var keyInput:Array = new Array();

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);

function keyPressed(Event:KeyboardEvent):void{
        if(Event.keyCode == 37){
                if(keyInput.length - 1 != "left"){
                        keyInput.push("left");
                        trace(keyInput);
                }  
        }else if(Event.keyCode == 39){
                if(keyInput.length - 1 != "right"){
                        keyInput.push("right");
                        trace(keyInput);
                }  
        } else if(Event.keyCode == 38){
                if(keyInput.length - 1 != "up"){
                        keyInput.push("up");
                        trace(keyInput);
                }  
        } else if(Event.keyCode == 40){
                if(keyInput.length - 1 != "down"){
                        keyInput.push("down");
                        trace(keyInput);
                }  
        }
}

-----------------------------------------------------------------------------------

The new if condition is basically asking if the last value in the array is not the same as the one we're trying to add, then allow it to be added. Also, a quick note: You may be wondering why it's "keyInput.length - 1" as opposed to "keyInput.length". This is because an array starts at 0 instead of 1. However, by having a value in keyInput[0], the array's length is 1. Therefore, we must take one off.
Now, this method is all well and dandy for games such as boxSlide, as timing did not matter. However, in the prototype I've been creating recently, timing WAS important. Therefore, I created a timer, and at every key press, I also logged what time it was done. For instance:

-----------------------------------------------------------------------------------

var keyInput:Array = new Array(),  timeInput:Array = new Array();
var timer:Timer = new Timer(1000);
var time:int = 0;

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
timer.addEventListener(TimerEvent.TIMER, gameTimer);


function gameTimer(e:TimerEvent):void{
        time++;
}
timer.start();

function keyPressed(Event:KeyboardEvent):void{
        if(Event.keyCode == 37){
                if(keyInput.length - 1 != "left"){
                        keyInput.push("left");
                        timeInput.push(time);
                }  
        }else if(Event.keyCode == 39){
                if(keyInput.length - 1 != "right"){
                        keyInput.push("right");
                        timeInput.push(time);
                }  
        } else if(Event.keyCode == 38){
                if(keyInput.length - 1 != "up"){
                        keyInput.push("up");
                        timeInput.push(time);
                }  
        } else if(Event.keyCode == 40){
                if(keyInput.length - 1 != "down"){
                        keyInput.push("down");
                        timeInput.push(time);
                }  
        }
}

-----------------------------------------------------------------------------------

In this part, I created an event timer (although, I could've used a simple setInterval - I dislike using these however, as you can't stop and start them, whereas with an event timer you can), and then every time the counter "ticked", the integer time increased by 1. I then pushed the time's value into the timeInput array every time a key was pressed. Pretty simple stuff.
Now that that is done, you can use this information and translate it into some visual feedback. Here's an example of my prototype in action (bear in mind it has other things added to it like colour transformations):

REPLAY GAME

Instructions: Use the left and right arrow keys to control the box. Avoid the obstacles, and make it to the right side of the game screen. As of now, there's no true objective/point for there being a replay, however, I do have plans for this.

Basically all I wanted to say! I found it rather interesting to make. Feedback would be nice. :)