Reputation: 3
I apologise in advance for the huge eyesore that is my inefficient coding as I'm a newbie.
I'm attempting to make a really basic game using Javascript on a HTML5 canvas and I can't seem to find a straightforward method to "check" for multiple user inputs.
I've successfully used addEventListener for the singleplayer game. However, when trying to make it multiplayer, everything falls apart. I'm not sure if using 'keydown' addEventListener twice works.
Basically, the game checks for the first player's answer using the WASD keys as well as the second player's answer using the arrow keys.
I currently have the following snippet of code and the code is duplicated exactly for p2Game with the function
ga.addEventListener('keydown', check2, false)
:
function p1Game() {
ga.addEventListener('keydown', check1, false);
blankp1screen();
p1Time = 0;
switch(random[p1Level]) {
case 1: // if the answer is UP, we will display DOWN
p1drawTriangleDown();
p1correctkeyID = 87; // answer for UP (W) key
break;
case 2: // if the answer is DOWN, we will display UP
p1drawTriangleUp();
p1correctkeyID = 83; // answer for DOWN (S) key
break;
case 3: // if the answer is LEFT, we will display RIGHT
p1drawTriangleRight();
p1correctkeyID = 65; // answer for the LEFT (A) key
break;
case 4: // if the answer is RIGHT, we will display LEFT
p1drawTriangleLeft();
p1correctkeyID = 68; // answer for the RIGHT (D) key
break;
}
function check1(e) {
p1tt += p1Time;
if (e.keyCode == 87 || e.keyCode == 83 || e.keyCode == 65 || e.keyCode == 68) { // Checks if user enters the keys we want
p1Answer = e.keyCode; // Stores the key to check
if (p1correctkeyID == p1Answer) { // If the answer is the correct answer...
if (p1Level < maxlevel) { // ...if we're not on level 10, we'll continue!
blankp1screen();
p1correctkeyID = null;
p1Answer == null;
p1Levelup();
if ((p1Level - p2Level) == checkforafk) {
p2Slow();
} else {
p1Game();
}
} else if (p1Level == maxlevel) { // if we're on the max level, we'll let the player win!
p1Win();
}
} else if (p1correctkeyID !== p1Answer) {
p1Lose(); }
}
}
ga.removeEventListener('keypress', check1, false);
}
For p2Game:
function p2Game() {
ga.addEventListener('keydown', check2, false);
p2Time = 0;
blankp2screen();
switch(random[p2Level]) {
case 1: // if the answer is UP, we will display DOWN
p2drawTriangleDown();
p2correctkeyID = 38; // answer for UP (W) key
break;
case 2: // if the answer is DOWN, we will display UP
p2drawTriangleUp();
p2correctkeyID = 40; // answer for DOWN (S) key
break;
case 3: // if the answer is LEFT, we will display RIGHT
p2drawTriangleRight();
p2correctkeyID = 37; // answer for the LEFT (A) key
break;
case 4: // if the answer is RIGHT, we will display LEFT
p2drawTriangleLeft();
p2correctkeyID = 39; // answer for the RIGHT (D) key
break;
}
function check2(e) {
p1tt += p2Time;
if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 37 || e.keyCode == 39) { // Checks if user enters the keys we want
p2Answer = e.keyCode; // Stores the key to check
if (p2correctkeyID == p1Answer) { // If the answer is the correct answer...
if (p2Level < maxlevel) { // ...if we're not on level 10, we'll continue!
blankp2screen();
p2correctkeyID = null;
p2Answer == null;
p2Levelup();
if ((p2Level - p1Level) == checkforafk) {
p2Slow();
} else {
p2Game();
}
} else if (p2Level == maxlevel) { // if we're on level 10, we'll let the player win!
p2Win(); // Max Level! Congratulations!
}
} else if (p2correctkeyID !== p2Answer) {
p2Lose();
}
}
}
ga.removeEventListener('keypress', check2, false);
}
Upvotes: 0
Views: 537
Reputation: 2531
Well is hard to tell without a running example to debug. But first off, if you run your code twice you will have two listeners for each player. If you run it three times you will have three, and so on. That's because you are adding an event listener for the keydown
event but then you are removing the keypress
, which basically means that you never remove the keydown
handler.
My advice would be that you should not handle the two inputs in separate places, it may seem easy at first but it creates 'synchronization' problems in your code, as you have to deal with the state of player 1 in the handling code for player 2. So, have just one event handling code and do whatever you need to do for every case. I think you will end up having code that is more easy to follow if you use good abstractions (I know you said you are starting with programming, so that's why I am suggesting that you should follow an approach that should be more easy to reason about now).
Upvotes: 1