Canvas diagonal movement [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to put together a simple "game" in HTML5. However I can't get diagonal movement working.
The "diagonal movement" only works when the two buttons are pressed at exactly the same time. Even then it moves once. Here's the code:
// Getting canvas, and canvas context
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
//Keymap, later passed as method parameter
var map = [false,false,false,false];
// Top, Right, Bottom, Left
// Function for resetting keymap
var resetMap = function() {
for(i=0;i<map.length;i++) {
map[i] = false;
};
};
//Function for clearing the screen before drawing
var clrScrn = function() {
ctx.clearRect(0,0,500,500);
};
// The player character
var character = function() {
this.x = 50;
this.y = 50;
this.h = 50;
this.w = 50;
};
// Draw method of the character class
character.prototype.draw = function() {
ctx.fillRect(this.x,this.y,this.h,this.w);
};
// The move method of the character class
character.prototype.move = function(map) {
if(map[0] === true) {
if(map[1] == true) {
this.x+=5;
this.y-=5;
console.log("Pressed at the same time");
}
else {
this.y-=5;
}
}
else if(map[1] === true) {
this.x+=5;
}
else if(map[2] === true) {
this.y+=5;
}
else if(map[3] === true) {
this.x-=5;
}
};
//Making a new character
var player = new character();
player.draw();
// Drawing everything on screen
var render = function() {
clrScrn();
player.move(map);
player.draw();
resetMap();
requestAnimFrame(render);
};
//Calling the render function
render();
//Binding event listener to window,checking key down, likely the source of the problem
window.addEventListener("keydown",function(e){
if(e.keyCode == 38 && e.keyCode == 39) {
map[0] = true;
map[1] = true;
}
else if(e.keyCode == 38) {
map[0] = true;
}
if(e.keyCode == 39) {
map[1] = true;
}
if(e.keyCode == 40) {
map[2] = true;
}
if(e.keyCode == 37) {
map[3] = true;
}
console.log(e.keyCode);
},false);
//Binding event listener to key up
window.addEventListener("keyup",function(e){
resetMap();
},false);

In your render function:
player.move(map); // you move the player
player.draw(); // you draw the player
resetMap(); // you forget all pressed keys
The resetMap() is the reason you need to press the keys again in order to move just one more step.
Note that horizontal and vertical motions may accidentally work due to keyboard repeat when a key is pressed for a long time. But you shouldn't depend on key repeats for a game. You should detect key down and key up individually for individual keys in order to figure out if a key is pressed or not.

try looking at:
JavaScript multiple keys pressed at once
and then re-work your if/else logic a little bit.

Related

Drawing lines with (mouse + other key)

I am a newbie in javascript and canvas. I am using the following code to draw a line while the mouse is dragged. I am trying to add another drawing option with the original while I dragged the mouse with some other key (say mouse + p) but I didn't get it, how to add. So basically there will be two options for drawing 1) mouse drag with one color "green" 2) key "P" + mouse drag with another color "red". I searched a lot on different site but everywhere the option is "mouse:down", "mouse:move", "mouse:up".
function makeBackgroundDrawingFabricCanvas(myCanvasObj, appendToCol) {
let canvas_id = myCanvasObj.id
let canvas_html = $("<canvas>")
$(canvas_html).attr("id", canvas_id)
$(canvas_html).attr("height", canvas_height)
$(canvas_html).attr("width", canvas_width)
$(appendToCol).append(canvas_html)
var canvas = new fabric.Canvas(canvas_id);
canvas.isDrawingMode = true
canvas.freeDrawingBrush.color = "green";
canvas.freeDrawingBrush.width = 10;
let add_back_detail_button = $("<button class='btn btn-primary'>Add Back Detail</button>")
$(appendToCol).append(add_back_detail_button)
$(add_back_detail_button).click(function(){
somefunction(canvas_3_add, obj, canvas4_id, obj.image.original_image)
})
}
it will be a great help if you just point me where to add that option in my code.
Add the following code
document.addEventListener("keydown", event => {
if (event.key === "p") {
canvas.freeDrawingBrush.color = "red";
}
});
document.addEventListener("keyup", event => {
if (event.key === "p") {
canvas.freeDrawingBrush.color = "green";
}
});

Keyboard input pause [duplicate]

This question already has answers here:
move element with keypress (multiple)
(3 answers)
Closed 3 years ago.
I made a pretty basic demo, you press an arrow key and the square moves in that direction. One problem: when I first press the key, the square moves a little, pauses, then continues moving. How do I get rid of or work around the pause?
Code:
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d');
var p1 = document.getElementById("p1");
var keys = [];
var x = 25
var y = 25
document.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
update();
});
document.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
update();
});
function update() {
ctx.clearRect(0, 0, 400, 400)
if(keys[40] == true) {
y += 5
}
if(keys[38] == true) {
y -= 5
}
if(keys[39] == true) {
x += 5
}
if(keys[37] == true) {
x -= 5
}
ctx.fillRect(x, y, 100, 100)
console.log(keys);
p1.innerText = "";
for (i = 0; i < keys.length; i++) {
if (keys[i]) {
p1.innerText += i + " | ";
}
}
}
<canvas id='canvas' width='400' height='400'></canvas>
<p id='p1'>testing</p>
This happens because the keydown event is continuously fired at different intervals in different browsers.
Instead of relying on the browser to send keydown from time to time, it's better to have your own update loop running at 60fps, using requestAnimationFrame and each frame moving the box based on the keys pressed.
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d');
var p1 = document.getElementById("p1");
var keys = [];
var x = 25
var y = 25
document.addEventListener("keydown", function(e) {
e.preventDefault(); // make sure this doesn't scroll the window
keys[e.keyCode] = true;
});
document.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
function update() {
// Tell the browser to run again update when it is "free",
// preferably at 60fps (actually your monitor's refresh rate)
requestAnimationFrame(update);
ctx.clearRect(0, 0, 400, 400)
if(keys[40] == true) {
y += 5
}
if(keys[38] == true) {
y -= 5
}
if(keys[39] == true) {
x += 5
}
if(keys[37] == true) {
x -= 5
}
ctx.fillRect(x, y, 100, 100)
p1.innerText = "";
for (i = 0; i < keys.length; i++) {
if (keys[i]) {
p1.innerText += i + " | ";
}
}
}
update(); // Start running the loop at 60fps
<canvas id='canvas' width='400' height='400'></canvas>
<p id='p1'>testing</p>
Note that the distance the box moves in a given amount of time depends on your framerate, so if the browser can't keep up at 60fps and only runs at 30fps, update will be only called half of the times, so the box will only move half of the distance it would otherwise move at 60fps. To learn more about animations and game update loops I recommend to read this fix your timestep article.

Stopping more than one instance of a function running at a time

I am fairly new to JavaScript and have searched everywhere for an answer to my question and cant seem to find anything related at all. This tells me that I'm missing something with my understanding of how my program works.
I have written a small game where the player navigates through a randomly generated maze using a gameloop that checks keydown events every x milliseconds. The game has a difficulty dropdown menu and then the game is started my clicking a button that calls a function to create a canvas where the game is drawn.
My problem is that when the button is clicked again to create a new maze without reloading the page, the gameloop for the original maze is still running and so key events are registered twice. This is causing some unexpected behavior. It's as though every time the button is clicked, a new instance of the function is running. Is there some way that each time the button is clicked I can set it to stop the previous game function?
var canvas;
var div;
var mazeGenButton;
$(document).ready(function () {
canvas = null;
div = document.getElementById('canvascontainer');;
mazeGenButton = document.getElementById("mazeGenButton");
mazeGenButton.onclick = createInstance;
});
function createInstance() {
if (canvas != null) {
div.removeChild(document.getElementById("myCanvas"));
}
canvas = document.createElement('canvas');
canvas.id = "myCanvas";
canvas.width = 1000;
canvas.height = 1000;
div.appendChild(canvas);
drawMaze();
};
var drawMaze = function () {
//code here to create the game(not posted)
//here is the Key listener - not sure if it's related
var keyState = {};
window.addEventListener('keydown', function (e) {
keyState[e.keyCode || e.which] = true;
}, true);
window.addEventListener('keyup', function (e) {
keyState[e.keyCode || e.which] = false;
}, true);
function gameLoop() {
//left
if (keyState[37] || keyState[65]) {
if (isLegalMove(playerXPos - 1, playerYPos)) {
grid[playerXPos][playerYPos].removePlayerCell();
playerXPos -= 1;
grid[playerXPos][playerYPos].setPlayerCell();
}
}
//right
if (keyState[39] || keyState[68]) {
if (isLegalMove(playerXPos + 1, playerYPos)) {
grid[playerXPos][playerYPos].removePlayerCell();
playerXPos += 1;
grid[playerXPos][playerYPos].setPlayerCell();
}
}
//up
if (keyState[38] || keyState[87]) {
if (isLegalMove(playerXPos, playerYPos - 1)) {
grid[playerXPos][playerYPos].removePlayerCell();
playerYPos -= 1;
grid[playerXPos][playerYPos].setPlayerCell();
}
}
//down
if (keyState[40] || keyState[83]) {
if (isLegalMove(playerXPos, playerYPos + 1)) {
grid[playerXPos][playerYPos].removePlayerCell();
playerYPos += 1;
grid[playerXPos][playerYPos].setPlayerCell();
}
}
drawSurroundingCells();
setTimeout(gameLoop, 50);
}
}

How to make a Camera for canvas, as mine is not working JS

I am trying to write a video game engine, however my camera doesn't update the movement of objects properly. I am trying to make it so that I update the position of something when the camera moves, and so the world would move around the camera, because you can't really make a camera that moves and update the coordinates that are drawn on the canvas, which would make this a lot easier. What happens is that the object will stutter across the screen instead of fluently move, which makes whatever game I make unplayable. here is my JSFiddle, lines of interest are 634, where an object moves, and 205 my camera class. I just can't for the life of me figure out how to do this
P.S I have seen this JSFiddle and the Syntax gives me a headache, his if's don't use brackets and his classes are not conventional to me, so I cannot read it.
Some of my camera code
function cameras() {
var cameraList = new Array();
function camera(name, localPosX, localPosY, trackedEntity, edgeScrollingRadius) {
var cameraID;
var cameraName = name;
var lPosX = localPosX;
var lPosY = localPosY;
var tEnt = trackedEntity || null;
var scrollHowFar = edgeScrollingRadius || 0;
function moveCamera() {
var movement = gameControls.getMovement();
if (movement == "Left") {
globalMove("Left");
}
if (movement == "Right") {
globalMove("Right");
}
if (movement == "Up") {
globalMove("Up");
}
if (movement == "Down") {
globalMove("Down");
}
}
this.cameraUpdate = function() {
moveCamera();
}
}
function createNewCamera(name, posX, posY, trackedEntity, edgeScrollingRadius) {
console.log("created camera");
var cam = new camera(name, posX, posY, trackedEntity, edgeScrollingRadius);
if (cameraList.length == 0) {
cam.cameraID = 0;
} else {
cam.cameraID = cameraList.length + 1;
}
cameraList.push(cam);
console.log(cameraList);
}
function removeCamera(id) {
for (var i = 0; i <= cameraList.length; i++) {
if (cameraList[i].cameraID == id) {
delete cameraList[i];
cameraList.splice(i);
}
}
}

How to make a character move smoothly in Javascript

I'm making a game, and I'd like to know how to make a character move more smoothly. The character can already move, but it moves really choppy; when you click the arrow key, it instantly appears 10 pixels ahead. I'd like it to move smoothly so it doesn't just "appear" 10 pixels ahead of itself.
Here is the Code:
document.onkeydown = checkKey;
var canvas;
var ctx;
var up;
var down;
var left;
var right;
var bobX = 200;
var bobY = 200;
var bobWidth = 30;
var bobHeight = 30;
window.onload = function() {
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
var fps = 200; // frames per second
setInterval(function() {
updateAll();
drawAll();
}, 1000/fps)
};
var drawAll = function() {
// draw background
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// draw bob
ctx.fillStyle = "red";
ctx.fillRect(bobX, bobY, bobWidth, bobHeight);
};
var updateAll = function() {
if (up == true) {
up = false;
}
if (down == true) {
bobY += 1;
down = false;
}
if (left == true) {
bobX -= 1;
left = false;
}
if (right == true) {
bobX += 1;
right = false;
}
};
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
up = true;
}
else if (e.keyCode == '40') {
down = true;
}
else if (e.keyCode == '37') {
left = true;
}
else if (e.keyCode == '39') {
right = true;
}
}
I tried doing moving it by one pixel every keypress, but it moves very slowly when I do that.
Your screen has maximum refreshrate, usually 60 fps. Some screens can get up to 120fps, but that's a rather rare case.
So what is happening here:
var fps = 200; // frames per second
setInterval(function() {
updateAll();
drawAll();
}, 1000/fps)
};
The canvas gets redrawn and the position gets updated at a rate which your screen can't catch up with. You simply can't see that your character only moves 1 pixel instead of 10 pixel.
Solution would be to use requestAnimationFrame instead. Which invokes when the screen refreshes:
function animate() {
requestAnimationFrame(animate);
updateAll();
drawAll();
};
animate();

Categories