0
I created a small code to illustrate my problem. In this code is drawn a circle (enemy) randomly on the canvas screen every 100ms. But sometimes you end up drawing also where the larger circle is that would be the player. What I want is for Spawn to be random inside the canvas as long as it’s not where the player is.
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 300
canvas.height = 300
const enemies = []
const player = {
x: canvas.width / 2,
y: canvas.height / 2,
radius: 50,
draw: function(){
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
ctx.fill()
}
}
class Enemy {
constructor(x, y, radius, color){
this.x = x
this.y = y
this.radius = radius
this.color = color
}
draw(){
ctx.save()
ctx.fillStyle = this.color
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
ctx.fill()
ctx.restore()
}
}
function rand(min, max) {
return Math.floor(Math.random() * ((max + 1) - min) + min)
}
// Spawn enemies every 100ms position randomly
setInterval(() => {
let x = rand(0, canvas.width)
let y = rand(0, canvas.height)
enemies.push(new Enemy(x, y, 10, '#f00'))
}, 100)
function run(){
ctx.clearRect(0, 0, canvas.width, canvas.height)
player.draw()
for(let i in enemies){
enemies[i].draw()
}
requestAnimationFrame(run)
}
run()
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background: #444;
}
canvas {
background: #fff;
display: block;
margin: 10px auto;
}
<canvas></canvas>
Update and troubleshooting
With the reference of @Augusto Vasques I could think of a way to solve.
All I did was create a function inside the setInterval that measures the distance between the enemy and the player and if there is collision calls the function again to generate a new coordinate on the canvas and if there is no collision is drawn the enemy.
setInterval(() => {
function spawnRandom(){
let radius = 10
let x = rand(0, canvas.width)
let y = rand(0, canvas.height)
const dist = Math.hypot(player.x - x, player.y - y)
if(dist < player.radius + radius){
spawnRandom()
} else {
enemies.push(new Enemy(x, y, 10, '#f00'))
}
}
spawnRandom()
}, 100)
Full code working below:
console.clear()
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 150
canvas.height = 150
const enemies = []
const player = {
x: canvas.width / 2,
y: canvas.height / 2,
radius: 50,
draw: function(){
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
ctx.fill()
}
}
class Enemy {
constructor(x, y, radius, color){
this.x = x
this.y = y
this.radius = radius
this.color = color
}
draw(){
ctx.save()
ctx.fillStyle = this.color
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
ctx.fill()
ctx.restore()
}
}
function rand(min, max) {
return Math.floor(Math.random() * ((max + 1) - min) + min)
}
// Spawn enemies every 100ms position randomly
setInterval(() => {
function spawnRandom(){
let radius = 10
let x = rand(0, canvas.width)
let y = rand(0, canvas.height)
const dist = Math.hypot(player.x - x, player.y - y)
if(dist < player.radius + radius){
spawnRandom()
} else {
enemies.push(new Enemy(x, y, 10, '#f00'))
}
}
spawnRandom()
}, 100)
function run(){
ctx.clearRect(0, 0, canvas.width, canvas.height)
player.draw()
for(let i in enemies){
enemies[i].draw()
}
requestAnimationFrame(run)
}
run()
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background: #444;
}
canvas {
background: #fff;
display: block;
margin: 10px auto;
}
<canvas></canvas>
I had seen your edition at the time and I was waiting for a reply from you to the comment, which did not come. Then as I do not know your degree mathematical knowledge I will not present you an answer, however here is an answer that will help you.
– Augusto Vasques