我正在制作一款游戏,并希望实施类似Konami代码的作弊码。
但是我该如何检查按键序列?
我希望它能够正常工作,以便玩家只需键入代码即可触发。
提前致谢!
答案 0 :(得分:5)
修改强> 有关始终有效的代码,请参阅我的其他帖子。如果代码与自身重叠,则以下代码不会检测到代码(例如:“UP,UP,UP,DOWN,DOWN,LEFT,RIGHT,LEFT,RIGHT,B”不起作用)
感谢 Gevorg 指出这一点。
如果只是如何识别你所关注的序列(我假设你知道如何从键盘输入)那么你可以得到如下内容。
int[] sequence = {UP, UP, DOWN, DOWN, LEFT, RIGHT, LEFT, RIGHT, B};
int currentButton = 0;
boolean checkKonami(int keyPressed) {
//Key sequence pressed is correct thus far
if(keyPressed == sequence[currentButton]) {
currentButton++;
//return true when last button is pressed
if(currentButton == sequence.length) {
//Important! Next call to checkKonami()
//would result in ArrayIndexOutOfBoundsException otherwise
currentButton = 0;
return true;
}
}
else {
//Reset currentButton
currentButton = 0;
}
return false;
}
只要按下按键,通过已按下的键,即可调用此功能。当然,在适当的时候修改类型。
答案 1 :(得分:5)
下面是一个检查Konami代码的类,包括“ UP ,UP,UP,DOWN等”的情况。
这适用于任何给定序列。
import java.util.Map;
import java.util.TreeMap;
public class Konami {
static private int[] code =
{UP, UP, DOWN, DOWN, LEFT, RIGHT, LEFT, RIGHT, B};
static private Map<Integer, Integer>[] graph;
static private int currentNode = 0;
public static void main(String args[]) {
//Create graph
graph = generateSequenceMap(code);
//Call checkKonami(key) whenever a key is pressed
}
static public boolean checkKonami(int keyPressed) {
Integer nextNode = graph[currentNode].get(keyPressed);
//Set currentNode to nextNode or to 0 if no matching sub-sequence exists
currentNode = (nextNode==null ? 0 : nextNode);
return currentNode == code.length-1;
}
static private Map<Integer, Integer>[] generateSequenceMap(int[] sequence) {
//Create map
Map<Integer, Integer>[] graph = new Map[sequence.length];
for(int i=0 ; i<sequence.length ; i++) {
graph[i] = new TreeMap<Integer,Integer>();
}
//i is delta
for(int i=0 ; i<sequence.length ; i++) {
loop: for(int j=i ; j<sequence.length-1 ; j++) {
if(sequence[j-i] == sequence[j]) {
System.out.println("If at Node "+j+" you give me seq["+(j-i+1)
+ "] OR " + (sequence[j-i+1]) + " , goto Node " + (j-i+1));
//Ensure that the longest possible sub-sequence is recognized
Integer value = graph[j].get(sequence[j-i+1]);
if(value == null || value < j-i+1)
graph[j].put(sequence[j-i+1], j-i+1);
}
else
break loop;
}
}
return graph;
}
}
答案 2 :(得分:3)
我确定你现在已经过了这个项目,但我刚刚把它实现到我的一个任务中,并希望让其他人找到它。此解决方案将最后n次击键(此处定义为10)记录到循环数组中,并在匹配我们的代码时返回true。作为方法的一部分,您可以轻松地传入不同的长度和代码(但是这种实现并不需要它)。我用^ ^ v v&lt; &GT; &LT; &GT; b a。
public class Code {
private static int[] history = new int[10];
private static int front = 0;
private static int size = 0;
// Here is the Code they must enter (ascii vals for konami).
private static int[] code = {38, 38, 40, 40, 37, 39, 37, 39, 66, 65};
// Static class. No constructor.
private Code(){}
// Adds key-press into history buffer. If code is matched, return true.
public static boolean add(int e){
// Write the value into our key history.
history[(front + size) % 10] = e;
// Stop growing at length 10 and overwrite the oldest value instead.
if (size < 10){
size++;
} else {
front = front + 1 % 10;
}
// Compare our history (from the current front) to the code (from 0)
for(int i = front; i < front + size; i++){
if (history[i % 10] != code[i-front]){
// Any 1 mismatch will abort
return false;
}
}
// Make sure we've logged enough keystrokes so it doesn't fire off
// if your first key press matches the code.
if (size < 10){
return false;
}
return true;
}
享受! :d
答案 3 :(得分:0)
我不知道你的需求是什么。您是尝试使用System.in
和System.out
制作游戏还是尝试制作完整的可视化GUI?
在此期间,请参阅界面java.awt.event.KeyListener
。 (Oracle Documentation)另请参阅Oracle's Tutorial。
根据个人经验,下面的代码近似于您的需要。
import java.awt.event.*; //Specifically KeyListener and KeyEvent
import java.util.ArrayList;
public class Test implements KeyListener {
private final int[] cheatCode = {38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 83, 84, 65, 82, 84} //assuming user types out "start"
private final ArrayList<Integer> KONAMI_CODE = createCheatCode(cheatCode);
private ArrayList<Integer> typedKeys = new ArrayList<Integer>();
public Test() {
//constructor goes here, if necessary
}
public /*static*/ ArrayList<Integer> createCheatCode(int[] code) { //uses Key Codes
ArrayList<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < code.length; i++)
temp.add(new Integer(code[i]));
return temp;
}
// Warning: MUST implement ALL KeyListener methods, or compiler will complain
public /*static*/ void keyPressed(KeyEvent e) {}
public /*static*/ void keyReleased(KeyEvent e) {
typedKeys.add(new Integer(e.getKeyCode()));
}
public /*static*/ void keyTyped(KeyEvent e) {}
public /*static*/ boolean cheatEntered() {
int cheatLen = KONAMI_CODE.size(); // or length, depending on what you use
int index = typedKeys.size() - cheatLen;
if (index < 0)
return false;
return typedKeys.get(index, typedKeys.size()).equals(KONAMI_CODE);
}
}
使用跑步方法时,只需指定
即可if (test.cheatEntered()) {
// do something
}
如果您想要面向对象的编程,可以删除/*static*/
;否则,如果要使用静态方法运行它,请删除/*
和*/
对。
答案 4 :(得分:0)
查看状态模式可能会很有趣,但您可以尝试下面的技巧,因为这是一个简单的案例:
String secretCode
StringBuilder userInput
,用于按住用户按下的键userInput
userInput
中附加的每个密钥后,检查更新的userInput
是否包含secretCode
以及以下内容:userInput.indexOf(secretCode)>-1
您可能希望从现在开始清空userInput
,然后根据时间或在识别序列后清空。