Collision detection between circle and rectangle in Javascript game? - javascript

I'm creating a javascript game where I need a collision between the ball and rectangle to trigger a reset of the game. For now I just have an alert there for testing purposes. I'm having trouble getting the collision detection working.
This is what I've got so far but it isn't working
function startGame() {
keeper = new obstacle(40, 20, "#666", 130, 180);
theBall = new component("#000", 80, 10);
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 300;
this.canvas.height = 250;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('keydown', function(e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function(e) {
myGameArea.key = false;
})
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(color, x, y, type) {
this.type = type;
this.speed = 1.5;
this.angle = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.beginPath();
ctx.arc(this.x, this.y, 10, 0, 2 * Math.PI);
ctx.fillStyle = color;
ctx.fill();
ctx.restore();
}
this.newPos = function() {
this.x -= this.speed * Math.sin(this.angle);
this.y += this.speed * Math.cos(this.angle);
}
}
function obstacle(width, height, color, x, y) {
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;
}
this.collideWith = function(theBall){
var collide = true;
var myTop =this.y;
var theBallBottom = theBall.y + (theBall.radius)
if (myTop < theBallBottom)
{
collide = false;
}
return collide;
}
}
function updateGameArea() {
if (keeper.crashWith(theBall)) {
alert("Collision");
} else {
myGameArea.clear();
theBall.newPos();
theBall.update();
keeper.speedX = 0;
keeper.speedY = 0;
if (myGameArea.key && myGameArea.key == 37) {keeper.speedX = -1; }
if (myGameArea.key && myGameArea.key == 39) {keeper.speedX = 1; }
keeper.newPos();
keeper.update();
}
}
The game can be found here http://alexhollingsworth.co.uk/game.php

You named your method collideWith, but you are calling it crashWith in the update method. Plus this will only detect collision on y axis, but I assume this is intended.

I made an if statement that can detect collisions in JavaScript, here it is:
if circle x < rect x + circle width && circle x + rect width > rect x && circle y < rect y + circle height && rect height + circle y > rect y {
This works by putting the ball into an 'imaginary box', then senses if any of the edges of the 'imaginary box' come in contact with any of the edges of the rectangle. I hope this helped.

Related

How stay on the floor

Can you help with the code? I'm creating a parkour game and everything went well but I got stuck on it: as the cube will stand on the floor. Here is my js code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//Налаштування
var width = canvas.width;
var height = canvas.height;
var gameOver = function() {
clearInterval(intervalId);
ctx.font = "60px Caurier";
ctx.textAlign = "cener";
ctx.textBaseline = "middle";
ctxfillText("GAME OVER", width / 2, height / 2);
};
var cicle = function(x, y, radius, fillCircle) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
}; //Людина
//намалювати
function Draw() {
this.x = 10;
this.y = 10;
}
Draw.prototype.draw = function() {
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x + 50, this.y);
ctx.lineTo(this.x + 50, this.y + 50);
ctx.lineTo(this.x, this.y + 50);
ctx.lineTo(this.x, this.y);
ctx.fill();
}
Draw.prototype.move = function() {
if (this.x < 0) {
this.x = 0;
} else if (this.x > 1250) {
this.x = 1250;
}
if (this.y < 0) {
this.y = 0;
} else if (this.y > 450) {
this.y = 450;
}
while (this.y < 450) {
this.y++;
}
}
Draw.prototype.setDirection = function(direction) {
if (direction === "left") {
this.x = this.x - 10;
} else if (direction === "right") {
this.x = this.x + 10;
} else if (direction === "up") {
this.y = this.y - 150;
}
}
var person = new Draw;
var keyActions = {
37: "left",
38: "up",
39: "right"
};
$("body").keydown(function(event) {
var direction = keyActions[event.keyCode];
person.setDirection(direction);
});
setInterval(function() {
ctx.clearRect(0, 0, 1300, 500);
person.draw();
person.move();
//карта
var floor = ctx.strokeStyle = "LimeGreen";
ctx.lineWidth = 4;
ctx.strokeRect(0, 312, 1300, 362);
}, 30);
body {
background-color: rgb(44, 235, 225);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>parcur</title>
</head>
<body>
<canvas id="canvas" width="1300" height="500"></canvas>
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
</body>
</html>
I tried a lot but it didn't work out. For example, I tried this: first the code checks whether the cube and the floor are in the same coordinates, if so it reflects, if not, then no.I want the cube to be able to walk on the floor which is painted green, and not pass through it.

Building simple 2d javascript game, how to stop game piece leaving the canvass

So i'm new to this and have probably coded it wrong to start off with. I'm thinking after doing research that i should have stored my other game pieces in an array or as seperate variables. Please correct me if im wrong.
Here is my code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:5px solid #d3d3d3;
background-color: green;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
var myObstacle
function startGame() {
myGamePiece = new component(30, 30, "black", 350, 445);
blueGamePiece = new component(20, 20, "blue", 20, 20);
whiteGamePiece = new component(5, 40, "white",400, 20);
brownGamePiece = new component(25, 25, "brown", 650, 20);
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 700;
this.canvas.height = 480;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('keydown', function (e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function (e) {
myGameArea.key = false;
})
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function component(width, height, color, x, y) {
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.key && myGameArea.key == 37) {myGamePiece.speedX = -5; }
if (myGameArea.key && myGameArea.key == 39) {myGamePiece.speedX = 5;}
myGamePiece.newPos();
myGamePiece.update();
myGamePiece.update();
blueGamePiece.y += 1;
blueGamePiece.update();
whiteGamePiece.y +=3;
whiteGamePiece.update();
brownGamePiece.y +=2;
brownGamePiece.update();
}
</script>
</body>
</html>
I simply want to stop myGamePiece leaving the canvass not bounce it back.
Any other advice would be more than welcome.
Thankyou very much in advance.
Solution: Replace "this.update" function with this code.
this.update = function(){
if(this.x < 0){this.x = 0}
if(this.y < 0){this.y = 0}
if(this.x + this.width > myGameArea.canvas.width){this.x = myGameArea.canvas.width - this.width}
if(this.y + this.height > myGameArea.canvas.height){this.y = myGameArea.canvas.height - this.height}
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}

JavaScript canvas color-property interference

Problem: The color of block should be grey, but instead inherits the color-property of ball which is red. block2 should be blue, but inherits the color of block which is grey. How do I fix this problem? I have just started to learn how to program so i do not have much experience with things like this:/
Code:
function Player(x, y, w, h, color) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
this.dy = 3;
this.draw = function() {
c.fillRect(this.x, this.y, this.w, this.h);
c.fillStyle = this.color;
c.stroke();
c.closePath();
};
this.update = function() {
if (keyW === true) {
block.y -= block.dy;
}
if (keyS === true) {
block.y += block.dy;
}
if (arrowUp === true) {
block2.y -= block2.dy;
}
if (arrowDown === true) {
block2.y += block2.dy;
}
if (this.y + this.h > canvas.height) {
this.y = canvas.height - this.h;
}
if (this.y < 0) {
this.y = 0;
}
this.draw();
};
}
block = new Player(10, (canvas.height / 2) - 50, 250, 100, "grey");
block2 = new Player(canvas.width - 30, (canvas.height / 2) - 50, 20, 100, "blue");
function Ball(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.dx = 3;
this.dy = 0;
this.draw = function() {
c.beginPath();
c.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
c.fillStyle = this.color;
c.fill();
c.closePath();
};
this.update = function() {
this.x -= this.dx;
if (this.y + this.radius > canvas.height) {
this.y = canvas.height - this.radius;
}
if (this.y - this.radius < 0) {
this.y = this.radius;
}
if (this.x + this.radius > canvas.width) {
this.dx = -this.dx;
}
if (this.x - this.radius < 0) {
this.dx = -this.dx;
}
this.draw();
};
}
ball = new Ball(canvas.width / 2 - 50, canvas.height / 2, 10, "red");
You are filling a rect inside Player update method before changing the color, so it uses previous fillStyle value which is red.
Instead of:
c.fillRect(x, y, w, h);
c.fillStyle = this.color;
Do:
c.fillStyle = this.color;
c.fillRect(x, y, w, h);

Randomly Positioning Squares in JavaScript?

Code isn't working, I need to randomly position a square component. I tried running some code, but nothing happens. Here's my code:
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image"){
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.update = function() {
ctx = myGameArea.context;
if (this.type == "image"){
ctx.drawImage(this.image,this.x, this.y, this.width,this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
}
function startGame() {
random = Math.floor((Math.random()*100) + 1);
document.write(random);
random2 = Math.floor((Math.random()*100) + 1);
document.write(random2);
square = new component(random, random2, "green", random, random2);
myGameArea.start();
return square
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 450;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 1);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function updateGameArea() {
myGameArea.clear();
square.update();
}
For some reason, the function startGame doesn't work correctly. Nothing happens when I run the code. I opened the console log as well, and no syntax errors registered.
You can get the code to work by applying it like this, for example:
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image"){
this.image = new Image();
this.image.src = color;
}
this.score = 0;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.gravity = 0;
this.gravitySpeed = 0;
this.color=color;
this.update = function() {
random = Math.floor((Math.random()*100) + 1);
random2 = Math.floor((Math.random()*100) + 1);
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
randcolor=getRandomColor();
ctx = myGameArea.context;
if (this.type == "image"){
ctx.drawImage(this.image, random, random2, random,random2);
} else {
ctx.fillStyle = randcolor;
ctx.fillRect(random, random2, random, random2);
}
this.x=random;
this.y=random2;
this.width=random;
this.height=random2;
this.color=randcolor;
}
}
function startGame() {
random = Math.floor((Math.random()*100) + 1);
random2 = Math.floor((Math.random()*100) + 1);
square = new component(random, random2, "green", random, random2);
myGameArea.start();
return square
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 450;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 1);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function updateGameArea() {
myGameArea.clear();
square.update();
}
document.getElementById("start").addEventListener('click', startGame)
<div id="start">press to start</div>
In here I did three things:
I added a text that you can click
I added an event listener on this text that invokes the startGame() function
I got rid of the document.write() statements. I built this is Jsfiddle, which doesn't allow it, and it's considered bad practice anyway.

Canvas multiple bouncing squares - Clearing Canvas

I've created a little bouncing boxes demo in javascript using the canvas. Each box (for want of a better word) class handles it's own updates and rendering. However, my problem lies in clearing the canvas before drawing the next frame. It clears fine when the boxes are moving but leaves artifacts behind after it hits a wall. Here's a fiddle - https://jsfiddle.net/dzuvL7ph/1/
Here's my code;
function init(){
window.box1 = new Box(50, 'red', 0, 0);
window.box2 = new Box(50, 'blue', 400, 20);
requestAnimationFrame(update);
}
function update() {
window.box1.update();
window.box2.update();
requestAnimationFrame(update);
requestAnimationFrame(render);
}
function render() {
window.box1.render();
window.box2.render();
}
// -------------------------------------------------------------------------------------------------------
// --
// -------------------------------------------------------------------------------------------------------
var Box = function(dimensions, color, x, y){
this.width = dimensions;
this.height = dimensions;
this.x = x;
this.y = y;
this.velocityX = 10;
this.velocityY = 10;
this.color = color;
this.context = document.getElementById('canvas').getContext('2d');
this.update = function(){
this.x += this.velocityX;
this.y += this.velocityY;
this.collisionCheck();
};
this.render = function(){
this.context.fillStyle = this.color;
this.context.clearRect(this.x - this.velocityX, this.y - this.velocityY, this.width, this.height);
this.context.fillRect(this.x, this.y, this.width, this.height);
};
this.collisionCheck = function(){
if(this.y > 600 - this.height || this.y < 0)
this.velocityY *= -1;
if(this.x > 800 - this.width || this.x < 0)
this.velocityX *= -1;
};
};
I assume it's to do with this.context.clearRect(this.x - this.velocityX, this.y - this.velocityY, this.width, this.height); but I can't figure out what I'm doing wrong.
It's a little weird you're doing a cleanup for each box. Normally, you'd wipe the whole canvas on each frame: https://jsfiddle.net/yb58fd47/
WHY it happens
Your update function checks for collisions, which can in turn reverse the speed component(s). But, your render function relies on that speed component to accurately represent the last speed. If you don't want to clear the whole canvas, you can keep track of the previous actual speed the box had (I added velocityXLast and velocityYLast):
function init(){
window.box1 = new Box(50, 'red', 0, 0);
window.box2 = new Box(50, 'blue', 120, 20);
requestAnimationFrame(update);
}
function update() {
window.box1.update();
window.box2.update();
requestAnimationFrame(update);
requestAnimationFrame(render);
}
function render() {
window.box1.render();
window.box2.render();
}
// -------------------------------------------------------------------------------------------------------
// --
// -------------------------------------------------------------------------------------------------------
var Box = function(dimensions, color, x, y){
this.width = dimensions;
this.height = dimensions;
this.x = x;
this.y = y;
this.velocityX = 10;
this.velocityY = 10;
this.color = color;
this.context = document.getElementById('canvas').getContext('2d');
this.update = function(){
this.x += this.velocityX;
this.y += this.velocityY;
this.velocityXLast = this.velocityX;
this.velocityYLast = this.velocityY;
this.collisionCheck();
};
this.render = function(){
this.context.fillStyle = this.color;
this.context.clearRect(this.x - this.velocityXLast, this.y - this.velocityYLast, this.width, this.height);
this.context.fillRect(this.x, this.y, this.width, this.height);
};
this.collisionCheck = function(){
if(this.y > 150 - this.height || this.y < 0)
this.velocityY *= -1;
if(this.x > 400 - this.width || this.x < 0)
this.velocityX *= -1;
};
};
init();
canvas {border: 1px solid black}
<canvas id="canvas" width="400" height="150"></canvas>

Categories

Resources