Using the Konami Code (Cheat codes)

Started by Steven_Wagner, Wed 16/12/2009 02:24:42

Previous topic - Next topic

Steven_Wagner

This is my first post so give me a chance.

I'm wondering if it is possible to let a player enter cheat codes during gameplay. Basically quick entering of keystrokes anytime during the game to unlock cheats/secrets. I wanted to throw in an easter egg using the Konami code but I've got no idea where to start.

Gilbert

#1
Yes. One way is to keep track on the 'progress' of the input of the code whenever a key is pressed.
Something like:
Add these global variables:
Code: ags

eKeyCode konami[10];
int konamipoint=0;

Initialise the 'code' (in game_start(), maybe):
Code: ags

konami[0]=eKeyUpArrow;
konami[1]=eKeyUpArrow;
konami[2]=eKeyDownArrow;
konami[3]=eKeyDownArrow;
konami[4]=eKeyLeftArrow;
konami[5]=eKeyRightArrow;
konami[6]=eKeyLeftArrow;
konami[7]=eKeyRightArrow;
konami[8]=eKeyB;
konami[9]=eKeyA;


Then, in on_key_press(), add:
Code: ags

if (keycode==konami[konamipoint]){
  konamipoint++;
  if (konamipoint==10){//all 10 keys entered
    //Do whatever you want here
    konamipoint=0; //Reset code
  }
} else konamipoint=0; //Reset also if wrong/non-code entered

monkey0506

#2
Sure, you can check it the player has pressed a specific key by using the built-in on_key_press event. Depending on the complexity of the cheat in question there are various ways of tracking the user's input.

Correct me if I'm wrong, but isn't the "Konami cheat code" up, down, up, down, left, right, left, right, enter (or something like that)? I'm not 100% sure that's it but I think it's similar. Anyway, we can use that as an example.

This is a pretty complex cheat as the user must enter 9 keys in a specific order to activate the cheat...one wrong key anywhere along the way voids everything up to that point. What I recommend for a cheat such as this is using a couple of arrays. Something like:

Code: ags
eKeyCode cheat[9]; // cheat code sequence
int cheat_index = 0; // the current position in entering the cheat code

function game_start() {
  cheat[0] = eKeyUp;
  cheat[1] = eKeyDown;
  cheat[2] = eKeyUp;
  cheat[3] = eKeyDown;
  cheat[4] = eKeyLeft;
  cheat[5] = eKeyRight;
  cheat[6] = eKeyLeft;
  cheat[7] = eKeyRight;
  cheat[8] = eKeyEnter;
}

function on_key_press(eKeyCode keycode) {
  if ((cheat_index < 9) && (keycode == cheat[cheat_index])) { // entered the next key in the sequence
    if (cheat_index == 8) { // entered all the keys
      Display("Cheat code activated.");
    }
    cheat_index++; // check for the next key
  }
  else cheat_index = 0; // otherwise a wrong key was entered, start over
}


This example is a bit naiive in that you would probably want to iterate over the given input to check for valid subsequences in case of an invalid key (that is, if part of the sequence including the most recently pressed key matches the beginning of the cheat, just not the current position). However, I'm feeling a bit tired and don't feel like debugging right now. :P

Anyway, it should be enough to get you set in the right direction. :)

Edit: I knew very well that Gilbot beat me to the punch, but I was too lazy to NOT post what I typed up. Haha.

Gilbert

Quote from: monkey_05_06 on Wed 16/12/2009 03:35:49
Correct me if I'm wrong, but isn't the "Konami cheat code" up, down, up, down, left, right, left, right, enter (or something like that)? I'm not 100% sure that's it but I think it's similar. Anyway, we can use that as an example.

No, it's UUDDLRLRBA in its original form first introduced in the Famicom version of Gradius. There're variations in subsequent games, such as in the SFC version of Gradius 3 you have to substitute the L and R direction with the L and R triggers (otherwise it's a suicide) and in consoles with different button names (say the playstation, not play station).

Khris

If the cheats are supposed to be text-only, the easiest way is to store the last 20 or so characters in a string:

Code: ags
// above on_key_press

String cheat = "                    ";  // 20 spaces

function check_for_cheat() {
  if (cheat.Substring(14, 6) == "MADCOW") lives++;
  if (cheat.Substring(10, 10) == "BIGBLUECUP") next_level();
  ...
}

// inside on_key_press

  if (keycode > 64 && keycode < 90) {  // A-Z
    cheat = String.Format("%s%c", cheat.Substring(1, 19), keycode);
    check_for_cheat();
  }

Steven_Wagner

Interesting. I'll try it out. Thanks guys.

monkey0506

That's actually a pretty slick method Khris, and with some modifications to your on_key_press it wouldn't have to be limited to (alpha)text-only cheats. There's no technical reason you couldn't store symbols, punctuation, numbers, etc. in the string. And for non-displayable characters you could always check it such as:

Code: ags
if (cheat.Chars[15] == eKeyUpArrow) {}


And Gilbot I said I wasn't 100% :P...I was tired and couldn't be bothered to look it up. I was pretty sure I had it wrong but as I said, it was sufficient for an example.

Gilbert

Quote from: monkey_05_06 on Thu 17/12/2009 21:19:30
Code: ags
if (cheat.Chars[15] == eKeyUpArrow) {}

No, that shouldn't work, as in a String each character is a char, which is only one byte. Some of the keys' "ASCII" codes are > 255. Take eKeyUpArrow for example, its code is 372 according to the manual. It may work if you rehash codes that are larger than 255 into a char value and then put them in the String, but personally I'll say it's no less complicated than the array method and it's probably not worth the trouble (when you mentioned using "if (cheat.Chars[xx]==xxx)..." the code has already lost its original simplicity by just using Substrings for checking).

monkey0506

Oh right, I don't know what I was thinking...I've been saying some rather silly things lately...haha... ::)

SMF spam blocked by CleanTalk