I am trying to detect if a rectangle collides with a circle but whatever I try it returns undefinded
.
Here is the code I am using. The relevant code starts around the RectCircleColliding
class.
const canvas = document.getElementById('canvas1');
const c = canvas.getContext('2d');
let playing = true
let mainMenu = false
let cutscenes = 0
let room = "main"
const gravity = 0.5
var onGround = false;
let scrolled = {
y: 0,
x: 0
}
let jumpTime = 0
const wjumpTime = 10
let collision = 0;
canvas.width = window.innerWidth
canvas.height = window.innerHeight
function startGame() {
let element = document.getElementById("start")
element.setAttribute("hidden", "hidden");
mainMenu = false
playing = true
console.log('start')
// if (cutscenes == 0) {
// player.position.x = 0
// player.position.y = 1000
// player.velocity.y = 0
// }
}
class Player {
constructor() {
this.position = {
x: 100,
y: 888
}
this.velocity = {
x: 0,
y: 0
}
this.width = 64
this.height = 128
}
draw() {
c.fillStyle = "red"
c.fillRect(this.position.x, this.position.y, this.width, this.height)
}
update() {
this.draw()
this.position.y += this.velocity.y
this.position.x += this.velocity.x
if (this.position.y + player.height + player.velocity.y <= canvas.height)
this.velocity.y += gravity
}
}
class Platform {
constructor({
x,
y,
w,
h
}) {
this.position = {
x,
y
}
this.width = w
this.height = h
}
draw(color) {
c.fillStyle = color
c.fillRect(this.position.x, this.position.y, this.width, this.height)
}
}
class Enemy {
constructor({
x,
y,
w,
h,
n
}) {
this.position = {
x,
y
},
this.velocity = {
x: 0,
y: 0
}
this.width = w
this.height = h
this.number = n
}
draw(color) {
c.fillStyle = color
c.fillRect(this.position.x, this.position.y, this.width, this.height)
}
update() {
this.position.y += this.velocity.y
this.position.x += this.velocity.x
if (this.position.y + this.height + this.velocity.y <= canvas.height)
this.velocity.y += gravity
}
}
class Circles {
constructor({
x,
y,
n,
r
}) {
this.position = {
x,
y
},
this.velocity = {
x: 0,
y: 0
}
this.radius = r
this.number = n
}
draw(color) {
c.beginPath();
c.globalAlpha = 0.2
c.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI, false);
c.fillStyle = color;
c.fill();
c.globalAlpha = 1
}
}
const player = new Player()
const platforms = [
// new Platform({ x: 200, y: 800, w: 200, h: 20 }), new Platform({ x: 500, y: 700, w: 200, h: 20 }),
]
// //new Platform({x: 0, y:1016, w:1900, h:150 })
// , new Platform({ x: 500, y: 400, w: 600, h: 20 }),
// //ground
// ]
let groundPos = 0
const ground = [new Platform({
x: 0,
y: 1016,
w: 64 * 43,
h: 128
})]
let tree = [
new Platform({
x: 1024,
y: 1016,
w: 512,
h: -1280
})
]
let mutatedgors = [
// Mutated Gors
new Enemy({
x: 888,
y: 800,
w: 64,
h: 64,
n: 1
})
]
let circles = [
new Circles({
x: 888,
y: 800,
r: 750,
n: 1
})
]
const keys = {
right: {
pressed: false
},
left: {
pressed: false
},
up: {
pressed: false
}
}
function animate() {
tree.forEach(tree => {
if (player.position.x > tree.position.x + 100 && player.position.x < tree.position.x + tree.width - 100) {
addEventListener('keydown', ({
keyCode
}) => {
// console.log(keyCode)
switch (keyCode) {
case 70:
player.position.y = -2000
room = "tree1"
break
}
})
}
})
circles.forEach(circles => {
mutatedgors.forEach(mutatedgors => {
if (circles.n == mutatedgors.n) {
circles.position.x = mutatedgors.position.x
circles.position.y = mutatedgors.position.y
}
})
})
function RectCircleColliding() {
circles.forEach(circles => {
mutatedgors.forEach(mutatedgors => {
var circle = {
x: circles.position.x,
y: circles.position.y,
r: circles.radius
};
var rect = {
x: player.position.x,
y: player.position.y,
w: player.width,
h: player.height
};
var distX = Math.abs(circle.x - rect.x - rect.w / 2);
var distY = Math.abs(circle.y - rect.y - rect.h / 2);
if (distX > (rect.w / 2 + circle.r)) {
return false
}
if (distY > (rect.h / 2 + circle.r)) {
return false
}
if (distX <= (rect.w / 2)) {
return true
}
if (distY <= (rect.h / 2)) {
return true
}
var dx = distX - rect.w / 2;
var dy = distY - rect.h / 2;
return (dx * dx + dy * dy <= (circle.r * circle.r));
})
})
}
console.log(RectCircleColliding())
// console.log(scrolled.x)
// console.log(player.position.x)
window.onscroll = function() {
window.scrollTo(1920, 1080);
}
//console.log(keys.up.pressed)
//console.log(onGround)
//console.log(jumpTime)
if (jumpTime >= wjumpTime) {
keys.up.pressed = false
}
if (player.velocity.y > 0) {
jumpTime = wjumpTime
}
requestAnimationFrame(animate)
c.clearRect(0, 0, canvas.width, canvas.height)
if (playing == true) {
platforms.forEach(platform => {
platform.draw("blue")
})
ground.forEach(ground => {
ground.draw("green")
})
tree.forEach(tree => {
tree.draw("#994a00")
})
mutatedgors.forEach(mutatedgors => {
mutatedgors.draw("blue")
})
circles.forEach(circles => {
circles.draw("red")
})
player.update()
mutatedgors.forEach(mutatedgors => {
mutatedgors.update()
})
}
if ((keys.right.pressed && player.position.x < 1100)) {
player.velocity.x = 5
} else if (((keys.left.pressed && player.position.x > 810)) ||
(keys.left.pressed && scrolled.x == 0 && player.position.x != -10)) {
// console.log(player.position.x)
player.velocity.x = -5
} else {
player.velocity.x = 0
if (keys.right.pressed && room == "main") {
scrolled.x -= 5
platforms.forEach(platform => {
platform.position.x -= 5
})
ground.forEach(ground => {
ground.position.x -= 5
})
tree.forEach(tree => {
tree.position.x -= 5
})
mutatedgors.forEach(mutatedgors => {
mutatedgors.position.x -= 5
})
} else if (keys.left.pressed && room == "main") {
if (scrolled.x <= 300 && player.position.x != -10) {
scrolled.x += 5
platforms.forEach(platform => {
platform.position.x += 5
})
ground.forEach(ground => {
ground.position.x += 5
})
tree.forEach(tree => {
tree.position.x += 5
})
mutatedgors.forEach(mutatedgors => {
mutatedgors.position.x += 5
})
}
}
}
if (keys.up.pressed) {
onGround = false
player.velocity.y -= 2
jumpTime++
}
while (player.position.y < 463.5) {
jumpTime = wjumpTime
player.position.y += 1
scrolled.y += 1
platforms.forEach(platform => {
platform.position.y += 1
})
ground.forEach(ground => {
ground.position.y += 1
})
tree.forEach(tree => {
tree.position.y += 1
})
mutatedgors.forEach(mutatedgors => {
mutatedgors.position.y += 1
})
}
if (scrolled.y > 0) {
while (player.position.y > 463.5 && scrolled.y != 0) {
jumpTime = wjumpTime
platforms.forEach(platform => {
platform.position.y -= 1
})
ground.forEach(ground => {
ground.position.y -= 1
})
tree.forEach(tree => {
tree.position.y -= 1
})
mutatedgors.forEach(mutatedgors => {
mutatedgors.position.y -= 1
})
player.position.y -= 1
scrolled.y -= 1
}
}
if (player.position.y > 850 && scrolled.y <= 0) {
while (player.position.y > 850) {
jumpTime = wjumpTime
platforms.forEach(platform => {
platform.position.y -= 1
})
ground.forEach(ground => {
ground.position.y -= 1
})
tree.forEach(tree => {
tree.position.y -= 1
})
mutatedgors.forEach(mutatedgors => {
mutatedgors.position.y -= 1
})
player.position.y -= 1
scrolled.y -= 1
}
}
platforms.forEach(platform => {
if (player.position.y + player.height <= platform.position.y + 1 &&
player.position.y + player.height + player.velocity.y >= platform.position.y + 1 &&
player.position.x + player.width >= platform.position.x &&
player.position.x <= platform.position.x + platform.width) {
player.velocity.y = 0
onGround = true
jumpTime = 0
collision = 0
} else
if (player.position.y <= platform.position.y + platform.height + 1 &&
player.position.y + player.velocity.y >= platform.position.y + platform.height + 1 &&
player.position.x + player.width >= platform.position.x &&
player.position.x <= platform.position.x + platform.width
) {
player.velocity.y = 0
collision = 0
jumpTime = 0
}
})
ground.forEach(ground => {
// console.log(collision)
if (player.position.y + player.height <= ground.position.y + 1 &&
player.position.y + player.height + player.velocity.y >= ground.position.y + 1 &&
player.position.x + player.width >= ground.position.x &&
player.position.x <= ground.position.x + ground.width) {
player.velocity.y = 0
onGround = true
jumpTime = 0
} else if (player.position.y >= ground.position.y + ground.height - 64 * (1 / 16) &&
player.position.y + player.velocity.y <= ground.position.y + ground.height - 64 * (1 / 16) &&
player.position.x + player.width >= ground.position.x &&
player.position.x <= ground.position.x + ground.width) {
console.log(player.position.y)
console.log(ground.position.y + ground.height)
player.velocity.y = 0
jumpTime = wjumpTime
} else if (player.position.x <= ground.width + ground.position.x + 1 &&
player.position.x + player.width >= ground.position.x - 1 &&
player.position.y + player.height >= ground.position.y + 1 &&
player.position.y <= ground.position.y + ground.width - 1) {
player.velocity.x = 0
}
})
platforms.forEach(platform => {
mutatedgors.forEach(mutatedgors => {
if (mutatedgors.position.y + mutatedgors.height <= platform.position.y + 1 &&
mutatedgors.position.y + mutatedgors.height + mutatedgors.velocity.y >= platform.position.y + 1 &&
mutatedgors.position.x + mutatedgors.width >= platform.position.x &&
mutatedgors.position.x <= platform.position.x + platform.width) {
mutatedgors.velocity.y = 0
} else
if (mutatedgors.position.y <= platform.position.y + platform.height + 1 &&
mutatedgors.position.y + mutatedgors.velocity.y >= platform.position.y + platform.height + 1 &&
mutatedgors.position.x + mutatedgors.width >= platform.position.x &&
mutatedgors.position.x <= platform.position.x + platform.width
) {
mutatedgors.velocity.y = 0
}
})
})
ground.forEach(ground => {
//console.log(collision)
mutatedgors.forEach(mutatedgors => {
if (mutatedgors.position.y + mutatedgors.height <= ground.position.y + 1 &&
mutatedgors.position.y + mutatedgors.height + mutatedgors.velocity.y >= ground.position.y + 1 &&
mutatedgors.position.x + mutatedgors.width >= ground.position.x &&
mutatedgors.position.x <= ground.position.x + ground.width) {
mutatedgors.velocity.y = 0
} else if (mutatedgors.position.y >= ground.position.y + ground.height - 64 * (1 / 16) &&
mutatedgors.position.y + mutatedgors.velocity.y <= ground.position.y + ground.height - 64 * (1 / 16) &&
mutatedgors.position.x + mutatedgors.width >= ground.position.x &&
mutatedgors.position.x <= ground.position.x + ground.width) {
mutatedgors.velocity.y = 0
} else if (mutatedgors.position.x <= ground.width + ground.position.x + 1 &&
mutatedgors.position.x + mutatedgors.width >= ground.position.x - 1 &&
mutatedgors.position.y + mutatedgors.height >= ground.position.y + 1 &&
mutatedgors.position.y <= ground.position.y + ground.width - 1) {
mutatedgors.velocity.x = 0
}
})
})
}
animate()
addEventListener('keydown', ({
keyCode
}) => {
switch (keyCode) {
case 65:
console.log('left')
keys.left.pressed = true
break
case 83:
console.log('down')
break
case 68:
console.log('right')
keys.right.pressed = true
break
case 32:
if (onGround == true) {
keys.up.pressed = true
} else keys.up.pressed = false
break
case 87:
console.log('jump')
if (onGround == true) {
keys.up.pressed = true
} else keys.up.pressed = false
break
}
})
addEventListener('keyup', ({
keyCode
}) => {
switch (keyCode) {
case 65:
console.log('left')
keys.left.pressed = false
break
case 83:
console.log('down')
break
case 68:
console.log('right')
keys.right.pressed = false
break
case 32:
console.log('jump')
keys.up.pressed = false
break
case 87:
console.log('jump')
keys.up.pressed = false
break
}
})
/* body {
background: black;
}
#canvas1 {
position: absolute;
border: 3px solid white;
width: 800px;
height: 700px;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
} */
body {
margin: 0px;
-ms-overflow-style: none;
/* for Internet Explorer, Edge */
scrollbar-width: none;
/* for Firefox */
overflow-y: scroll;
}
body::-webkit-scrollbar {
display: none;
/* for Chrome, Safari, and Opera */
}
#start {
position: absolute;
left: 810px;
top: 350px;
font-size: 50px;
border: 5px solid black;
color: black;
text-align: center;
background-color: white;
}
footer {
vertical-align: top
}
div {
margin: 0px;
}
canvas {
margin: 0px;
}
<canvas id="canvas1"></canvas>
<div id="start-screen" class="screen" style="display:block">
<button id="start" onclick="startGame()">Start Game</button>
</div>
You are not returning something from the RectCircleColliding
function.
If you need to return smth then forEach
is the wrong looping mechanism to use.
You can use a for ... of loop instead:
function RectCircleColliding() {
for (let circlesParam of circles) {
var circle = {
x: circlesParam.position.x,
y: circlesParam.position.y,
r: circlesParam.radius,
};
var rect = {
x: player.position.x,
y: player.position.y,
w: player.width,
h: player.height,
};
var distX = Math.abs(circle.x - rect.x - rect.w / 2);
var distY = Math.abs(circle.y - rect.y - rect.h / 2);
if (distX > rect.w / 2 + circle.r) {
return false;
}
if (distY > rect.h / 2 + circle.r) {
return false;
}
if (distX <= rect.w / 2) {
return true;
}
if (distY <= rect.h / 2) {
return true;
}
var dx = distX - rect.w / 2;
var dy = distY - rect.h / 2;
return dx * dx + dy * dy <= circle.r * circle.r;
}
}
console.log(RectCircleColliding());
PS: If you are going to loop over the elements of an array it's better to name the individual element differently, for example:
circles.forEach((circle) => ...)
MDN docs of forEach for more info: https://mzl.la/3RShywF