이전 글에서는 공 하나가 화면 안에서 생각없이 튕기는 내용이었다.
이번에는 컴퓨터의 강점을 살려, 공의 갯수를 확 늘리게되면 이제 좀 볼만해진다.
이전에는 ball 클래스를 만들어놓고 공을 하나만 만들었었는데, 이번에는 초기화 함수, init()에서 공을 여러개 생성하고,
animate() 함수에서 그 공들을 매 순간 업데이트 할 때마다 계산해준다.
function init(){ // 공의 갯수만큼 공의 객체 생성
for(i=0;i<ballNumber;i++){
balls[i] = new Ball(canvas.width*0.5, canvas.height*0.5)
}
}
function animate(){ // 매 프레임마다 벌어지는 일들
ctx.fillStyle='rgba(255,255,255,0.8)'; // 전체 화면 지우기. 하얀색의 alpha값을 변경함에 따라 공의 잔상이 달라진다.
ctx.fillRect(0,0,canvas.width,canvas.height);
for(i=0;i<ballNumber;i++){
balls[i].update();
balls[i].draw();
}
}
위 데모에서는 30개의 공을 그렸는데, requestAnimationFrame()이 1초에 60번 동작하고, 그 때마다 30개 공의 좌표를 이동시키고 그림을 그리고 벽에 닿았는지 판단해준다. 문돌이에게는 놀라운 일이다. ㅎ
다양성을 주기 위해서 각 공마다 랜덤 특성을 부여했다.
시작할때 공이 랜덤한 방향으로 날라가고,
this.angle = (Math.random()*(Math.PI*2));
공의 색깔이 랜덤하게 생성되고,
this.c = 'rgba('+Math.random()*255+','+Math.random()*255+','+Math.random()*255+')';
공의 크기를 다르게 하고,
this.size = 10+Math.random()*20;
공이 날라가는 속도를 다르게 했다.
this.power = Math.random()*3+2;
아예 공의 수를 200개로...
이 공이 움직이는 것처럼 보이는 이유가, 매 프레임마다 캔버스 전체를 하얀색 상자를 그려서 덮어버리고 각 공들을 이동한 좌표로 그려주고, 다음 프레임에서 다시 다 지우고, 공들을 다시 그리고 ... 이렇게 반복함으로써 공들이 움직이는 것처럼 보이는 것인데...
캔버스를 덮을 하얀색의 투명도(alpha값)을 다르게 함에 따라서 공의 궤적을 다르게 볼 수 있다.
alpha =1 |
alpha = 0.5 |
alpha = 0.1 |
전체 코드 :
window.onload = function () {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth-15;
canvas.height = window.innerHeight-15;
balls=[];
ballNumber = 20;
class Ball{
constructor(x,y){ // ball의 기본 속성들을 정의
this.x = x;
this.y = y;
this.c = 'rgba('+Math.random()*255+','+Math.random()*255+','+Math.random()*255+')'; // 공의 색깔을 random으로 설정
this.size = 10+Math.random()*20;
this.angle = (Math.random()*(Math.PI*2));
this.power = Math.random()*3+2;
this.directionX = this.power * Math.cos(this.angle);
this.directionY = this.power * Math.sin(this.angle);
}
update(){ // 프레임마다 속성들을 변화시킴
this.y += this.directionY;
this.x += this.directionX;
if(this.y+this.size>canvas.height || this.y-this.size<0){ // 바운드 처리
this.directionY *= -1;
}
if(this.x>canvas.width-this.size ) {
this.x = canvas.width-this.size;
this.directionX *= -1;
} else if (this.x-this.size < 0){
this.directionX *= -1;
}
}
draw(){ // 넘어온 속성값대로 캔버스에 그림을 그려줌
ctx.fillStyle= this.c;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle= 'black';
ctx.stroke();
}
}
function init(){ // 공의 갯수만큼 공의 객체 생성
for(i=0;i<ballNumber;i++){
balls[i] = new Ball(canvas.width*0.5, canvas.height*0.5)
}
}
function animate(){ // 매 프레임마다 벌어지는 일들
ctx.fillStyle='rgba(255,255,255,0.1)'; // 전체 화면 지우기. 하얀색의 alpha값을 변경함에 따라 공의 잔상이 달라진다.
ctx.fillRect(0,0,canvas.width,canvas.height);
for(i=0;i<ballNumber;i++){
balls[i].update();
balls[i].draw();
}
window.addEventListener('resize',function(){ // 화면 크기가 변하면 캔버스 크기도 변경해줌
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
})
requestAnimationFrame(animate);
}
init();
animate();
}
|
cs |
다음에는 중력까지 가미해보자.
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받을 수 있습니다.
'문과생의 coding' 카테고리의 다른 글
Javascript 마우스 드래그한 방향으로 공 날리기 (0) | 2021.02.13 |
---|---|
Javascript 캔버스에서 튕기는 공들 (w 중력) (0) | 2021.02.08 |
Javascript 캔버스에서 튕기는 공 w 중력 (0) | 2021.01.10 |
Javascript 캔버스에서 움직이는 공 그리기 (0) | 2020.12.26 |
JavaScript 간단하게 구현한 계산기 (버블링 활용) (0) | 2020.09.20 |