I am completely new to JavaScript so please be patient with me
I have been following a tutorial to display images from a folder in JavaScript but when I add the script that iterates it causes the computer viewing the page to lock up completely
The following in inside my tags:
var canvas = document.getElementById("canvas");
var graphics_context = canvas.getContext("2d");
var rightPressed = false;
var leftPressed = false;
var currentpage = 0;
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if ((e.key == "Right" || e.key == "ArrowRight") && !rightPressed) {
rightPressed = true;
currentpage++;
}
else if ((e.key == "Left" || e.key == "ArrowLeft") && !leftPressed) {
leftPressed = true;
currentpage--;
}
}
function keyUpHandler(e) {
if (e.key == "Right" || e.key == "ArrowRight") {
rightPressed = false;
}
else if (e.key == "Left" || e.key == "ArrowLeft") {
leftPressed = false;
}
}
function draw() {
var img = new Array();
for(let i = 0; true; i++) {
try {
var image = new Image();
image.src = "img/" + i + ".jpg";
img[i] = image;
}
catch(err) {
break;
}
}
if(currentpage <= 0)
currentpage = 0;
if(currentpage >= img.length)
currentpage = img.length - 1;
ctx.drawImage(img[currentpage], 0, 0, 800, 800);
}
setInterval(draw, 10);
I do realise that reading from a folder in a loop is incredibly inefficient but I really don't see how it would cause my entire PC to lock up (it is a separate PC to the one running the page)
Any help is appreciated!
Related
I have wrote this code in JavaScript :
window.onload = function() {
var keyboard = new Keyboard();
var gameCanvas = document.getElementById("gameCanvas").getContext("2d");
var player = new Player(gameCanvas, keyboard);
player.Init();
setInterval(function() {
gameCanvas.clearRect(0, 0, 1200, 300);
player.Update();
}, 20);
}
class Player {
constructor(canvas, keyboard) {
this._canvas = canvas;
this._keyboard = keyboard;
this._x = 100;
this._y = 75;
this._dx = 1;
this.dy = 1;
}
Init() {
this.Draw();
}
Update() {
if (this._keyboard.GetIsArrowLeftDown())
this._x -= this._dx;
if (this._keyboard.GetIsArrowRightDown())
this._x += this._dx;
if (this._keyboard.GetIsArrowUpDown())
this._y -= this._dy;
if (this._keyboard.GetIsArrowDownDown())
this._y += this._dy;
this.Draw();
}
Draw() {
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.strokeStyle = "black";
this._canvas.stroke();
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.fillStyle = "red";
this._canvas.fill();
}
}
class Keyboard {
constructor() {
this.isArrowLeftDown = false;
this.isArrowRightDown = false;
this.isArrowUpDown = false;
this.isArrowDownDown = false;
window.addEventListener("keyup", keyboard.OnKeyUpEvent);
window.addEventListener("keydown", keyboard.OnKeyDownEvent);
}
OnKeyUpEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = false;
if (key == "ArrowRight")
this.isArrowRightDown = false;
if (key == "ArrowUp")
this.isArrowUpDown = false;
if (key == "ArrowDown")
this.isArrowDownDown = false;
}
OnKeyDownEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = true;
if (key == "ArrowRight")
this.isArrowRightDown = true;
if (key == "ArrowUp")
this.isArrowUpDown = true;
if (key == "ArrowDown")
this.isArrowDownDown = true;
}
GetIsArrowLeftDown() {
return this.isArrowLeftDown;
}
GetIsArrowRightDown() {
return this.isArrowRightDown;
}
GetIsArrowUpDown() {
return this.isArrowUpDown;
}
GetIsArrowDownDown() {
return this.isArrowDownDown;
}
}
I have a Keyboard object which remembers which keys the user pressed.
Player is an object that draw himself.
I expected that when I press left, the shape would move to the left of the screen. But it's not working as expected.
It seems my keyboard object hasn't the good property values when read by the player object.
What am I missing?
Some issues:
In the Player constructor you assign 1 to the dy property, but it is later referenced as _dy, so you should add the underscore here.
In the Keyboard constructor you use keyboard, but that is undefined; you intended this.
In those same lines you pass a reference to the OnKeyUpEvent and OnKeyDownEvent methods. But when they are called, they do not pass the current value of this, so you should bind(this) to make that happen.
Here is the corrected code:
window.onload = function() {
var keyboard = new Keyboard();
var gameCanvas = document.getElementById("gameCanvas").getContext("2d");
var player = new Player(gameCanvas, keyboard);
player.Init();
setInterval(function() {
gameCanvas.clearRect(0, 0, 1200, 300);
player.Update();
}, 20);
}
class Player {
constructor(canvas, keyboard) {
this._canvas = canvas;
this._keyboard = keyboard;
this._x = 100;
this._y = 75;
this._dx = 1;
this._dy = 1; /// add the underscore
}
Init() {
this.Draw();
}
Update() {
if (this._keyboard.GetIsArrowLeftDown())
this._x -= this._dx;
if (this._keyboard.GetIsArrowRightDown())
this._x += this._dx;
if (this._keyboard.GetIsArrowUpDown())
this._y -= this._dy;
if (this._keyboard.GetIsArrowDownDown())
this._y += this._dy;
this.Draw();
}
Draw() {
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.strokeStyle = "black";
this._canvas.stroke();
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.fillStyle = "red";
this._canvas.fill();
}
}
class Keyboard {
constructor() {
this.isArrowLeftDown = false;
this.isArrowRightDown = false;
this.isArrowUpDown = false;
this.isArrowDownDown = false;
window.addEventListener("keyup", this.OnKeyUpEvent.bind(this)); // use this and bind
window.addEventListener("keydown", this.OnKeyDownEvent.bind(this));
}
OnKeyUpEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = false;
if (key == "ArrowRight")
this.isArrowRightDown = false;
if (key == "ArrowUp")
this.isArrowUpDown = false;
if (key == "ArrowDown")
this.isArrowDownDown = false;
}
OnKeyDownEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = true;
if (key == "ArrowRight")
this.isArrowRightDown = true;
if (key == "ArrowUp")
this.isArrowUpDown = true;
if (key == "ArrowDown")
this.isArrowDownDown = true;
}
GetIsArrowLeftDown() {
return this.isArrowLeftDown;
}
GetIsArrowRightDown() {
return this.isArrowRightDown;
}
GetIsArrowUpDown() {
return this.isArrowUpDown;
}
GetIsArrowDownDown() {
return this.isArrowDownDown;
}
}
<canvas id="gameCanvas"></canvas>
NB: You can detect such errors since they are reported in the console.
I am new to JavaScript and this community. I apologize if this has been asked before, but the threads I found for this topic did not really help me with this specific problem.
I would like to achieve the following working:
Image 1 is displayed.
If you press the left arrow key (keydown) the image should change to image 2.
If you stop pressing (keyup), it should change to image 3.
If you press the right arrow key it should change to image 4 and on keyup, change to image 5.
The code is:
<img src="img/image1.png" id="myIMG">
and
var imgs = ["img/image5.png", "img/image3.png", "img/image1.png", "img/image4.png"];
function changeIMG(dir) {
var img = document.getElementById("myIMG");
img.src = imgs[imgs.indexOf(img.src) + (dir || 1)] || imgs[dir ? imgs.length - 1 : 0];
}
var keys = {};
$(document).keydown(function (event) {
keys[event.which] = true;
}).keyup(function (event) {
if(e.keyCode == 37){
delete keys[37];
changeIMG(+1);
}
else if(e.keyCode == 39){
delete keys[39];
changeIMG(+2);
}
});
function IMGLoop() {
if (keys[37]) {
changeIMG(+3);
} else if (keys[39]) {
changeIMG(+4);
}
setTimeout(IMGLoop, 20);
}
IMGLoop();
The issue is described below.
The keyup does not do anything and the keydown only works once and then I can not even switch between left and right anymore.
I need to do this with a loop because I also want to do other things on the loop that are not displayed in this code. I would appreciate any type of help.
Hope this helps you
var imgs = [
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQgz2HMpGysZL6ifYfhqWASDoA0b2MyX-gyMuQszgYRv87yr9qug",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQV3JL_HtVvlLr3Xy-KQV5MNmIF2-kCb9cHB4oXkUKQ1jiLT0H",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRgDmo-5YpwYK9Yc35CK1oq3Y2zHDnXlu3q6m7GnSvLarDTRl0B",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQt2dZklq8eDbsNL1vZ0MTwZsm0KWDIxl6YifmbUqjPiE5lOmIe"
];
var showImageName = 2;
function changeIMG(dir) {
var img = document.getElementById("myIMG");
img.src = imgs[dir];
img.alt = dir;
}
var keyPressed = false;
function f(e) {
if (e.keyCode == 37) {
showImageName--;
if (showImageName == -1) {
showImageName = imgs.length - 1;
}
changeIMG(showImageName);
} else if (e.keyCode == 39) {
showImageName++;
if (showImageName == imgs.length) {
showImageName = 0;
}
changeIMG(showImageName);
}
}
$(document)
.keydown(function(e) {
if (!keyPressed) {
keyPressed = true;
f(e);
}
})
.keyup(function(e) {
if (keyPressed) {
keyPressed = false;
f(e);
}
});
changeIMG(0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img alt='' src="" id="myIMG">
Update after question edited
var imgs = [
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQgz2HMpGysZL6ifYfhqWASDoA0b2MyX-gyMuQszgYRv87yr9qug",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQV3JL_HtVvlLr3Xy-KQV5MNmIF2-kCb9cHB4oXkUKQ1jiLT0H",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRgDmo-5YpwYK9Yc35CK1oq3Y2zHDnXlu3q6m7GnSvLarDTRl0B",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQt2dZklq8eDbsNL1vZ0MTwZsm0KWDIxl6YifmbUqjPiE5lOmIe",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSnDWTv5oLaNgUm_SXQFSzzBJl-21c7wLCC6Hgld-ndQ1k0knly"
];
var showImageName = 2;
function changeIMG(dir) {
var img = document.getElementById("myIMG");
img.src = imgs[dir];
img.alt = dir;
}
var keyPressed = false;
function f(e, str) {
switch (str) {
case "up":
if (e.keyCode == 37) {
changeIMG(2);
} else if (e.keyCode == 39) {
changeIMG(4);
}
break;
case "down":
if (e.keyCode == 37) {
changeIMG(1);
} else if (e.keyCode == 39) {
changeIMG(3);
}
break;
}
}
$(document)
.keydown(function(e) {
if (!keyPressed) {
keyPressed = true;
f(e, "down");
}
})
.keyup(function(e) {
if (keyPressed) {
keyPressed = false;
f(e, "up");
}
});
changeIMG(0);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img alt='' src="" id="myIMG">
I am making a classic snake remake in JavaScript just for weekend fun, and I ran into this problem that if I press buttons quite fast - the snake (caterpillar in my case) is able to change direction to opposite and run into itself.
The way to recreate this situation is as follows:
direction is for example 'left'
press up(or down) and press right quickly after
now the caterpillar goes backwards. And my goal is it should make U-turn
I made the checks for opposite dir, but this doesn't prevent this
update = function() {
if (cat.direction != 'right' && key[37] === true) {
cat.direction = 'left';
}
if (cat.direction != 'left' && key[39] === true) {
cat.direction = 'right';
}
if (cat.direction != 'down' && key[38] === true) {
cat.direction = 'up';
}
if (cat.direction != 'up' && key[40] === true) {
cat.direction = 'down';
}
};
the full code
I was using normal addEventListener for the key listening, but I changed it for another approach (found somewhere), where I do update on keys very often and caterpillar moving is happening only from time to time, as I thought it might be a problem to directly associate drawing, changing direction and moving in the same time interval. I hope I am understandable, sorry if something isn't clear - I would be happy to provide more info if so.
One solution is to not process more than one key per move, but to allow more responsiveness you could implement a key buffer, instead of maintaining the key states as you do know. You would only collect arrow key presses in that buffer, and not push any repetitions of the same key into it.
Here are the relevant changes to the code:
Initialise the key buffer:
var keyBuffer = [];
Push arrow keys into the buffer when pressed:
var keyDown = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
// *** Queue the arrow key presses
if (keyCode >= 37 && keyCode <= 40 &&
keyCode !== keyBuffer[keyBuffer.length-1] && ) {
keyBuffer.push(keyCode);
}
};
Process one key from the buffer at a time:
var update = function() {
// *** Extract next key from buffer, and only treat that one
// -- could be `undefined`, but that is not a problem:
var key = keyBuffer.shift();
if(cat.direction != 'right' && key === 37){
cat.direction = 'left';
} else if(cat.direction != 'left' && key === 39){
cat.direction = 'right';
} else if(cat.direction != 'down' && key === 38){
cat.direction = 'up';
} else if(cat.direction != 'up' && key === 40){
cat.direction = 'down';
}
};
Only process next key when about to move:
function loop() {
board.resetCanvas();
if(counter > 1000){
update(); // ***only process buffered keys when moving
cat.move();
counter = 0;
}
cat.draw();
counter += 5*cat.multiplier;
};
That's it. See fiddle below:
var canvas = document.getElementById("board");
var context = canvas.getContext("2d", {alpha:false});
var pieceSideLength = canvas.width / 40;
var key = [];
var keyBuffer = [];
window.addEventListener('keyup', function(e) {
this.keyUp.call(this, e);
}, false);
window.addEventListener('keydown', function(e) {
this.keyDown.call(this, e);
}, false);
function Piece(x,y){
this.x = x;
this.y = y;
}
board = {
leftBound: 0,
rightBound: canvas.width / pieceSideLength,
topBound: 0,
bottomBound: canvas.height / pieceSideLength,
drawPiece: function(x, y, color){
context.fillStyle = color;
context.fillRect(x*pieceSideLength,y*pieceSideLength,pieceSideLength,pieceSideLength);
context.strokeStyle = 'white';
context.strokeRect(x*pieceSideLength,y*pieceSideLength,pieceSideLength,pieceSideLength);
},
resetCanvas: function(){
context.clearRect(0,0,canvas.width,canvas.height);
}
};
//cat as for caterpillar
cat = {
x: canvas.width/pieceSideLength/2, //initial x
y: canvas.height/pieceSideLength/2, //initial y
pieces: [],
direction: 'up',
color: '#5da03c',
shouldGrow: false,
multiplier: 5,
init: function(){
cat.pieces.push(new Piece(this.x, this.y));
},
move: function(){
if(cat.pieces.length <= 10){
cat.shouldGrow = true;
}
var newX = cat.pieces[cat.pieces.length-1].x;
var newY = cat.pieces[cat.pieces.length-1].y;
if(cat.direction=='up'){
cat.makeNewHeadAt(newX,newY-1);
}
if(cat.direction=='down'){
cat.makeNewHeadAt(newX,newY+1);
}
if(cat.direction=='left'){
cat.makeNewHeadAt(newX-1,newY);
}
if(cat.direction=='right'){
cat.makeNewHeadAt(newX+1,newY);
}
cat.grow();
},
makeNewHeadAt: function(x,y){
cat.pieces.push(new Piece(x,y));
},
grow: function(){
if(cat.shouldGrow == false){
cat.pieces.shift();
} else {
cat.shouldGrow = false;
}
},
draw: function(){
for(i=0;i<cat.pieces.length;i++){
var p = cat.pieces[i];
board.drawPiece(p.x,p.y,cat.color);
}
}
};
cat.init();
update = function() {
// *** Extract next key from buffer, and only treat that one
// -- could be `undefined`, but that is not a problem:
var key = keyBuffer.shift();
if(cat.direction != 'right' && key === 37){
cat.direction = 'left';
} else if(cat.direction != 'left' && key === 39){
cat.direction = 'right';
} else if(cat.direction != 'down' && key === 38){
cat.direction = 'up';
} else if(cat.direction != 'up' && key === 40){
cat.direction = 'down';
}
};
keyUp = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
this.key[keyCode] = false;
};
keyDown = function(e) {
var keyCode = e.which ? e.which : e.keyCode;
// *** Queue the key presses
if (keyCode >= 37 && keyCode <= 40 &&
keyCode !== keyBuffer[keyBuffer.length-1]) {
keyBuffer.push(keyCode);
}
this.key[keyCode] = true;
};
var counter = 0;
function loop() {
board.resetCanvas();
if(counter > 1000){
update(); // ***only process buffered keys when moving
cat.move();
counter = 0;
}
cat.draw();
counter += 5*cat.multiplier;
};
setInterval(loop, 1);
body { margin: 0px }
<div>
<canvas id="board" width="300" height="200" style="display: block; margin: 0 auto; background-color: #553300; border-style: solid; border-color: green;"></canvas>
</div>
Limiting the buffer size
You can limit the buffer size by replacing this:
keyBuffer.push(keyCode);
with:
keyBuffer = keyBuffer.slice(-2).concat(keyCode);
This will limit the size to 3. Adjust the slice argument as desired.
You can keep track of whether the snake has 'moved'. If you receive keyboard input, don't react to another keypress until the snake has moved. This way you're only allowing 1 key for each movement, so you can't change direction and run into yourself.
Modified example: link
update = function() {
if (moved = true) {
if(cat.direction != 'right' && key[37] === true){
and so forth
In a Cocos2d-x V 3.81 project, I am trying to animate a sprite inside an object which extends Sprite, but it does not seem to do anything. Is it even possible to have an animated sprite inside such a node, or does it have to extend Layer to have animation?
var Player = cc.Sprite.extend ({
ctor: function () {
this._super(res.Player_png);
this.UP = false;
this.DOWN = false;
this.LEFT = false;
this.RIGHT = false;
this.ACTION = false;
this.speed = 5;
cc.spriteFrameCache.addSpriteFrame(res.Player_Left_plist);
var leftFrames = [];
for(var i = 0; i < 4; i++)
{
var str = "Left" + i + ".png";
var frame = cc.spriteFrameCache.getSpriteFrame(str);
leftFrames.push(frame);
}
this.leftAnim = new cc.Animation(leftFrames, 0.3);
this.runLeft = new cc.repeatForever(new cc.Animate(this.leftAnim));
this.state = "nothing";
this.nothing = "nothing";
this.scheduleUpdate();
cc.eventManager.addListener (
cc.EventListener.create ({
event: cc.EventListener.KEYBOARD ,
onKeyPressed: function(key, event)
{
if(key == 87) this.UP = true;
else if(key == 65) this.LEFT = true;
else if(key == 83) this.DOWN = true;
else if(key == 68) this.RIGHT = true;
else if (key == 69 || key == 32) this.ACTION = true;
}.bind(this),
onKeyReleased: function(key, event)
{
if(key == 87) this.UP = false;
else if(key == 65) this.LEFT = false;
else if(key == 83) this.DOWN = false;
else if(key == 68) this.RIGHT = false;
else if (key == 69 || key == 32) this.ACTION = false;
}.bind(this)
}),this);
return true;
},
update:function(dt) {
if(this.UP)
{
this.y += this.speed;
this.runAction(this.runLeft);
}
else if(this.DOWN)
{
this.y -= this.speed;
}
if(this.LEFT)
{
this.x -= this.speed;
this.runAction(this.runLeft);
}
else if(this.RIGHT)
{
this.x += this.speed;
}
}
});
I think the problem is this line:
cc.spriteFrameCache.addSpriteFrame(res.Player_Left_plist);
It should read
cc.spriteFrameCache.addSpriteFrames(res.Player_Left_plist);
where SpriteFrames is plural. The method without an 's' on the end is used to load a single cc.SpriteFrame object into the cache, after you've created that SpriteFrame manually. the method WITH an 's' on the end is the one that takes a URL for a plist to load a whole spritesheet at once.
http://www.cocos2d-x.org/reference/html5-js/V3.8/symbols/cc.spriteFrameCache.html
This code works for you outside the sprite class? For example in a regular sprite?
I think this is wrong but I have not tested it:
this.leftAnim = new cc.Animation(leftFrames, 0.3);
this.runLeft = new cc.repeatForever(new cc.Animate(this.leftAnim));
With your code what I'd do:
var leftAnim = new cc.Animation();
for(var i = 0; i < 4; i++)
{
var str = "Left" + i + ".png";
var frame = cc.spriteFrameCache.getSpriteFrame(str);
leftAnim.addSpriteFrame(frame);
}
leftAnim.setDelayPerUnit(0.08);
this.runAction(cc.animate(leftAnim)); //or this.runAction(cc.animate(leftAnim).repeatForever());
Hope it helps
The pluralization was largely the problem.
For those curious, here is the block of functional code:
You are correct. Thank you very much. For those interested, this is the block of functional code:
cc.spriteFrameCache.addSpriteFrames(res.playerRun_plist);
var i,f;
var frames=[];
for (i=1; i <= 4; i++) {
f=cc.spriteFrameCache.getSpriteFrame("playerRun"+i+".png");
frames.push(f);
}
var playerRunAnim = new cc.Animation(frames, 0.1);
this.playerAction = new cc.RepeatForever(new cc.Animate(playerRunAnim));
this.runAction(this.playerAction);
I'm trying to move a box in the canvas, all the functions work fine, but as soon as i press down on any of the 4 keys the box disappears, I can tell it is because i have a ctx.ClearRect after pressing any of the 4 keys, i managed to stop it from dispersing, the problem is now it does not move or disappear and the cosole does not show any errors so I am stuck again.
any help would be really really helpful, thank you.
function Player (row,col) {
this.isUpKey = false;
this.isRightKey = false;
this.isDownKey = false;
this.isLeftKey = false;
this.row = row;
this.col = col;
this.color = "#f00";
}
var players = new Array();
function drawPlayer() {
players[players.length] = new Player(2,2);
for (var p = 0; p < players.length; p++) {
ctxPlayer.fillStyle = players[p].color;
ctxPlayer.fillRect(players[p].row*25, players[p].col*25, 25, 25);
}
}
function doKeyDown(e){
if (e.keyCode == 87) {
ClearPlayer();
Player.isUpKey = true;
Player.col = Player.col - 1;
}
if (e.keyCode == 83) {
ClearPlayer();
Player.isDownKey = true;
Player.col = Player.col + 1;
}
if (e.keyCode == 65) {
ClearPlayer();
Player.isLeftKey = true;
Player.row = Player.row - 1;
}
if (e.keyCode == 68) {
ClearPlayer();
Player.isRightKey = true;
Player.row = Player.row + 1;
}
}
function ClearPlayer() {
ctxPlayer.clearRect(0,0,canvasWidth,canvasHeight);
}
I created a plnkr with an example of what I think you are trying to do:
// Code goes here
function Player(row, col) {
this.isUpKey = false;
this.isRightKey = false;
this.isDownKey = false;
this.isLeftKey = false;
this.row = row;
this.col = col;
this.color = "#f00";
}
var players = [];
var ctxPlayer;
var currentPlayer;
window.onload = function()
{
ctxPlayer = document.getElementById('c').getContext('2d');
currentPlayer = players[players.length] = new Player(2, 2);
setInterval(render, 25);
}
window.onkeypress = doKeyDown;
function render()
{
ClearPlayer();
drawPlayer();
}
function drawPlayer() {
for (var p = 0; p < players.length; p++) {
ctxPlayer.fillStyle = players[p].color;
ctxPlayer.fillRect(players[p].row * 25, players[p].col * 25, 25, 25);
}
}
function doKeyDown(e) {
console.log(e);
if (e.keyCode == 97) {
currentPlayer.isUpKey = true;
--currentPlayer.row;
}
if (e.keyCode == 100) {
currentPlayer.isDownKey = true;
++currentPlayer.row;
}
if (e.keyCode == 119) {
currentPlayer.isLeftKey = true;
--currentPlayer.col;
}
if (e.keyCode == 115) {
currentPlayer.isRightKey = true;
++currentPlayer.col;
}
}
function ClearPlayer() {
ctxPlayer.clearRect(0, 0, 600, 400);
}
http://plnkr.co/edit/XejZKCkshNiihdy8ui1u?p=preview
First I introduced a render function to call clear and draw. This render function will get called every 25 ms after the window has loaded.
Then you created a new Player every draw-call. I changed it so that one player is created onload. The key-events are respective to this player-object.
Last I changed the key-events for my testing purposes, but they should work with yours too.
Keep in mind that the plnkr is just a quick example on how it works. You probably need to adjust it to your needs.