Player movement in javascript with socket.io - javascript

Im currently making a html5 multiplayer game with socket.io.
My problem is that i can only move my character in a straight line, while i also want to be able to move diagonal across my canvas. What i mean by this is if i press the 'a' and 'd' key, my character moves diagonally to the bottom right. With my current code my character only moves to the right or down.
//client, how i capture my keyboard input.
document.onkeydown = function(event){
console.log(`Keycode: ${event.which}`);
if(event.which == 68 || event.which == 39) //d of pijl rechts
sock.emit('keyPress', 'right');
else if(event.which == 83 || event.which == 40) //s of pijl naar beneden
sock.emit('keyPress','down');
else if(event.which == 65 || event.which == 37) //a of pijl naar links
sock.emit('keyPress','left');
else if(event.which == 87 || event.which == 38) // w of pijl naar omhoog
sock.emit('keyPress','up');
}
//server,
sock.on('keyPress', (keypress) => {
var currentUser = this[sock.id];
if (keypress == 'up') {
currentUser.y = currentUser.y - currentUser.speed;
}
else if (keypress == 'down') {
currentUser.y = currentUser.y + currentUser.speed;
}
else if (keypress == 'left') {
currentUser.x = currentUser.x - currentUser.speed;
}
else if (keypress == 'right') {
currentUser.x = currentUser.x + currentUser.speed;
}
});
setInterval(function(){
io.emit('update-players', Users);
},1000/30);
//client, how all players are drawn onto to canvas
sock.on('update-players', updatePlayers);
var updatePlayers= (Users) => {
ctx.clearRect(0,0,10000,10000);
Users.forEach((user) => {
var img = new Image();
img.src = 'Images/player.png';
ctx.drawImage(img,user.x,user.y,user.width,user.height);
ctx.font = "20px Courier New";
ctx.fillText(`${user.name}`,user.x,(user.y - 10))
}
});
sorry for my crappy english.

When we press two keys on the keyboard and hold them down, only the last key pressed gets repeated events in the keydown listener. So, for example, if you press DOWN and RIGHT "at the same time", only one will be repeatedly reported to the listener and the other will be ignored.
A better approach is to have listeners for the keydown and keydown events, like this:
var keyStates = {
up: false,
down: false,
left: false,
right: false
}
function updateKeyStates(code, value) {
if(code == 68 || code == 39) //d of pijl rechts
keyStates.right = value;
else if(code == 83 || code == 40) //s of pijl naar beneden
keyStates.down = value;
else if(code == 65 || code == 37) //a of pijl naar links
keyStates.left = value;
else if(code == 87 || code == 38) // w of pijl naar omhoog
keyStates.up = value;
}
document.addEventListener('keydown', function(event) {
console.log(`Pressed: ${event.which}`);
updateKeyStates(event.which, true);
});
document.addEventListener('keyup', function(event) {
console.log(`Released: ${event.which}`);
updateKeyStates(event.which, false);
});
So we basically have a boolean variable for each direction. You should send that information (keyStates) to the server and it should do the math based on which keys are down.

Related

p5.js: how can I limit keyPressed to sending just 1 output?

I'm trying to prevent players from pressing both left and right keys at the same time, since doing so will change both "isLeft" and "isRight" to true. I've tried the code below but it makes the controls really stiff, for example, if you were to let go of "D" too late before pushing "A", it will register "D" being released but would not register "A" being pressed (since A is pressed when "isRight" is true. Sorry if this analogy is too confusing...
I'm looking for a way to take input from pressing "A", and if "D" is still pressed after "A" is released, immediately take input from "D".
Thanks in advance!
function keyPressed()
{
if ((key == 'A' || keyCode == 37) && !isRight)
{
isLeft = true;
}
else if ((key == 'D' || keyCode == 39) && !isLeft)
{
isRight = true;
}
}
A solution to interpret left vs right when both keys are pressed is to listen for keyPressed and keyReleased. On keyReleased we can also check and see if the alternate key is already down. This approach allows the code to immeditally switch to the other key when both are down and one is released
var isLeft = false;
var isRight = false;
function setup(){
frameRate(10);
}
function keyPressed(){
if ((key == 'A' || keyCode == 37) && !isRight){
isLeft = true;
} else if ((key == 'D' || keyCode == 39) && !isLeft) {
isRight = true;
}
}
function keyReleased(){
if ((key == 'A' || keyCode == 37)){
isLeft = false;
if ((keyIsDown(16) && keyIsDown(68)) || keyIsDown(39)){
isRight = true;
}
}
else if ((key == 'D' || keyCode == 39)){
isRight = false;
if ((keyIsDown(16) && keyIsDown(65))|| keyIsDown(37)){
isLeft = true;
}
}
}
function draw(){
console.log( " isLeft: "+isLeft + " isRight: " + isRight);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>
The keyIsDown detects if a key is being pressed. I'm not sure if it works for all characters, but it works for the arrow keys. If you add !keyIsDown(RIGHT_ARROW), then it sees if the Right arrow is down. If it's down, then the if isn't true, if it's false the if is true it's being run.
Tell me if this doesn't work.
function keyPressed()
{
if ((key == 'A' || keyCode == 37) && !isRight&&!keyIsDown(RIGHT_ARROW))
{
isLeft = true;
}
else if ((key == 'D' || keyCode == 39) && !isLeft!keyIsDown(LEFT_ARROW))
{
isRight = true;
}
}

How to make a rect svg element not escape the viewBox of the svg

I have an SVG
<svg id='mainSvg' viewBox='0 0 1920 1080'>
<rect id='rectangle' x='800' y='800'/>
</svg>
and I am moving the rectangle inside the SVG with javascript with left and right arrow keys and A and D keys.
that is working perfectly but I have a problem that the rectangle can go outside of the view-box of the SVG and I want the rectangle to stop when it touches the left or right corner. this is my code.
function keyDown(event) {
if (event.key === 'ArrowLeft' || event.key === 'a') {
leftKey = true;
aKey = true;
} else if (event.key === 'ArrowRight' || event.key === 'd') {
rightKey = true;
dKey = true;
}
}
function keyUp(event) {
if (event.key === 'ArrowLeft' || event.key === 'a') {
leftKey = false;
aKey = false;
} else if (event.key === 'ArrowRight' || event.key === 'd') {
rightKey = false;
dKey = false;
}
}
function move() {
let xPosition = parseInt(rectangle.getAttribute('x'));
const movmentSpeed = 10;
//if right arrow key,d is pressed
if (rightKey) {
rectangle.setAttribute('x', xPosition + movmentSpeed);
//if right arrow key,a is pressed
} else if (leftKey) {
rectangle.setAttribute('x', xPosition - movmentSpeed)
if(xPosition === 0){
leftKey = false;
}
}
setTimeout(move, 10);
}
on the last function move() I tried saying if(Xposition ===0){leftKey = false} that works briefly but if the user keeps pressing the left arrow then the rectangle will start moving again and go out of the viewBox.
Also, the arrow keys have a value of false by default
Any ideas on how to fix this?

Web page change when left or right arrow in keyboard pushed

i want to ask how can i change the web page when the arrow key pushed by user , like a web of manga/book if we want to next page we just push the arrow key
sorry for my english , thanks before
You can use jQuery for that:
$(document).keydown(function(e) {
if (e.which == 37) {
alert("left");
e.preventDefault();
return false;
}
if (e.which == 39) {
alert("right");
e.preventDefault();
return false;
}
});
If you wish to use the jQuery framework, then look at Binding arrow keys in JS/jQuery
In plain javascript, I'll go with :
document.onkeydown = function (e) {
e = e || window.event;
var charCode = (e.charCode) ? e.charCode : e.keyCode;
if (charCode == 37) {
alert('left');
}
else if (charCode == 39) {
alert('right');
}
};
Here is a non jQuery option:
document.onkeydown = arrowChecker;
function arrowChecker(e) {
e = e || window.event;
if (e.keyCode == '37') { //left
document.location.href = "http://stackoverflow.com/";
}
else if (e.keyCode == '39') { //right
document.location.href = "http://google.com/";
}
}

Canvas auto running on off window click?

Canvas auto runs when you click on another window and come back.
I have added key listeners and they make the ship move when you click w a s d or up, left, right, down.
It all works fine until you click two buttons like up and right and then click on another tab or window and come back. Then it will just keep moving not listening to your input.
What I think the problem is, is that when you click off the page the canvas never gets to check if the key was left up.But how do I make all the keys act like they were unpressed when you click off the screen?
Also the enemy disappera when you move off screen
This is what happens when buttons are pressed:
Player.prototype.checkKeys = function() //these functions are in the PLayer class
{
if(this.isUpKey == true)//if true
{
if(Player1.drawY >= 0)
{
this.drawY -= this.Speed;
}
}
if(this.isRightKey == true)
{
if(Player1.drawX <= (canvasWidthShips - this.playerWidth))
{
this.drawX += this.Speed;
}
}
if(this.isDownKey == true)
{
if(Player1.drawY <= (canvasHeightShips - this.playerHeight))
{
this.drawY += this.Speed;
}
}
if(this.isLeftKey == true)
{
if(Player1.drawX >= 0)
{
this.drawX -= this.Speed;
}
}
};
And these are my simple functions to check when a key is pressed down, I dont think the error is here but not sure?
function checkKeyDown(e)
{
if (Paused == false)
{
var KeyID = e.KeyCode || e.which;
if (KeyID === 38 || KeyID === 87) //up and w keyboard buttons
{
Player1.isUpKey = true;
e.preventDefault(); //webpage dont scroll when playing
}
if (KeyID === 39 || KeyID === 68) //right and d keyboard buttons
{
Player1.isRightKey = true;
e.preventDefault(); //webpage dont scroll when playing
}
if (KeyID === 40 || KeyID === 83) //down and s keyboard buttons
{
Player1.isDownKey = true;
e.preventDefault(); //webpage dont scroll when playing
}
if (KeyID === 37 || KeyID === 65) //left and a keyboard buttons
{
Player1.isLeftKey = true;
e.preventDefault(); //webpage dont scroll when playing
}
}
else if (Paused == true)
{
Player1.isUpKey = false;
Player1.isDownKey = false;
Player1.isRightKey = false;
Player1.isLeftKey = false;
}
}
function checkKeyUp(e)
{
if (Paused == false)
{
var KeyID = e.KeyCode || e.which;
if (KeyID === 38 || KeyID === 87) //up and w keyboard buttons
{
Player1.isUpKey = false;
e.preventDefault(); //webpage dont scroll when playing
}
if (KeyID === 39 || KeyID === 68) //right and d keyboard buttons
{
Player1.isRightKey = false;
e.preventDefault(); //webpage dont scroll when playing
}
if (KeyID === 40 || KeyID === 83) //down and s keyboard buttons
{
Player1.isDownKey = false;
e.preventDefault(); //webpage dont scroll when playing
}
if (KeyID === 37 || KeyID === 65) //left and a keyboard buttons
{
Player1.isLeftKey = false;
e.preventDefault(); //webpage dont scroll when playing
}
}
else if (Paused == true)
{
Player1.isUpKey = false;
Player1.isDownKey = false;
Player1.isRightKey = false;
Player1.isLeftKey = false;
}
}
Would it be ok to just pause the game? You can listen for onblur on the browser window which gets triggered when it loses focus and then just pause the game in the event handler.
window.onblur = function() {
// Add logic to pause the game here...
Paused = true;
};

Working with multiple key press events (windows key)

While working with the multiple keypress events i found this code which worke fine
$(document).bind('keypress', function(event) {
if( event.which === 65 && event.shiftKey ) {
alert('you pressed SHIFT+A');
}
});
But to make it to work wth combinig with windows key... like
event.which === 65 && event.windowsKey
it failed...
Is there any option to make it work with windows key?
if it is a mac machine there is no key as windows..so what could be the alternate option for windows key in mac
Use keyup event.
On a Mac left Command is which = 91, right Command is which = 93. I can't tell what are those on Windows, but you can test it yourself. As #ian commented they should be 91 and 92 respectively.
To test
$(document).on('keyup', function(e) {
var modKey = "";
if (e.shiftKey) modKey += "shiftKey,";
if (e.ctrlKey) modKey += "ctrlKey,";
if (e.altKey) modKey += "altKey,";
if (e.metaKey) modKey += "metaKey,";
console.log ("which: " + e.which + " modkey: " + modKey );
});
UPDATE: Try use keydown event and event.metaKey
$(document).on('keydown', function(e) {
if(e.which === 65 && event.metaKey ) {
console.log ("You pressed Windows + A");
}
});
Remember the key you pressed before. Like if you press shift. get a boolean or something to shiftPressed = true on a onKeyRelease make it false again. That way you can check if shiftPressed == true && aPressed == true before doing something
I made something a while ago for a little WASD game. Perhaps it makes more sense if you see the code:
var up = false;
var down = false;
var left = false;
var right = false;
function keyUp(e) {
keyCode = (e.keyCode ? e.keyCode : e.which);
if (keyCode == 37 || keyCode == 65) {
left = false;
}
if (keyCode == 38 || keyCode == 87) {
up = false;
}
if (keyCode == 39 || keyCode == 68) {
right = false;
}
if (keyCode == 40 || keyCode == 83) {
down = false;
}
}
function forceStopMoving() {
left = false;
up = false;
right = false;
down = false;
}
function keyDown(e) {
keyCode = (e.keyCode ? e.keyCode : e.which);
if (keyCode == 37 || keyCode == 65) {
left = true;
}
if (keyCode == 38 || keyCode == 87) {
up = true;
}
if (keyCode == 39 || keyCode == 68) {
right = true;
}
if (keyCode == 40 || keyCode == 83) {
down = true;
}
}

Categories