I am currently doing this for input handling:
var upKey = false;
var downKey = false;
var leftKey = false;
var rightKey = false;
var sqrt2over2 = 0.707106781;
var MoveSpeed = 20.0;
var Horizontal = false;
var Vertical = false;
document.onkeyup=function(e){
if(e.which == 87)
{
Vertical = false;
upKey = false;
}
if(e.which == 83)
{
Vertical = false;
downKey = false;
}
if(e.which == 65)
{
Horizontal = false;
leftKey = false;
}
if(e.which == 68)
{
Horizontal = false;
rightKey = false;
}
}
document.onkeydown=function(e){
//Up arrow key
if(e.which == 87) upKey = true;
//Down arrow key
if(e.which == 83) downKey = true;
//Left arrow key
if(e.which == 65) leftKey = true;
//Right arrow key
if(e.which == 68) rightKey = true;
var diagonals = Vertical && Horizontal;
if(downKey)
{
Vertical = true;
moveY -= diagonals ? MoveSpeed * sqrt2over2: MoveSpeed;
}
if(upKey)
{
Vertical = true;
moveY += diagonals ? MoveSpeed * sqrt2over2: MoveSpeed;
}
if(rightKey)
{
Horizontal = true;
moveX -= diagonals ? MoveSpeed * sqrt2over2: MoveSpeed;
}
if(leftKey)
{
Horizontal = true;
moveX += diagonals ? MoveSpeed * sqrt2over2: MoveSpeed;
}
}
I need to have this work so that the screen doesn't pause at all when you press another direction or multiple directions. Currently there is a bit of a pause. Is there a setting to turn off this pause or is there another approach to pooling and responding to input which circumvents this dilemma?
I think the pause is due to key repeat rate. Take a look at this question / answers: remove key press delay in javascript
The problem is that you're using the operating system's key repeat as the 'tick' for moving. Instead of this you should use setInterval to create your own tick for moving, and then monitor keydown / keyup to change the direction of movement.
Related
I want the movement to be smooth upon pressing a key, the object does an initial movement and then starts moving completely when holding down the button.
//movement speed
var xSpeed = 0.5;
var zSpeed = 0.5;
document.addEventListener("keydown", onDocumentKeyDown, false);
function onDocumentKeyDown(event) {
var keyCode = event.which;
if (keyCode == 87) { //W KEY
car.position.z -= zSpeed;
} else if (keyCode == 83) { //S KEY
car.position.z += zSpeed;
} else if (keyCode == 65) { //A KEY
car.position.x -= xSpeed;
} else if (keyCode == 68) { //D KEY
car.position.x += xSpeed;
} else if (keyCode == 32) {
car.position.set(0, 0, 0);
}
};
Trying to get a GLTF imported model to be controlled on a plane with keyboard controls smoothly.
Tried wrapping the program in a loop and made the state of the keyboard available inside the scope of that loop but couldn't get it working
You could try an approach where the velocity is modified upon keyup/keydown, and the loop just modifies the car's position based on the velocity.
// initial movement speed
var xSpeed = 0;
var zSpeed = 0;
document.addEventListener("keydown", onDocumentKeyDown, false);
document.addEventListener("keydown", onDocumentKeyUp, false);
function onDocumentKeyDown(event) {
var keyCode = event.which;
if (keyCode == 87) { //W KEY
zSpeed = -0.5;
} ... // do so for the rest of the keys
};
function onDocumentKeyUp(event) {
var keyCode = event.which;
if (keyCode == 87) { //W KEY
zSpeed = 0;
} ... // do so for the rest of the keys
};
function loop() {
car.position.z += zSpeed;
car.position.x += xSpeed;
window.requestAnimationFrame(loop);
}
If you are interested in more eased movement, e.g. the car doesn't just start moving at constant velocity but ramps up and slows down, consider having the keyup/keydown modify an acceleration factor, and the loop modifies the velocity.
This is a good in-depth article by Daniel Shiffman about attempting to represent the real world with code:
https://natureofcode.com/book/chapter-1-vectors/
This question already has answers here:
How to detect if multiple keys are pressed at once using JavaScript?
(19 answers)
Closed 5 years ago.
So i am making a html5 game where i was working in movement. Player can move with w, a, s ,d in key. That is working well but i wanted to add a power ..like if player press a + space-bar or d + space-bar an ability will trigger.
i used and operator and it should have worked in my theory but it's not working.
I am new in html5 and any help will be appreciated. thanks in advance.
Here is my code... Just copy paste on html note.
<canvas id="canvas" width="800" height="500" style="border:1px solid #000000;"></canvas>
<script>
var c = document.getElementById("canvas").getContext("2d");
var WIDTH = 800;
var HEIGHT = 500;
var player = {
x: Math.random() * WIDTH,
y: Math.random() * HEIGHT,
width: 30,
height: 30,
color: 'black',
pressingDown: false,
pressingUp: false,
pressingLeft: false,
pressingRight: false,
pressinpowerRight: false,
pressinpowerLeft: false,
};
drawEntity = function(e) {
c.fillStyle = e.color;
c.fillRect(e.x - e.width / 2, e.y - e.height / 2, e.width, e.height);
}
document.onkeydown = function(event) {
if (event.keyCode === 68) //d
player.pressingRight = true;
else if (event.keyCode === 83) //s
player.pressingDown = true;
else if (event.keyCode === 65) //a
player.pressingLeft = true;
else if (event.keyCode === 87) // w
player.pressingUp = true;
else if (event.keyCode === 68 && event.keyCode === 32) // this statement is not working
player.pressinpowerRight = true;
else if (event.keyCode === 65 && event.keyCode === 32) // this statement is not working
player.pressinpowerLeft = true;
}
document.onkeyup = function(event) {
if (event.keyCode === 68) //d
player.pressingRight = false;
else if (event.keyCode === 83) //s
player.pressingDown = false;
else if (event.keyCode === 65) //a
player.pressingLeft = false;
else if (event.keyCode === 87) // w
player.pressingUp = false;
else if (event.keyCode === 68 && event.keyCode === 32) // not working
player.pressinpowerRight = false;
else if (event.keyCode === 65 && event.keyCode === 32) // not working
player.pressinpowerLeft = false;
}
updatePlayerPosition = function() {
if (player.pressingRight)
player.x += 5;
if (player.pressingLeft)
player.x -= 5;
if (player.pressingDown)
player.y += 5;
if (player.pressingUp)
player.y -= 5;
if (player.pressingpowerRight)
player.x += 50;
if (player.pressingpowerLeft)
player.x -= 50;
}
update = function() {
c.clearRect(0, 0, WIDTH, HEIGHT);
updatePlayerPosition();
drawEntity(player);
}
setInterval(update, 40);
</script>
Try creating a previousButtonKey global variable and always record the last key, then check the previousButtonKey with another key to combine two keys on your condition.
Ex. First key is to be pressed is 'Shift', store it to a variable, then once another key event happens, check the previous and the new key. If it is valid, then do the action that you want.
I've scoured the web for this answer. If it is buried in a StackOverflow answer somewhere I apologize.
I am working on a 2d canvas JavaScript game.
I am handling arrow key input with onkeydown and onkeyup events.
I store this input in an object called Keys.
var Keys = {
up: false,
down: false,
left: false,
right: false
};
This is what my event handlers look like:
window.onkeydown = function(e){
var kc = e.keyCode;
e.preventDefault();
if(kc === 37) Keys.left = true;
else if(kc === 38) Keys.up = true;
else if(kc === 39) Keys.right = true;
else if(kc === 40) Keys.down = true;
move();
};
window.onkeyup = function(e){
var kc = e.keyCode;
e.preventDefault();
if(kc === 37) Keys.left = false;
else if(kc === 38) Keys.up = false;
else if(kc === 39) Keys.right = false;
else if(kc === 40) Keys.down = false;
};
Then each time the keydown event occurs, I call my move() function:
var move = function(){
if(Keys.up){
hero.y -= 10;
}
else if(Keys.down){
hero.y += 10;
}
if(Keys.left){
hero.x -= 10;
}
else if(Keys.right){
hero.x += 10;
}
main();
}
The move() function calls my main() function which just draws the map again.
I'm trying to avoid looping the game, and instead update the map each time the player moves.
So my problem arises when I try to move diagonally. I am able to do it, however once I release the second key pressed, my character stops.
For example:
Right key pressed and then up key pressed, character moves northeast.
Up key released, player stops.
However, if I release the right key, the character continues moving up.
Another glitch is when I hold both left and right, the character will move left,
but I want it to stop moving.
Quickly sketched an example, jsfiddle: http://jsfiddle.net/ofnp4vj4/
HTML: <div id="log"></div>
JS:
var Keys = {
up: false,
down: false,
left: false,
right: false
};
var hero = {
x: 0,
y: 0
};
var log = document.getElementById("log");
window.onkeydown = function(e){
var kc = e.keyCode;
e.preventDefault();
if(kc === 37) Keys.left = true;
if(kc === 38) Keys.up = true;
if(kc === 39) Keys.right = true;
if(kc === 40) Keys.down = true;
};
window.onkeyup = function(e){
var kc = e.keyCode;
e.preventDefault();
if(kc === 37) Keys.left = false;
if(kc === 38) Keys.up = false;
if(kc === 39) Keys.right = false;
if(kc === 40) Keys.down = false;
};
function main() {
/* body */
move();
log.innerHTML = "x: "+hero.x+", y: "+hero.y;
};
function move(){
if(Keys.up){
hero.y -= 10;
}
if(Keys.down){
hero.y += 10;
}
if(Keys.left) {
hero.x -= 10;
}
if(Keys.right){
hero.x += 10;
}
}
setInterval(main, 100);
You mention that you want the player to stop moving when you press the left and right keys simultaneously. It appears you should be able to easily do this by replacing the else if statements in move with if statements, resulting in a move function similar to:
var move = function(){
if(Keys.up){
hero.y -= 10;
}
if(Keys.down){
hero.y += 10;
}
if(Keys.left){
hero.x -= 10;
}
if(Keys.right){
hero.x += 10;
}
main();
}
I am new to javascript games.
I have an idea of game, As an example if I am taking Solidsnake's character.
I want character view changes on pressing navigation keys.
If I press left key it should show left view, right key for right view and so on.
How do i get change in image on pressing keys , how can I do this in javascript?
Idea of game-
Code in brief-
var leftKey,upKey,rightKey,downKey;
var box = $("#plane"),
left = 37,
up = 38,
right = 39,
down = 40;
function key(e) {
console.log(e.keyCode);
var $key = e.keyCode;
$(document).keydown(function(e) {
if (e.keyCode == left)
leftKey = true;
if (e.keyCode == up)
upKey = true;
if (e.keyCode == right)
rightKey = true;
if (e.keyCode == down)
downKey = true;
}).keyup(function(e) {
if (e.keyCode == left)
leftKey = false;
if (e.keyCode == up)
upKey = false;
if (e.keyCode == right)
rightKey = false;
if (e.keyCode == down)
downKey = false;
});
}
$("body").keydown(function(){
key(event);
});
setInterval(function() {
if (upKey) {
box.css("top", "-=10");
}
if (rightKey) {
box.css("left", "+=10");
}
if (downKey) {
box.css("top", "+=10");
}
if (leftKey) {
box.css("left", "-=10");
}
},20);
Right now i have this code with simple navigation moves.
Js fiddle
You can do this with CSS to set it right and avoid multiple image requests. You need to have a sprite with all images of the character in a row and then mask with a div the area you need to show. Then with javascript you can change the position of the image either by using marginLeft or marginRight or left and right (you need to set position relative or absolute for left and right).
When you do e.keyCode == up and the like, you can change the image source then:
if (e.keyCode == up) {
upKey = true;
$("#plane").attr('src', 'up-img-src');
}
Either do this: http://jsfiddle.net/VMM5P/1/
Change the image src on keypress:
if (upKey) {
box.attr("src", "http://cdn3.iconfinder.com/data/icons/blackblue/128/iChat.png");
}
if (rightKey) {
box.attr("src", "http://cdn2.iconfinder.com/data/icons/blackblue/128/guitar.png");
}
if (downKey) {
box.attr("src", "http://cdn3.iconfinder.com/data/icons/blackblue/128/TextEdit.png");
}
if (leftKey) {
box.attr("src", "http://cdn2.iconfinder.com/data/icons/blackblue/128/preview.png");
}
or you can make a sprite and position them accordingly:
Suppose box is the div which has a background sprite image
if (upKey) {
box.css("background-position", "0px 0px"); // pos 1
}
if (rightKey) {
box.css("background-position", "120px 0px"); // pos 2
}
if (downKey) {
box.css("background-position", "240px 0px"); // pos 3
}
if (leftKey) {
box.css("background-position", "360px 0px"); // pos 4
}
You would want to change the attr source for the image.
if (leftKey) {
box.find('img').attr('src', 'ENTER NEW IMAGE URL HERE');
}
I tried to make a moving img, and it works partially. If I press the right, up or down button, it moves right, up or down. But, if I press the left button, it jumps very fast very far to the right, and then back to the left and doesn't stop moving (I believe. I said it was fast).
JSFiddle;
Javascript:
$(document).ready(function() {
var up = down = left = right = false;
var top = 100, left = 500;
$("body").on("keydown", function(e) {
if(e.keyCode == 39) {e.preventDefault(); if (right == false) right = setInterval(moveRight, 80);}
else if(e.keyCode == 37) {e.preventDefault(); if (left == false) left = setInterval(moveLeft, 80);}
else if(e.keyCode == 38) {e.preventDefault(); if (up == false) up = setInterval(moveUp, 80);}
else if(e.keyCode == 40) {e.preventDefault(); if (down == false) down = setInterval(moveDown, 80);}
});
$("body").on("keyup", function(e) {
if(e.keyCode == 39) {clearInterval(right); right = false;}
else if(e.keyCode == 37) {clearInterval(left); left = false;}
else if(e.keyCode == 38) {clearInterval(up); up = false;}
else if(e.keyCode == 40) {clearInterval(down); down = false;}
});
function moveUp() {
top -= 2;
$("#player").css("top", top + "px");
}
function moveDown() {
top += 2;
$("#player").css("top", top + "px");
}
function moveLeft() {
left -= 2;
$("#player").css("left", left + "px");
}
function moveRight() {
left += 2;
$("#player").css("left", left + "px");
}
});
This is probably not the best way to do this, I'm open for better suggestions.
You're defining two "left" variables, and they are getting in the way of each other. Change one of their names (perhaps leftInterval for the interval variable), and things should go better.
The variables are overwritten, try something like :
$("body").on("keydown", function(e) {
e.preventDefault();
var elm = $("#player"),
top = parseInt(elm.css('top')),
left = parseInt(elm.css('left'));
switch(e.which) {
case 37:
elm.css("left", left-2);
break;
case 38:
elm.css("top", top-2);
break;
case 39:
elm.css("left", left+2);
break;
case 40:
elm.css("top", top+2);
break;
}
});
FIDDLE