I am trying to make collision detection work in a JavaScript program I am working in currently, and I can't figure out why it is triggering in such strange coordinates. X 50 Y 199
If any of you good help that would be much appreciated. Here is my code.
var game = {};
game.fps = 50;
game.playerX = 50;
game.playerY = 50;
game.draw = function () {
c = document.getElementById('canvas');
ctx = c.getContext("2d");
clearCanvas();
//PLAYER
ctx.fillStyle = "blue";
ctx.fillRect(game.playerX, game.playerY, 50, 50);
//ENEMY
ctx.fillStyle = "green";
ctx.fillRect(200, 200, 50, 50);
//Coords
ctx.font = "20px Arial";
ctx.fillStyle = "red";
ctx.fillText(game.playerX, 400, 480);
ctx.fillText(game.playerY, 450, 480);
};
game.update = function () {
document.onkeydown = function () {
switch (window.event.keyCode) {
case 87:
//up
--game.playerY;
break;
case 83:
//down
++game.playerY;
break;
case 65:
//left
--game.playerX;
break;
case 68:
//right
++game.playerX;
break;
}
};
//COLLISION DETECTION
if (game.playerX <= 200 && game.playerX <= 250 && game.playerY >= 200 && game.playerY <= 250) {
alert("it worked!");
game.playerX = 400;
}
//END OF COLLISION DETECTION
};
game.run = function () {
game.update();
game.draw();
};
game.start = function () {
game._intervalId = setInterval(game.run, 1000 / game.fps);
};
game.stop = function () {
clearInterval(game._intervalId);
};
Based on your if statement in the Y axis I'd say you want if(game.playerX >= 200 rather than if(game.playerX <= 200. Right now you're checking if playerX is both less than 200 and less than 250, which 50 satisfies.
You are using the wrong keycodes: JavaScript Keycodes. Additionally, you are only running the collision check one time, when you manually call game.update(). You need to run the collision check within the keydown event:
Here is a Fiddle
document.onkeydown = function (e) {
switch (e.keyCode) {
case 38:
//up
console.log('up');
--game.playerY;
break;
case 40:
//down
++game.playerY;
break;
case 37:
//left
--game.playerX;
break;
case 39:
//right
++game.playerX;
break;
}
console.log(game.playerX + ', ' + game.playerY);
//COLLISION DETECTION
if (game.playerX >= 200 && game.playerX <= 250 && game.playerY >= 200 && game.playerY <= 250) {
alert("it worked!");
game.playerX = 400;
}
};
Related
This question already has an answer here:
setInterval time increases on every click
(1 answer)
Closed 1 year ago.
Every single time I move with the right or left arrows keys or A or D, the player speeds up. I don't want this to happen. I want the player to move at the same speed whenever you press the move key. I have no idea why this is happening. Here is my code:
class Player {
constructor(x, y, color, width, height, health, strength, type, speed) {
this.x = x;
this.y = y;
this.color = color;
this.width = width;
this.height = height;
this.health = health;
this.strength = strength;
this.type = type;
this.speed = speed;
}
draw() {
c.beginPath();
c.rect(this.x, this.y, this.width, this.height);
c.fillStyle = this.color;
c.fill();
c.stroke();
}
moveLeft(){
this.x -= this.speed;
}
moveRight(){
this.x += this.speed;
}
moveUp(){
this.y += this.speed;
}
}
var x = canvas.width / 2;
var y = canvas.height / 2;
var left = false;
var up = false;
var right = false;
var left2 = false;
var up2 = false;
var right2 = false;
var pressing;
var player = new Player(x, y, 'red', 30, 30, 100, 30, 'basic', 2);
player.draw();
document.addEventListener('keydown', function(e) {
switch (e.keyCode) {
case 37:
left = true;
setInterval(function pressing(){
if(left2===false && left === true){
player.moveLeft();
}
},10)
break;
case 65:
left2 = true;
setInterval(function pressing(){
if(left===false && left2 === true){
player.moveLeft();
}
},10)
break;
case 39:
right = true;
setInterval(function pressing(){
if(right2===false && right === true){
player.moveRight();
}
},10)
break;
case 68:
right2 = true;
setInterval(function pressing(){
if(right===false && right2 === true){
player.moveRight();
}
},10)
break;
}
});
document.addEventListener("keyup", event => {
clearInterval(pressing);
if (event.keyCode === 37) {
left = false;
}
if (event.keyCode === 65) {
left2 = false;
}
if (event.keyCode === 39) {
right = false;
}
if (event.keyCode === 68) {
right2 = false;
}
});
I followed many tutorials but couldn't find a different easy way to move my player. Does anyone have another strategy for moving or know why this isn't working?
On every keypress you are currently creating a new interval that is never stopped. So what you are actually doing is to create duplicate intervals each time the key is pressed. As a first, rough fix you could try to store the return value of setInterval in a variable outside of the scope of the key event handler and check whether you have earlier intervals running. If so, clear them up before going ahead.
As clearInterval does not throw any error when fed un-intervalish values, you don't even have to check before clearing:
let myInterval = null
document.addEventListener('keydown', (e) => {
// Clean up any earlier mess.
clearInterval(myInterval)
// Create new mess.
myInterval = setInterval(() => { /* do something */ }, 10)
})
I think that you already have the answer...
You are creating multiple intervals that are never stopped.
But I would not use the interval in the key events, instead use just one outside to draw at certain frequency, then use a more mathematical approach to move and set the speed of the player on those events, we don't need different functions to move left or right, all we need is the correct speed value, positive increases (moves right), negative decreases (moves left) ... here is the code:
class Player {
constructor(pos, speed) {
this.pos = pos
this.speed = speed
}
draw() {
this.pos.x += this.speed.x
this.pos.y += this.speed.y
c.clearRect(0, 0, canvas.width, canvas.height)
c.beginPath()
c.rect(this.pos.x, this.pos.y, 20, 20)
c.fill()
}
}
let canvas = document.getElementById("game")
let c = canvas.getContext("2d")
var player = new Player({ x: 60, y: 50 }, { x: 0, y: 0 })
setInterval(() => player.draw(), 50)
document.addEventListener("keydown", function (e) {
switch (e.keyCode) {
case 37:
case 65:
player.speed.x = -1
break
case 39:
case 68:
player.speed.x = 1
break
}
})
document.addEventListener("keyup", function (e) {
switch (e.keyCode) {
case 37:
case 65:
case 39:
case 68:
player.speed.x = 0
break
}
})
<canvas id="game"></canvas>
I did simplify a lot of your code to keep this example small...
If you are really serious about building a JS game you should look at some of the game engines:
https://github.com/collections/javascript-game-engines
Those are some of the most popular open source ones
I am learning how to make a game with the canvas via JavaScript, and I have the arrow keys set to move a block on the canvas. I want to add a modifier in which while holding shift, the block moves twice as fast, and I cannot get my function to work properly when the shift key is pressed.
Any suggestions/help would be much appreciated!
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 540;
this.canvas.height = 330;
this.context = this.canvas.getContext("2d");
document.body.appendChild(this.canvas,document.body.childNodes[0]);
this.canvas.setAttribute("id", "myCanvas");
this.canvas.hidden = true;
this.interval = setInterval(updateGameArea, 1000/FPS);
window.addEventListener('keydown', function (e) {
myGameArea.keys = (myGameArea.keys || []);
myGameArea.keys[e.keyCode] = (e.type == "keydown");
})
window.addEventListener('keyup', function (e) {
myGameArea.keys[e.keyCode] = (e.type == "keydown");
})
},
clear : function(){
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y) {
this.gamearea = myGameArea;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateGameArea() {
myGameArea.clear();
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
if (myGameArea.keys && myGameArea.keys[37]) {myGamePiece.speedX = -10; }
if (myGameArea.keys && myGameArea.keys[39]) {myGamePiece.speedX = 10; }
if (myGameArea.keys && myGameArea.keys[38]) {myGamePiece.speedY = -10; }
if (myGameArea.keys && myGameArea.keys[40]) {myGamePiece.speedY = 10; }
if (myGameArea.keys && myGameArea.keys[65]) {myGamePiece.speedX = -10; }
if (myGameArea.keys && myGameArea.keys[68]) {myGamePiece.speedX = 10; }
if (myGameArea.keys && myGameArea.keys[87]) {myGamePiece.speedY = -10; }
if (myGameArea.keys && myGameArea.keys[83]) {myGamePiece.speedY = 10; }
//What do I need to do to get the following function to execute? (NOTE
//THIS WAS MOVED TO AFTER IF STATEMENTS PER COMMENT BELOW, THIS DID NOT
/////FIX the ISSUE)
GetShiftState(e);
myGamePiece.newPos();
myGamePiece.update();
}
//Below is the get shift key function I cannot get to work.
//What I am trying to do is increase the speed of the gamepiece moving
//when holding shift + the directional arrow
function GetShiftState (e) {
if (e.shiftKey) {
switch(e.which) {
case 37:
console.log("shift + left arrow");
myGamePiece.speedX = -20;
break;
case 38:
console.log("shift + up arrow");
myGamePiece.speedY = -20;
break;
case 39:
console.log("shift + right arrow");
myGamePiece.speedX = 20;
break;
case 40:
console.log("shift + down arrow");
myGamePiece.speedY = 20;
break;
default:
break;
}
}
else {
console.log("Shift key is up.");
}
}
You are resetting the myGamePiece.speed to 10 after you call the method.
Move the function call to after the end of the if statements.
Below is a snippet from some code I wrote for moving a div around the screen.
The principle is the same though, note we have a step variable and we adjust it if the event.shiftKey is true.
Complete code can be viewed / forked here: https://repl.it/#PaulThomas1/MoveDivAroundTheScreen
var step = 10;
if (event.shiftKey) step = step * 2;
switch (key) {
case "ArrowUp":
event.preventDefault();
box.style.top = (top - step) + "px";
break;
case "ArrowDown":
event.preventDefault();
box.style.top = (top + step) + "px";
break;
case "ArrowLeft":
box.style.left = (left - step) + "px";
break;
case "ArrowRight":
box.style.left = (left + step) + "px";
break;
}
I would like to know how to create a rainbow effect in my canvas in the fill style, like for it to change colors at certain intervals or when I continually press a key. Like from red to blue, etc, similar to how you can add a rainbow effect to text.
<script type="text/javascript">
var GAME_SPEED = 1000/60; //game rate
var x = 100;
var y = 100;
var sideLength = 10;
var leftKey = false;
var rightKey = false;
var upKey = false;
var downKey = false;
var spaceKey = false;
window.onload = function()
{
c = document.getElementById("marCanvas2");
c.width = window.innerWidth*0.9;
c.height = window.innerHeight*0.9;
window.setInterval("draw()" , GAME_SPEED);
}
document.onkeyup = function(event)
{
switch(event.keyCode)
{
case 37: leftKey =false;
break;
case 39: rightKey = false;
break;
case 38: upKey = false;
break;
case 40: downKey = false;
break;
case 32: spaceKey = false;
break;
}
}
document.onkeydown = function(event)
{
switch(event.keyCode)
{
case 37: leftKey =true;
break;
case 39: rightKey = true;
break;
case 38: upKey = true;
break;
case 40: downKey = true;
break;
case 32: spaceKey = true;
break;
}
}
function draw()
{
if(leftKey == true)
{
x--;
}
if(rightKey == true)
{
x++;
}
if(upKey == true)
{
y--;
}
if(downKey == true)
{
y++;
}
if(spaceKey == true)
{
sideLength++;
}
var c = document.getElementById("marCanvas2");
var cntxt = c.getContext("2d");
cntxt.fillStyle= " ";
cntxt.fillRect(x, y, sideLength, sideLength);
}
</script>
</head>
<body>
<!--Marlon Jacques -->
<canvas id="marCanvas2" style="border: 5px solid
#000000;">
Your browser does not support the canvas element.
</canvas>
</body>
</html>
You can do this by dynamically defining the start and end of the gradient. What colors you want is up to you, but you can use for example HSL color model to "rotate" through a color range with different speed for start and end.
Example 1
var ctx = document.querySelector("canvas").getContext("2d"),
angleA = Math.random() * 360, // start angle (for HSL)
angleB = Math.random() * 360,
stepA = 1.2, stepB = 0.7; // "speed" for change
function createGradient() {
var gr = ctx.createLinearGradient(0, 0, 500, 0); // create gradient
gr.addColorStop(0, "hsl(" + (angleA % 360) + ",100%, 50%)"); // start color
gr.addColorStop(1, "hsl(" + (angleB % 360) + ",100%, 50%)"); // end color
ctx.fillStyle = gr; // set as fill style
ctx.fillRect(0, 0, 500, 150); // fill area
}
// demo loop
(function anim() {
createGradient();
ctx.clearRect(8,8,484,134);
// =========> DRAW YOUR FRONT OBJECTS HERE <=========
angleA += stepA; // increase angles
angleB += stepB;
requestAnimationFrame(anim)
})();
<canvas width=500></canvas>
In the demo above the start and end colors are more or less random, you can instead just give one a head start so the other follows:
Example 2
var ctx = document.querySelector("canvas").getContext("2d"),
angle = Math.random() * 360, // start angle (for HSL)
angleDlt = 60, // 60° ahead
step = 1; // "speed" for change
function createGradient() {
var gr = ctx.createLinearGradient(0, 0, 500, 0); // create gradient
gr.addColorStop(0, "hsl(" + (angle % 360) + ",100%, 50%)"); // start color
gr.addColorStop(0.5, "hsl(" + ((angle + (angleDlt/2)) % 360) + ",100%, 50%)");
gr.addColorStop(1, "hsl(" + ((angle + angleDlt) % 360) + ",100%, 50%)");
ctx.fillStyle = gr; // set as fill style
ctx.fillRect(0, 0, 500, 150); // fill area
}
// demo loop
(function anim() {
createGradient();
ctx.clearRect(8,8,484,134);
angle += step; // increase angles
requestAnimationFrame(anim)
})();
<canvas width=500></canvas>
I am making a 2-Dimensional baseball game with JavaScript and HTML5 and I am trying to move an image that I have drawn with JavaScript like so:
//canvas
var c = document.getElementById("gameCanvas");
var ctx = c.getContext("2d");
//baseball
var baseball = new Image();
baseball.onload = function() {
ctx.drawImage(baseball, 400, 425);
};
baseball.src = "baseball2.png";
I'm not sure how I would move it though, I have seen many people seem to just type something like ballX and ballY but I don't understand where the actual x and y definition comes from. Here is my code so far:
http://jsfiddle.net/xRfua/
Thanks in advance for any help at all!
Store the balls position in a couple of variables and then you can translate based on these values before drawing your object, something like this should work:
var baseballX = 0;
var baseballY = 0;
var goLeft = 0;
var goRight = 0;
var goUp = 0;
var goDown = 0;
var ballSpeed = 5;
function renderCanvas() {
// clear the canvas
ctx.clearRect(0, 0, c.width, c.height);
ctx.save();
if(goLeft) baseballX -= ballSpeed;
if(goRight) baseballX += ballSpeed;
if(goUp) baseballY -= ballSpeed;
if(goDown) baseballY += ballSpeed;
// translate to balls position
ctx.translate(baseballX, baseballY);
// draw the image
ctx.drawImage(baseball, 0, 0);
ctx.restore();
}
// handle any user input
window.addEventListener('keyup', function(event) {
switch (event.keyCode) {
case 37: // Left
goLeft = 0;
break;
case 38: // Up
goUp = 0;
break;
case 39: // Right
goRight = 0;
break;
case 40: // Down
goDown = 0;
break;
}
}, false);
window.addEventListener('keydown', function(event) {
switch (event.keyCode) {
case 37: // Left
goLeft = 1;
break;
case 38: // Up
goUp = 1;
break;
case 39: // Right
goRight = 1;
break;
case 40: // Down
goDown = 1;
break;
}
}, false);
// set off timer
setInterval(renderCanvas, 1000 / 100);
Here is a working example: fiddle
I am trying to make these events happen when the D key ( for right movement ) and the A key ( for left movement ) but when I enter their correct key codes in the correct places it does not function when I press the D or S key to move. Can anyone tell me what is wrong? I'm using a recent version of Mozilla FireFox but I don't believe it's a requestAnimFrame problem.
document.onkeydown = function(e)
{
e = e || window.event;
switch(e.which || e.keyCode)
{
case 37:
leftpress = true;
Context.clearRect( 0, 0, CanWidth, CanHeight ); // Clear the Canvas
Context.fillStyle = 'green';
OldBackgroundX = BackgroundX;
BackgroundX = BackgroundX + 5;
Context.drawImage( FirstBackgroundImg, BackgroundX, BackgroundY, 1600, 800 );
Context.fillText( "You move left.", 200, 100 );
leftanimate = true;
if ( jumppress == true )
{
leftjump = true;
}
break;
// case 38:
// jump();
// up/jump
//break;
case 39:
if ( rightpress == true )
{
rightanimate = true;
}
/*console.log("You move right");
Context.fillStyle = 'green';
OldBackgroundX = BackgroundX;
BackgroundX = BackgroundX - 20;
Context.drawImage( FirstBackgroundImg, BackgroundX, BackgroundY, 1600, 800 );
Context.drawImage( ArrowRightImg, 400, 200 );// right
Context.fillText( "You move right.", 200, 100 );
break;
case 40: // down*/
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
};
document.onkeypress = function(event)
{
event = event || window.event;
switch(event.which || event.keyCode)
{
case 32:
jumppress = true;
if ( jumppress == true )
{
PJ = true;
}
if ( rightpress == true )
{
archjump = true;
}
if ( leftpress == true )
{
leftjump = true;
}
// up/jump
break;
/*
*
* Player Right Animation
*
*
* */
var Animation;
case 39:
rightpress = true;
if ( rightpress == true )
{
Context.clearRect( 0, 0, CanWidth, CanHeight ); // Clear the Canvas
//console.log("You move right");
Context.fillStyle = 'green';
BackgroundX = BackgroundX - 5;
Context.drawImage( FirstBackgroundImg, BackgroundX, BackgroundY, 1600, 800 );
rightanimate = true;
if ( jumppress == true )
{
archjump = true;
}
}
break;
}
}
document.onkeyup = function(event)
{
event = event || window.event;
switch(event.which || event.keyCode)
{
case 32:
jumppress = false;
break;
case 39:
rightpress = false;
break;
case 37:
leftpress = false;
}
}
You are using the wrong key codes to bind to WASD; the codes you are using correspond to the arrow keys themselves.
var KEY = {
WASD_LEFT: 65,
WASD_RIGHT: 68,
WASD_UP: 87,
WASD_DOWN: 83
}
document.onkeydown = function (e) {
switch (e.keyCode) {
case KEY.WASD_LEFT:
alert('Left');
break;
case KEY.WASD_RIGHT:
alert('Right');
break;
case KEY.WASD_UP:
alert('Up');
break;
case KEY.WASD_DOWN:
alert('Down');
break;
default:
return; // exit this handler for other keys
}
};
Here's a nice reference for JS key codes, and a fiddle for funsies.