Javascript - Increasing value by keypress, only once - javascript

im trying to get the value of a variable that i have to increase by 5 each time that the up key is pressed.
Currently i have the variable increasing upon keypress etc but the main problem i have is that from one keypress, the value will continue rise. For example, value would start at 5, upon one keypress would continue to rise by 5 each time and would stop just after 600. Whereas i want it to start at 5 then upon each keypress go to 10,15,20....
Here's the code i have, i'd be grateful for the help on where im going wrong etc
var projectoryHeight = 5;
function setHeight()
{
projectoryHeight = projectoryHeight + 5;
};
if (keyCode == 38)
{
setHeight();
console.log(projectoryHeight);
};
The code that relates to keycode for the up key being placed, is inside a rendering function, for use with requestAnimationFrame(). I feel like this may be what is causing the issue of it continuing to count however I have tried moving it outside of this function and nothing happens.
Javascript being used alongside THREE.js & Physi.js
More code to help with problem:
var render = function() {
requestAnimationFrame(render);
scene.simulate();
let keyFlag = false;
// Update the title page shape rotations
sphere.rotation.y += 0.06;
sphere.rotation.x += 0.10;
sphere.rotation.z += 0.06;
document.addEventListener("keydown", (e) => {
if(e.code == 'KeyW'){
$(title).hide();
$(keyTitle).hide();
scene.remove(sphere);
sphere.geometry.dispose();
sphere.material.dispose();
//add all the game functions here
scene.add(cube);
scene.add(firingBall);
scene.add(struct1);
scene.add(struct2);
scene.add(struct3);
scene.add(struct4);
scene.add(struct5);
scene.add(struct6);
scene.simulate();
}
});
document.addEventListener("keydown", (e) => {
if(e.code == 'Space'){
firingBall.setLinearVelocity(new THREE.Vector3(speedOfBall, projectoryHeight, 0));
}
});
document.addEventListener("keydown", (e) => {
if(e.code == 'ArrowUp'){
if (!keyFlag) {
keyFlag = true;
projectoryHeight = projectoryHeight + 5;
console.log(projectoryHeight);
}
}
});
document.addEventListener("keydown", (e) => {
if(e.code == 'ArrowDown'){
if (!keyFlag) {
keyFlag = true;
projectoryHeight = projectoryHeight - 5;
console.log(projectoryHeight);
}
}
});
document.addEventListener("keyup", (e) => {
if(e.code == 'ArrowUp'){
if (keyFlag){
console.log("stopped");
keyFlag = false;
}
}
});
document.addEventListener("keyup", (e) => {
if(e.code == 'ArrowDown'){
if (keyFlag){
console.log("stopped");
keyFlag = false;
}
}
});
renderer.autoClear = false;
renderer.clear();
renderer.render(backgroundScene, backgroundCamera);
renderer.render(scene, camera);
};
This is the function where keypresses etc are used, inside the render function. Also starts the animation frames and game physics.
This function is then called directly after it is declared
Thanks

You need to set a flag that tells you whether or not a key is being held down. To do this in simple form, you can use the keydown event in conjunction with the keyup event. In the following code the key can be held down but it only performs an action once based on the flag.
i.addEventListener("keydown", (e) => {
if (!keyflag) console.log(e.key);
keyflag = true;
});
i.addEventListener("keyup", (e) => {
if (keyflag) console.log("released!");
keyflag = false;
});
let i = document.querySelector("input"),
keyflag = false;
i.addEventListener("keydown", (e) => {
if (!keyflag) console.log(e.key);
else e.preventDefault();
keyflag = true;
});
i.addEventListener("keyup", (e) => {
if (keyflag) console.log("released!");
else e.preventDefault();
keyflag = false;
});
<input>
Note inside the snippet I use e.preventDefault() to stop letters appearing in the input box. My intention was only that this would make it easier to see.

Related

Restart game by spacebar instead of pointerdown

I'd like to restart my game with the spacebar instead of of using my mouse. I was trying some things out, but it didn't work like:
this.restart.input.keyboard.on('keyup_SPACE', () => {
this.dino.setVelocityY(0);
this.dino.body.height = 92;
this.dino.body.offset.y = 0;
this.physics.resume();
this.obsticles.clear(true, true);
this.isGameRunning = true;
this.gameOverScreen.setAlpha(0);
this.anims.resumeAll();
})
This is what I have:
this.restart.on('pointerdown', () => {
this.dino.setVelocityY(0);
this.dino.body.height = 92;
this.dino.body.offset.y = 0;
this.physics.resume();
this.obsticles.clear(true, true);
this.isGameRunning = true;
this.gameOverScreen.setAlpha(0);
this.anims.resumeAll();
})
this.restart = this.add.image(0, 80, 'restart').setInteractive();
this.gameOverScreen.add([
this.gameOverText, this.restart
])
You can catch keyup event like this (checking the keyCode corresponding to the spacebar):
document.body.addEventListener("keyup", (e) => {
if(e.keyCode === 32) console.log("Spacebar pressed");
});
You could restart the game when the spacebar is pressed, could look something like this.
document.body.addEventListener("keyup", (e) => {
if(e.keyCode === 32) {
this.restart();
}
});

Manipulating integers using a keyboard

Sorry for the vague post. I'm stuck on an online coding challenge, where the objective is that it must be possible to increase and or decrease a number using a keyboard, using the up and down keys. (all HTML-content must be created using JS)
It wants me to use addEventListener without an element object - use the event type keydown. Regardless if the buttons or the up and down keys are used, the decrease button must be 'disabled' if the values in the div-element is '1', and there can't be a number less than '1' in the div element.
Here is my code so far - I'm not sure how to incorporate the functions described above:
addEventListener('load', function() {
let button = document.createElement('input')
let secondButton = document.createElement('input')
button.setAttribute('type', 'button')
button.setAttribute('id', 'increase')
secondButton.setAttribute('type', 'button')
secondButton.setAttribute('id', 'decrease')
document.body.appendChild(button)
document.body.appendChild(secondButton)
let div = document.createElement('div')
div.setAttribute('id', 'bet-size')
div.textContent = '1'
document.body.appendChild(div)
if (Number(div.textContent) === 1) {
secondButton.setAttribute('disabled', '')
}
const increase = function() {
div.textContent = Number(div.textContent) + 1
if (Number(div.textContent) > 1) {
secondButton.disabled = false
}
}
const decrease = function() {
if (Number(div.textContent) === 2) {
secondButton.disabled = true
}
if (Number(div.textContent) > 1) {
div.textContent = Number(div.textContent) - 1
}
}
button.addEventListener('click', increase)
secondButton.addEventListener('click', decrease)
})
You want to use keyDown event's keyCode property to determine the pressed key and call increase() or decrease() accordingly. keyCode stores a number indicating the key that caused the event evocation. There are a number of sites on the internet to determine your desired key code, like this for example.
You also might want to use keyUp to determine key releases again because you might get these events multiple times and only want to react to one of them.
let isKeyDown = false;
const handleKeyDown = function(event) {
if(isKeyDown == false)
{
isKeyDown = true;
if(event.keyCode == 38) // Arrow Up
{
event.preventDefault(); // Prevent page scrolling
increase();
}
else if(event.keyCode == 40) // Arrow Down
{
event.preventDefault(); // Prevent page scrolling
decrease();
}
}
}
const handleKeyUp = function(event) {
if(isKeyDown == true)
{
isKeyDown = false;
}
}
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
Your expanded example might look like this, then:
addEventListener('load', function() {
let button = document.createElement('input')
let secondButton = document.createElement('input')
button.setAttribute('type', 'button')
button.setAttribute('id', 'increase')
secondButton.setAttribute('type', 'button')
secondButton.setAttribute('id', 'decrease')
document.body.appendChild(button)
document.body.appendChild(secondButton)
let div = document.createElement('div')
div.setAttribute('id', 'bet-size')
div.textContent = '1'
document.body.appendChild(div)
if (Number(div.textContent) === 1 ) {
secondButton.setAttribute('disabled', '')
}
const increase = function() {
div.textContent = Number(div.textContent) + 1
if (Number(div.textContent) > 1) {
secondButton.disabled = false
}
}
const decrease = function() {
if (Number(div.textContent) === 2) {
secondButton.disabled = true
}
if (Number(div.textContent) > 1) {
div.textContent = Number(div.textContent) - 1
}
}
// Required to remember if a key is already pressed or not
let isKeyDown = false;
//Event handlers for KeyUp And KeyDown
const handleKeyDown = function(event) {
if(isKeyDown == false)
{
isKeyDown = true;
if(event.keyCode == 38) // Up
{
event.preventDefault(); // Prevent page scrolling
increase();
}
else if(event.keyCode == 40) // Down
{
event.preventDefault(); // Prevent page scrolling
decrease();
}
}
}
const handleKeyUp = function(event) {
if(isKeyDown == true)
{
isKeyDown = false;
}
}
button.addEventListener('click', increase)
secondButton.addEventListener('click', decrease)
//Add the new event handlers to the document's keydown and keyup events
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
})

I can't get a simple throttle function to work

I know there is a bunch of other people who have posted questions about throttling functions and I have scrolled through them but most if not all are way above my level or include stuff like jquery and really weird logic to function.
I'm just trying to limit the number of changes a user can make per second, to stop them from spamming stuff.
I wrote my code with the help of this youtube video and I can understand it, for the most part. However it doesn't seem to work, I can't see any issues or blocks.
This is my first attempt at implementing throttling:
const throttle = (bad_func, limit) =>{
var flag = true;
document.getElementById('key').innerHTML = flag;
return function(){
let context = this;
let args = arguments;
if(flag){
bad_func.apply(context,args);
bad_func();
flag = false;
setTimeout(()=>{
flag = true;
},limit);
}
}
}
ThrottledFunc = throttle(logKey, 4000);
window.addEventListener('keydown', ThrottledFunc);
function logKey(e){
// document.getElementById('EKey').innerHTML = e.which;
if (e.which == 87){
document.getElementById('demo').innerHTML = 'forwards';
}
else if (e.which == 83){
document.getElementById('demo').innerHTML = 'backwards';
}
else{
document.getElementById('demo').innerHTML = 'empty';
}
}
But it doesn't work, I can still spam w and s. The "demo" changes but there is no delay.
For my second attempt I just said screw it and tried to implement the timeout thing into the function, still no luck:
window.addEventListener('keydown', logKey);
function logKey(e){
var flag = true;
var limit = 10000;
document.getElementById('key').innerHTML = flag;
if(flag){
if (e.which == 87){
flag = false;
document.getElementById('demo').innerHTML = 'forwards';
setTimeout(()=>{
flag =true;
}, limit);
}
else if (e.which == 83){
document.getElementById('demo').innerHTML = 'backwards';
flag = false;
setTimeout(()=>{
flag =true;
}, limit);
}
}
else{
document.getElementById('demo').innerHTML = 'empty';
}
}
What am I doing wrong?
I went thru a similar exercise a couple years ago.
I ended up coming up with a really tiny implementation:
throttled-event-listener.js
Here's a live demo that uses it.
And here's some docs on what the calling code looks like.
Hope this helps!
You need to build a closure, that means the variable flag must preserve its value between each logKey() invocation. The solution is to store it global (as below) or in a parent scope where logKey can access it.
window.addEventListener("keydown", logKey);
var flag = true;
var limit = 10000;
function logKey(e) {
document.getElementById("key").innerHTML = flag;
if (flag) {
if (e.which == 87) {
flag = false;
document.getElementById("demo").innerHTML = "forwards";
setTimeout(() => {
flag = true;
}, limit);
} else if (e.which == 83) {
document.getElementById("demo").innerHTML = "backwards";
flag = false;
setTimeout(() => {
flag = true;
}, limit);
}
} else {
document.getElementById("demo").innerHTML = "empty";
}
}
<div id="demo"></div>
<div id="key"></div>
I would suggest using a library like lodash that provides a throttle function.

Javascript Play/Pause button Keyboard event

I'm still working on a music player, mouse controls have been assigned, but I'm having little trouble with keyboard events on the PLAY/PAUSE button.
So far, I got the user to be able to "click" the PLAY button by pressing SPACEBAR. What happens is that the PLAY button is being hidden and replaced by the PAUSE button.
Which I want now is getting the user to be able to press the SPACEBAR again so it "clicks" PAUSE, and therefore shows PLAY again.
Here is what I have :
html
<div>
</div>
script
<script>
/* mouse */
$('#play').on('click', function(event) {
console.log('play click clicked');
//currentPlayingTrack.play();
$('#pause').show();
$('#play').hide();
$('#pause').on('click', function(event) {
//currentPlayingTrack.pause();
$('#pause').hide();
$('#play').show();
});
/* keyboard */
var play = document.getElementById("play");
var pause = document.getElementById("pause");
document.onkeydown = function (e) {
if (e.keyCode == 32) {
play.click();
}
else if(e.keyCode == 32) {
pause.click();
}
};
</script>
What am I missing ?
the mistake is here:
document.onkeydown = function (e) {
if (e.keyCode == 32) {
play.click();
} else if(e.keyCode == 32) {
pause.click();
}
};
the second condition cannot be executed because everytime the keyCode is 32 it's goes only in the first conditions.
You can declare a variable "isPlaying" that indicate you if the player is playing.
var isPlaying = false;
document.onkeydown = function (e) {
if (e.keyCode == 32) {
if (isPlaying) {
pause.click();
} else {
play.click();
}
isPlaying = !isPlaying; // if true equal false, if false equal true
}
};
the first mistake is that you arent closing all brackets,the second is this part of code:
if (e.keyCode == 32) {
play.click();
}
else if(e.keyCode == 32) {
pause.click();
}
i suggest to use a variable for check if the button play is being pressed or not:
var ispaused = true;
var play = document.getElementById("play");
var pause = document.getElementById("pause");
$('#play').on('click', function(event) {
ispaused = false;
console.log('play click clicked');
//currentPlayingTrack.play();
$('#pause').show();
$('#play').hide();
/* keyboard */
});
$('#pause').on('click', function(event) {
ispaused = true;
//currentPlayingTrack.pause();
$('#pause').hide();
$('#play').show();
});
document.onkeydown = function (e) {
if (e.keyCode == 32) {
if(ispaused == true ){
play.click();
}else{
pause.click();
}
}
};
fiddle
It works. you double check space keyCode when you space anytime and the first condition would be true every single time.
Second, you need to use $bla instead for $("#blablabla") .It runs almost 600 line Code with find object you select everytime.So don't be let duplicate work.
Final,$() is lik $(doucument).ready().It's all done when rendered it's done and DOM it's OK.THAT IS!
** code **
$(function () {
let $play = $("#play");
let $pause = $("#pause");
$play.on('click', function (event) {
console.log('play click clicked');
//currentPlayingTrack.play();
$pause.show();
$play.hide();
});
$pause.on('click', function (event) {
//currentPlayingTrack.pause();
$pause.hide();
$play.show();
});
/* keyboard */
document.onkeydown = function (e) {
if (e.keyCode == 32) {
toggle = !toggle;
$play.trigger("click");
}
else if (e.keyCode == 32) {
toggle = !toggle;
$pause.trigger("click");
}
};
});
Seems like you're missing a bit more knowledge of js which will come with time :) Here's a codepen on how I'd accomplish this.
http://codepen.io/smplejohn/pen/zNVbRb
Play
Pause
$('.playpause').click(function(){
$('.playpause').toggle();
return false;
});
document.onkeydown = function (e) {
if (e.keyCode == 32){
$('.playpause').toggle();
}
};

keydown event not fired, why?

In JavaScript, I hold two keys down, and keydown is fired perfectly. When I release one of the keys, keyupis fired. So far so good. But I am still holding one key down, so why arent keydown fired? I need this to happen in my game. Am I doing something wrong? Is this the expected response? Is there a work around or something?
window.addEventListener("keydown",
function (e) {
console.log('down');
}, false);
window.addEventListener('keyup',
function (e) {
console.log('up');
}, false);
Looks to me like you're trying to do something like this:
var down = false;
var up = false;
document.body.addEventListener('keydown', function (e) {
if(e.which === 40) {
down = true;
}
if(e.which === 38) {
up = true;
}
});
document.body.addEventListener('keyup', function (e) {
if(e.which === 40) {
down = false;
}
if(e.which === 38) {
up = false;
}
// logic here for one but not the other
if(down && !up) {
alert('down but not up!');
}
});

Categories