如何在基于html的网站中添加konami代码?
How to add konami code in a website based on html?
我被要求实施科乐美代码
在我目前正在处理的网站上。它应该执行以下操作:
更改背景图片
播放声音
弹出一些
使用 javascript 实现此目的的最简单方法是什么?
将下面的代码放在文件 js/konami.js
中,并在 html 文件的正文中引用它,如下所示:<script src="js/konami.js"></script>
// a key map of allowed keys
var allowedKeys = {
37: 'left',
38: 'up',
39: 'right',
40: 'down',
65: 'a',
66: 'b'
};
// the 'official' Konami Code sequence
var konamiCode = ['up', 'up', 'down', 'down', 'left', 'right', 'left', 'right', 'b', 'a'];
// a variable to remember the 'position' the user has reached so far.
var konamiCodePosition = 0;
// add keydown event listener
document.addEventListener('keydown', function(e) {
// get the value of the key code from the key map
var key = allowedKeys[e.keyCode];
// get the value of the required key from the konami code
var requiredKey = konamiCode[konamiCodePosition];
// compare the key with the required key
if (key == requiredKey) {
// move to the next key in the konami code sequence
konamiCodePosition++;
// if the last key is reached, activate cheats
if (konamiCodePosition == konamiCode.length) {
activateCheats();
konamiCodePosition = 0;
}
} else {
konamiCodePosition = 0;
}
});
function activateCheats() {
document.body.style.backgroundImage = "url('images/cheatBackground.png')";
var audio = new Audio('audio/pling.mp3');
audio.play();
alert("cheats activated");
}
编辑:将顺序更改为 b, a 而不是 a, b。感谢评论!
编辑 2:在调用 activateCheats 后将 konamiCodePosition 重置为 0。感谢评论!
Silentdrummer 有一个很好的答案。我不完全确定,但我认为它最终可能会在输入密集型页面时占用太多内存。重置是个好习惯。不管怎样,这里有一个替代方案。
// Cheat Codes
neededkeys = [38,38,40,40,37,39,37,39,66,65], started = false, count = 0;
$(document).keydown(function(e) {
key = e.keyCode;
if (!started) {
if (key == 38) {
started = true;
}
}
if (started) {
if (neededkeys[count] == key) {
count++;
} else {
reset();
}
if (count == 10) {
reset();
// Do your stuff here
alert('Cheat Codes Activated');
$('body').css('background-color', '#FFA8A8');
// Turn down for what
var s=document.createElement('script');
s.setAttribute('src','https://nthitz.github.io/turndownforwhatjs/tdfw.js');
document.body.appendChild(s);
}
} else {
reset();
}
});
function reset() {
started = false;
count = 0;
}
精简版:
function onKonamiCode(cb) {
var input = '';
var key = '38384040373937396665';
document.addEventListener('keydown', function (e) {
input += ("" + e.keyCode);
if (input === key) {
return cb();
}
if (!key.indexOf(input)) return;
input = ("" + e.keyCode);
});
}
onKonamiCode(function () {alert('\o/')})
我自己的精简版本受此处答案启发:
let cursor = 0;
const KONAMI_CODE = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
document.addEventListener('keydown', (e) => {
cursor = (e.keyCode == KONAMI_CODE[cursor]) ? cursor + 1 : 0;
if (cursor == KONAMI_CODE.length) activate();
});
在这种情况下,触发时调用activate()
函数。
我非常喜欢 Peter 的回答,所以我将其命名空间化并使回调成为可选的。我也用了jquery因为我喜欢它¯\_(ツ)_/¯
var Konami = Konami || {};
Konami.key = '38384040373937396665';
Konami.onCode = function(callback) {
var input = '';
$(document).on("keydown", function(e) {
input += ("" + e.keyCode);
if (input === Konami.key) {
if(typeof callback == 'undefined') {
return alert("⬆⬆⬇⬇⬅➡⬅➡");
}
else {
return callback();
}
}
if (!Konami.key.indexOf(input)) return;
input = ("" + e.keyCode);
});
}
Konami.offCode = function() {
$(document).off("keydown");
}
Konami.onCode();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
作为打字稿模块
const Konami = (() => {
// up, up, down, down, left, right, left, right, b, a, enter
const SEQUENCE: Array<number> = [
38,
38,
40,
40,
37,
39,
37,
39,
66,
65,
13,
];
let head: number = 0;
let isActive: boolean = false;
let callback: Function | undefined;
const start = (cb: Function): void => {
if (isActive) {
return;
}
window.addEventListener("keydown", onKeyDown);
callback = cb;
isActive = true;
};
const stop = (): void => {
if (!isActive) {
return;
}
isActive = false;
window.removeEventListener("keydown", onKeyDown);
};
const onKeyDown = (event) => {
if (event.keyCode === SEQUENCE[head]) {
head++;
if (head === SEQUENCE.length) {
if (callback instanceof Function) {
callback();
}
head = 0;
}
} else {
head = 0;
}
};
return {
start,
stop,
};
})();
export default Konami;
实施:
Konami.start(() => { alert("konami sequence entered!"); });
注释: SEQUENCE 是预期输入的数组。通过使用 head
var,可以维护顺序检查和正确输入的数量。如果输入偏离顺序,它还提供了一种重新启动的简单方法。它还消除了对 "count" 变量的需求。
这是我大约 3 或 4 年前提出的解决方案。在我的例子中,我选择 keyUp 以使其与 keyDown 事件发生的任何操作分开。
此外,无需指定允许使用哪些键,因为 for 循环 会检查针对键盘上的所有键释放了哪个键。
var konamicode = [38,38,40,40,37,39,37,39,66,65];
var kc=0;
function checker() {
if (kc==10) {
// What you want to occur when code matches goes in here.
kc=0; // This resets the sequence.
alert("It Worked!");
}
}
function keyUp(e) {
var keynum;
if (window.event) { keynum = event.keyCode; }
else if (e.which) { keynum = e.which; }
for (i = 0; i < 222; i++) { // The 222 represents all the keys on the keyboard.
var kx=konamicode[kc]; // kx represents the current position in the code sequence.
if (keynum == i) {
// Checks to see if key matches sequence, and resets sequence if it doesn't.
if (i!=kx){kc=0;} else {kc++;}
}
}
checker();
}
要创建您自己的 "Konami Code",请在您的 HTML 代码中添加以下代码片段。
PS:将 const secretCode 更改为...您想要的任何内容:)。使用当前代码,您必须键入 'arrow up' 按钮,然后是 'h',然后是 'i',最后但并非最不重要的是 'arrow down' 按钮。
有问题吗?请教
<script>
const pressed = [];
const secretCode = 'ArrowUphiArrowDown';
window.addEventListener('keyup', (e) => {
console.log(e.key);
pressed.push(e.key);
pressed.splice(-secretCode.length - 1, pressed.length - secretCode.length);
if(pressed.join('').includes(secretCode)) {
console.log("Any source code that will be executed if you enter the correct code.");
}
console.log(pressed);
})
</script>
搭载 Ehsan Kia,
我还没有看到任何人处理向上键可以按 3 次以上的情况,从技术上讲,代码输入正确。
由于条件变长,将其缩小了一点。
let c = 0;
const kCode = [38,38,40,40,37,39,37,39,66,65];
document.addEventListener('keydown', (e) => {
c = (e.keyCode == kCode[c] ? c + 1 : (e.keyCode-38 ? 0 : (c ? (kCode[c-1] == 38 ? c : 0) : 0)));
if(c == kCode.length) activate();
});
使用以下代码。
const keySequence = [];
let konamiString = '';
const konamiCode = [
'ArrowUp',
'ArrowUp',
'ArrowDown',
'ArrowDown',
'ArrowLeft',
'ArrowRight',
'ArrowLeft',
'ArrowRight',
'b',
'a'
];
document.addEventListener('keydown', function(e) {
// To make sure it freezes the scroll when
// the first two keypresses are "ArrowUp"
if (keySequence[0] === 'ArrowUp' && keySequence[1] === 'ArrowUp' && e.key === 'ArrowDown') {
e.preventDefault();
}
});
document.addEventListener('keyup', function(e) {
const doc = document.documentElement;
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
// This make sure it only work
// when the window `scrollTop` is 0.
if (top === 0) {
keySequence.push(e.key);
keySequence.splice(-konamiCode.length - 1, keySequence.length - konamiCode.length);
konamiString = konamiCode.join('');
if (keySequence.join('').includes(konamiString)) {
// Trigger your easter egg here
}
}
});
该代码还会检查 window
的 scrollTop
,以便在前两个按键为“ArrowUp”和 scrollTop
时不会向下滚动 window
是 0
我已经在 my blog 上使用此代码,没有任何问题。
这是我使用 JQuery 的答案:
var konamiCode = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13];
var emptyArray = [];
$(document).keyup (function (e){
emptyArray.push(e.keyCode);
if (JSON.stringify(konamiCode) === JSON.stringify(emptyArray)) {
alert('there you go')
}
});
如评论中所述,如果用户按“向上”3 次而不是两次,当前接受的答案将不起作用。
如果我们考虑这个问题,我们应该意识到该方法的缺陷是假设一个单一的“输入序列”。我的意思是,每次用户按下金手指的第一个键,我们应该认为这可能是一个新的输入序列。
考虑到这个缺陷,一个简单的解决方案是跟踪多个输入序列,而不仅仅是单个输入序列。因此,此处所有使用单个整数 inputPosition
(或任何名称)的答案都会有缺陷*。
*需要说明的是,解决方案可以使用单个整数 inputPosition
如果它在序列被破坏时进行一些“反向行走”检查以查看它的一部分是否可能是新序列的开始顺序,但那样写起来会很困难,读起来也不愉快。
所以,这是我的版本:
const keyCodesByLabel = {
left: 37,
up: 38,
right: 39,
down: 40,
a: 65,
b: 66
};
const konamiCode = [
'up',
'up',
'down',
'down',
'left',
'right',
'left',
'right',
'b',
'a'
];
const konamiKeyCodes = konamiCode.map(label => keyCodesByLabel[label]);
const activateCheats = () => {
alert("godmode enabled");
};
var inputPositions = [];
const incrementOrRemove = (inputPositions, keyCode) => {
return inputPositions.reduce((acc, inputPosition, i, arr) => {
if (keyCode == konamiKeyCodes[inputPosition]) {
inputPosition++;
if (inputPosition == konamiCode.length) {
inputPositions = [];
activateCheats();
arr.splice(1); // eject early by mutating iterated copy
return [];
} else {
acc.push(inputPosition);
return acc;
}
} else {
return acc;
}
}, []);
};
const handleKeyCode = keyCode => {
if (keyCode == konamiKeyCodes[0]) {
inputPositions.push(0);
}
if (inputPositions.length > 0) {
inputPositions = incrementOrRemove(inputPositions, keyCode);
}
};
document.addEventListener('keydown', ({ keyCode }) =>
handleKeyCode(keyCode)
);
inputPositions
以空数组开始。
按下某个键时:
- 如果它是“第一个作弊代码密钥”,那么一个新元素
0
将被添加到数组中。
- 如果
inputPositions
数组不为空,则该数组将“缩减”为另一个数组,我们可以:
- 丢弃序列已被破坏的元素(下一个所需的键与按下的键不同)或
- 递增一个序列已继续的元素(下一个所需的键与按下的键相同)。
在reduce
期间,如果一个元素等于金手指的长度,我们就知道金手指已经成功输入。将 inputPositions
重置为空数组,退出 reduce
并调用 activateCheats
或任何您想发生的事情。
请注意,此解决方案比仅处理“up up up”情况更强大。
例如,假设作弊码是“a a b a a c”。如果用户输入“a a b a a b”,他们应该(正确地)期望能够输入“a a c”并激活作弊。但是任何在序列中断时重置“位置”的解决方案都不会捕捉到它。更重要的是,任何检查按下的键是否是初始键的解决方案都不会捕捉到它。唯一的整体解决方案是拥有一组输入位置。
这是一个简单的版本,它接受回调函数和可选的键代码列表,默认为 konami 代码。
我们通过显示键入的键码并在击中 konami 码时进行报告来进行演示。我们还 运行 另一个寻找键“K”、“O”、“N”、“A”、“M”和“I”。 (我们低效地一直在寻找我们的输出元素。这只是为了演示,所以我认为这不重要。)
const onKonami = (action, seq = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]) => {
const target = seq .join (',')
let current = []
window.addEventListener ('keydown', (e) => {
current = current .concat (e.keyCode) .slice (-seq.length)
if (current .join (',') == target) {action (current)}
})
}
onKonami (
(seq) => {document .getElementById ('output') .innerHTML += `\nKonami code found: [${seq}]\n`}
)
onKonami (
(seq) => {document .getElementById ('output') .innerHTML += `\nThe word Konami code found: [${seq}]\n`},
[...'KONAMI'].map(c => c .charCodeAt (0))
)
<p>Click here and then type</p><p>Try the Konami code (up, up, down, down, left, right, left, right, b, a)</p><p><b>Codes:</b></p><pre id="output"></pre>
<script>document.addEventListener('keydown', e => document .getElementById('output') .innerHTML += e.keyCode + ' - ')</script>
我们保留最后 n
击键的 current
数组,其中 n
是我们目标序列的长度。如果该序列与我们的目标匹配,我们将触发回调。
传递一个事件目标并不困难,所以我们只在特定元素获得焦点时才监听。我把它留作练习。
我被要求实施科乐美代码 在我目前正在处理的网站上。它应该执行以下操作:
更改背景图片
播放声音
弹出一些
使用 javascript 实现此目的的最简单方法是什么?
将下面的代码放在文件 js/konami.js
中,并在 html 文件的正文中引用它,如下所示:<script src="js/konami.js"></script>
// a key map of allowed keys
var allowedKeys = {
37: 'left',
38: 'up',
39: 'right',
40: 'down',
65: 'a',
66: 'b'
};
// the 'official' Konami Code sequence
var konamiCode = ['up', 'up', 'down', 'down', 'left', 'right', 'left', 'right', 'b', 'a'];
// a variable to remember the 'position' the user has reached so far.
var konamiCodePosition = 0;
// add keydown event listener
document.addEventListener('keydown', function(e) {
// get the value of the key code from the key map
var key = allowedKeys[e.keyCode];
// get the value of the required key from the konami code
var requiredKey = konamiCode[konamiCodePosition];
// compare the key with the required key
if (key == requiredKey) {
// move to the next key in the konami code sequence
konamiCodePosition++;
// if the last key is reached, activate cheats
if (konamiCodePosition == konamiCode.length) {
activateCheats();
konamiCodePosition = 0;
}
} else {
konamiCodePosition = 0;
}
});
function activateCheats() {
document.body.style.backgroundImage = "url('images/cheatBackground.png')";
var audio = new Audio('audio/pling.mp3');
audio.play();
alert("cheats activated");
}
编辑:将顺序更改为 b, a 而不是 a, b。感谢评论!
编辑 2:在调用 activateCheats 后将 konamiCodePosition 重置为 0。感谢评论!
Silentdrummer 有一个很好的答案。我不完全确定,但我认为它最终可能会在输入密集型页面时占用太多内存。重置是个好习惯。不管怎样,这里有一个替代方案。
// Cheat Codes
neededkeys = [38,38,40,40,37,39,37,39,66,65], started = false, count = 0;
$(document).keydown(function(e) {
key = e.keyCode;
if (!started) {
if (key == 38) {
started = true;
}
}
if (started) {
if (neededkeys[count] == key) {
count++;
} else {
reset();
}
if (count == 10) {
reset();
// Do your stuff here
alert('Cheat Codes Activated');
$('body').css('background-color', '#FFA8A8');
// Turn down for what
var s=document.createElement('script');
s.setAttribute('src','https://nthitz.github.io/turndownforwhatjs/tdfw.js');
document.body.appendChild(s);
}
} else {
reset();
}
});
function reset() {
started = false;
count = 0;
}
精简版:
function onKonamiCode(cb) {
var input = '';
var key = '38384040373937396665';
document.addEventListener('keydown', function (e) {
input += ("" + e.keyCode);
if (input === key) {
return cb();
}
if (!key.indexOf(input)) return;
input = ("" + e.keyCode);
});
}
onKonamiCode(function () {alert('\o/')})
我自己的精简版本受此处答案启发:
let cursor = 0;
const KONAMI_CODE = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
document.addEventListener('keydown', (e) => {
cursor = (e.keyCode == KONAMI_CODE[cursor]) ? cursor + 1 : 0;
if (cursor == KONAMI_CODE.length) activate();
});
在这种情况下,触发时调用activate()
函数。
我非常喜欢 Peter 的回答,所以我将其命名空间化并使回调成为可选的。我也用了jquery因为我喜欢它¯\_(ツ)_/¯
var Konami = Konami || {};
Konami.key = '38384040373937396665';
Konami.onCode = function(callback) {
var input = '';
$(document).on("keydown", function(e) {
input += ("" + e.keyCode);
if (input === Konami.key) {
if(typeof callback == 'undefined') {
return alert("⬆⬆⬇⬇⬅➡⬅➡");
}
else {
return callback();
}
}
if (!Konami.key.indexOf(input)) return;
input = ("" + e.keyCode);
});
}
Konami.offCode = function() {
$(document).off("keydown");
}
Konami.onCode();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
作为打字稿模块
const Konami = (() => {
// up, up, down, down, left, right, left, right, b, a, enter
const SEQUENCE: Array<number> = [
38,
38,
40,
40,
37,
39,
37,
39,
66,
65,
13,
];
let head: number = 0;
let isActive: boolean = false;
let callback: Function | undefined;
const start = (cb: Function): void => {
if (isActive) {
return;
}
window.addEventListener("keydown", onKeyDown);
callback = cb;
isActive = true;
};
const stop = (): void => {
if (!isActive) {
return;
}
isActive = false;
window.removeEventListener("keydown", onKeyDown);
};
const onKeyDown = (event) => {
if (event.keyCode === SEQUENCE[head]) {
head++;
if (head === SEQUENCE.length) {
if (callback instanceof Function) {
callback();
}
head = 0;
}
} else {
head = 0;
}
};
return {
start,
stop,
};
})();
export default Konami;
实施:
Konami.start(() => { alert("konami sequence entered!"); });
注释: SEQUENCE 是预期输入的数组。通过使用 head
var,可以维护顺序检查和正确输入的数量。如果输入偏离顺序,它还提供了一种重新启动的简单方法。它还消除了对 "count" 变量的需求。
这是我大约 3 或 4 年前提出的解决方案。在我的例子中,我选择 keyUp 以使其与 keyDown 事件发生的任何操作分开。 此外,无需指定允许使用哪些键,因为 for 循环 会检查针对键盘上的所有键释放了哪个键。
var konamicode = [38,38,40,40,37,39,37,39,66,65];
var kc=0;
function checker() {
if (kc==10) {
// What you want to occur when code matches goes in here.
kc=0; // This resets the sequence.
alert("It Worked!");
}
}
function keyUp(e) {
var keynum;
if (window.event) { keynum = event.keyCode; }
else if (e.which) { keynum = e.which; }
for (i = 0; i < 222; i++) { // The 222 represents all the keys on the keyboard.
var kx=konamicode[kc]; // kx represents the current position in the code sequence.
if (keynum == i) {
// Checks to see if key matches sequence, and resets sequence if it doesn't.
if (i!=kx){kc=0;} else {kc++;}
}
}
checker();
}
要创建您自己的 "Konami Code",请在您的 HTML 代码中添加以下代码片段。 PS:将 const secretCode 更改为...您想要的任何内容:)。使用当前代码,您必须键入 'arrow up' 按钮,然后是 'h',然后是 'i',最后但并非最不重要的是 'arrow down' 按钮。
有问题吗?请教
<script>
const pressed = [];
const secretCode = 'ArrowUphiArrowDown';
window.addEventListener('keyup', (e) => {
console.log(e.key);
pressed.push(e.key);
pressed.splice(-secretCode.length - 1, pressed.length - secretCode.length);
if(pressed.join('').includes(secretCode)) {
console.log("Any source code that will be executed if you enter the correct code.");
}
console.log(pressed);
})
</script>
搭载 Ehsan Kia,
我还没有看到任何人处理向上键可以按 3 次以上的情况,从技术上讲,代码输入正确。
由于条件变长,将其缩小了一点。
let c = 0;
const kCode = [38,38,40,40,37,39,37,39,66,65];
document.addEventListener('keydown', (e) => {
c = (e.keyCode == kCode[c] ? c + 1 : (e.keyCode-38 ? 0 : (c ? (kCode[c-1] == 38 ? c : 0) : 0)));
if(c == kCode.length) activate();
});
使用以下代码。
const keySequence = [];
let konamiString = '';
const konamiCode = [
'ArrowUp',
'ArrowUp',
'ArrowDown',
'ArrowDown',
'ArrowLeft',
'ArrowRight',
'ArrowLeft',
'ArrowRight',
'b',
'a'
];
document.addEventListener('keydown', function(e) {
// To make sure it freezes the scroll when
// the first two keypresses are "ArrowUp"
if (keySequence[0] === 'ArrowUp' && keySequence[1] === 'ArrowUp' && e.key === 'ArrowDown') {
e.preventDefault();
}
});
document.addEventListener('keyup', function(e) {
const doc = document.documentElement;
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
// This make sure it only work
// when the window `scrollTop` is 0.
if (top === 0) {
keySequence.push(e.key);
keySequence.splice(-konamiCode.length - 1, keySequence.length - konamiCode.length);
konamiString = konamiCode.join('');
if (keySequence.join('').includes(konamiString)) {
// Trigger your easter egg here
}
}
});
该代码还会检查 window
的 scrollTop
,以便在前两个按键为“ArrowUp”和 scrollTop
时不会向下滚动 window
是 0
我已经在 my blog 上使用此代码,没有任何问题。
这是我使用 JQuery 的答案:
var konamiCode = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13];
var emptyArray = [];
$(document).keyup (function (e){
emptyArray.push(e.keyCode);
if (JSON.stringify(konamiCode) === JSON.stringify(emptyArray)) {
alert('there you go')
}
});
如评论中所述,如果用户按“向上”3 次而不是两次,当前接受的答案将不起作用。
如果我们考虑这个问题,我们应该意识到该方法的缺陷是假设一个单一的“输入序列”。我的意思是,每次用户按下金手指的第一个键,我们应该认为这可能是一个新的输入序列。
考虑到这个缺陷,一个简单的解决方案是跟踪多个输入序列,而不仅仅是单个输入序列。因此,此处所有使用单个整数 inputPosition
(或任何名称)的答案都会有缺陷*。
*需要说明的是,解决方案可以使用单个整数 inputPosition
如果它在序列被破坏时进行一些“反向行走”检查以查看它的一部分是否可能是新序列的开始顺序,但那样写起来会很困难,读起来也不愉快。
所以,这是我的版本:
const keyCodesByLabel = {
left: 37,
up: 38,
right: 39,
down: 40,
a: 65,
b: 66
};
const konamiCode = [
'up',
'up',
'down',
'down',
'left',
'right',
'left',
'right',
'b',
'a'
];
const konamiKeyCodes = konamiCode.map(label => keyCodesByLabel[label]);
const activateCheats = () => {
alert("godmode enabled");
};
var inputPositions = [];
const incrementOrRemove = (inputPositions, keyCode) => {
return inputPositions.reduce((acc, inputPosition, i, arr) => {
if (keyCode == konamiKeyCodes[inputPosition]) {
inputPosition++;
if (inputPosition == konamiCode.length) {
inputPositions = [];
activateCheats();
arr.splice(1); // eject early by mutating iterated copy
return [];
} else {
acc.push(inputPosition);
return acc;
}
} else {
return acc;
}
}, []);
};
const handleKeyCode = keyCode => {
if (keyCode == konamiKeyCodes[0]) {
inputPositions.push(0);
}
if (inputPositions.length > 0) {
inputPositions = incrementOrRemove(inputPositions, keyCode);
}
};
document.addEventListener('keydown', ({ keyCode }) =>
handleKeyCode(keyCode)
);
inputPositions
以空数组开始。
按下某个键时:
- 如果它是“第一个作弊代码密钥”,那么一个新元素
0
将被添加到数组中。 - 如果
inputPositions
数组不为空,则该数组将“缩减”为另一个数组,我们可以:
- 丢弃序列已被破坏的元素(下一个所需的键与按下的键不同)或
- 递增一个序列已继续的元素(下一个所需的键与按下的键相同)。
在reduce
期间,如果一个元素等于金手指的长度,我们就知道金手指已经成功输入。将 inputPositions
重置为空数组,退出 reduce
并调用 activateCheats
或任何您想发生的事情。
请注意,此解决方案比仅处理“up up up”情况更强大。
例如,假设作弊码是“a a b a a c”。如果用户输入“a a b a a b”,他们应该(正确地)期望能够输入“a a c”并激活作弊。但是任何在序列中断时重置“位置”的解决方案都不会捕捉到它。更重要的是,任何检查按下的键是否是初始键的解决方案都不会捕捉到它。唯一的整体解决方案是拥有一组输入位置。
这是一个简单的版本,它接受回调函数和可选的键代码列表,默认为 konami 代码。
我们通过显示键入的键码并在击中 konami 码时进行报告来进行演示。我们还 运行 另一个寻找键“K”、“O”、“N”、“A”、“M”和“I”。 (我们低效地一直在寻找我们的输出元素。这只是为了演示,所以我认为这不重要。)
const onKonami = (action, seq = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]) => {
const target = seq .join (',')
let current = []
window.addEventListener ('keydown', (e) => {
current = current .concat (e.keyCode) .slice (-seq.length)
if (current .join (',') == target) {action (current)}
})
}
onKonami (
(seq) => {document .getElementById ('output') .innerHTML += `\nKonami code found: [${seq}]\n`}
)
onKonami (
(seq) => {document .getElementById ('output') .innerHTML += `\nThe word Konami code found: [${seq}]\n`},
[...'KONAMI'].map(c => c .charCodeAt (0))
)
<p>Click here and then type</p><p>Try the Konami code (up, up, down, down, left, right, left, right, b, a)</p><p><b>Codes:</b></p><pre id="output"></pre>
<script>document.addEventListener('keydown', e => document .getElementById('output') .innerHTML += e.keyCode + ' - ')</script>
我们保留最后 n
击键的 current
数组,其中 n
是我们目标序列的长度。如果该序列与我们的目标匹配,我们将触发回调。
传递一个事件目标并不困难,所以我们只在特定元素获得焦点时才监听。我把它留作练习。