Анимации(canvas)
На экране шарик со случайным цветом,который двигается в разных направлениях и отбивается от стен. Каждые 200 миллисекунд появляется ещё 1 шарик, у которого есть случайный цвет и двигается в случайном направлении. Максимальное количество шариков не должно превышать 20.
Помогите пожалуйста понять и реализовать задачу.
class GraphicTools{
constructor(){
this.canvas=document.querySelector('canvas')
this.ctx=this.canvas.getContext('2d')
}
}
//===================================================
class Ball extends GraphicTools{
constructor(){
super()
this.x=Math.random()*this.canvas.width;
this.y=Math.random()*this.canvas.height;
this.z=20;
this.dx=Math.random()*2
this.dy=Math.random()*2
this.a=Math.random()*255
this.b=Math.random()*255
this.c=Math.random()*255
this.col=`rgb(${this.a},${this.b},${this.c})`
}
move(){
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)
if(this.x>this.canvas.width||this.x<0){
this.dx=-this.dx
}
if(this.y>this.canvas.height||this.y<0){
this.dy=-this.dy
}
this.x+=this.dx
this.y+=this.dy
this.paint()
}
paint(){
this.ctx.beginPath()
this.ctx.fillStyle=this.col
this.ctx.arc(this.x,this.y,this.z,0,6.28)
this.ctx.fill()
this.ctx.closePath()
}
}
//=================================================
class Animation{
static start(){
let ball=new Ball()
ball.paint()
// for(let i=0;i<20;i++){
// setInterval(function(){
// ball.paint()
// },200)
// }
setInterval(function(){
ball.move();
},2)
}
}
<canvas height="600" width="1366" style="background: yellowgreen"></canvas>
Ответы (2 шт):
Как-то так:
class Game{
constructor(){
this.balls = [];
//bind events to this context
this.addBall = this.addBall.bind(this);
this.render = this.render.bind(this);
//timer for generate new ball
this.timer = setInterval(this.addBall, 200);
//start draw loop
this.render();
}
addBall(){
//recursion condition
if(this.balls.length >= 20){
if(this.timer)
clearInterval(this.timer);
return;
}
//generate new ball
this.balls.push(new Ball(
genRandom(opts.radius/2, w - opts.radius/2),
genRandom(opts.radius/2, h - opts.radius/2),
genRandom(0, Math.PI*2)
));
}
render(){
//draw background
ctx.fillStyle = opts.bgColor;
ctx.fillRect(0, 0, w, h);
//redraw balls
this.balls.forEach( (ball) => {
ball.update();
ball.render();
} );
//loop render function
requestAnimationFrame(this.render);
}
}
Полный пример: https://codepen.io/HTMLProgrammer/pen/qBdoXor
Если вносить минимум изменений в ваш код, то это должно выглядеть как в коде ниже. Переносится код очищения canvas в GraphicTools поскольку вызвать его надо только один раз в начале рисования всех шаров. А дальше делается просто массив let balls = []; и работаем со всеми шарами одновременно. Все основные изменения в пределах класса Animation.
class GraphicTools{
constructor(){
this.canvas=document.querySelector('canvas')
this.ctx=this.canvas.getContext('2d')
}
clear(){
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)
}
}
//===================================================
class Ball extends GraphicTools{
constructor(){
super()
this.x=Math.random()*this.canvas.width;
this.y=Math.random()*this.canvas.height;
this.z=20;
this.dx=Math.random()*2
this.dy=Math.random()*2
this.a=Math.random()*255
this.b=Math.random()*255
this.c=Math.random()*255
this.col=`rgb(${this.a},${this.b},${this.c})`
}
move(){
if(this.x>this.canvas.width||this.x<0){
this.dx=-this.dx
}
if(this.y>this.canvas.height||this.y<0){
this.dy=-this.dy
}
this.x+=this.dx
this.y+=this.dy
this.paint()
}
paint(){
this.ctx.beginPath()
this.ctx.fillStyle=this.col
this.ctx.arc(this.x,this.y,this.z,0,6.28)
this.ctx.fill()
this.ctx.closePath()
}
}
//=================================================
class Animation{
static start(){
let balls = [new Ball()];
let gt = new GraphicTools();
let interval = setInterval(() => {
balls.push(new Ball());
if(balls.length >= 20) clearInterval(interval);
}, 200)
setInterval(function(){
gt.clear()
balls.forEach(ball => {
ball.move(), ball.paint()
});
},2)
}
}
Animation.start()
<canvas height="600" width="1366" style="background: yellowgreen"></canvas>