1. HTML 표준 CANVAS 기술 소개 / https://itadventure.tistory.com/130
◐ 2. 자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자 ◑
어릴 때 오락실에서 비행기 게임을 해본 적이 있다면,
수많은 적의 비행기와 총탄들이 자연스럽게 동시에 움직이는 것을 볼 수 있는데요.
크레이는 이제 평화주의인지라 전쟁과 관련된 것을 만들기는 싫고,
겨울에 내리는 눈송이들이 각각 속도와 크기, 속도(크기에 좌우됨) 등의 정보를 가지고 하늘에서 땅으로 떨어지는 장면을 묘사하려 합니다 :)
아래 URL에서 먼저 확인해보실 수 있습니다.
http://dreamplan7.cafe24.com/canvas/cray02.php
먼저 크레이가 준비한 소스 공개합니다.
역시 기본적인 웹페이지는 꾸며서 볼 수 있다는 전제하에 진행됩니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>캔바스 샘플#2</title>
</head>
<body>
https://blog.naver.com/ephraimdrlee
/ 크레이의 세컨드라이프 탐구생활 네이버 블로그<br/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
// 기본 초기화
var init=false;
var myCanvas;
var Context;
// 떨어질 눈의 갯수
var snow_max = 150;
var snow=Array();
// 초기화
function Init()
{
if(init==false)
{
myCanvas=document.getElementById("MyCanvas");
Context=myCanvas.getContext("2d");
for(i=0;i<snow_max;++i)
{
var obj=new Object();
obj.x=Math.random()*myCanvas.width;
obj.y=Math.random()*myCanvas.height;
obj.size=Math.sqrt(Math.random()*100)+1;
obj.alpha=Math.random();
snow.push(obj);
}
init=true;
}
}
// draw 이벤트
function onDraw()
{
if(init==false)return;
Context.fillStyle="#000";
Context.fillRect(0, 0, myCanvas.width-1, myCanvas.height-1);
for(i=0;i<snow_max;++i)
{
Context.beginPath(); //
Context.moveTo(snow[i].x, snow[i].y);
Context.fillStyle = // 채울색상, 투명도
'rgba(255,255,255,' + snow[i].alpha + ')';
Context.arc(
snow[i].x, // 가로좌표
snow[i].y, // 세로좌표
snow[i].size, // 원 크기
0, // 원호의 시작
Math.PI * 2 // 원호의 끝
);
Context.closePath();
Context.fill();
}
Context.filter = "none";
}
function Run()
{
for(i=0;i<snow_max;++i)
{
snow[i].y+=snow[i].size*0.2;
if(snow[i].y>=myCanvas.height)snow[i].y=-10;
}
onDraw();
}
$(document).ready(function(){
Init();
setInterval(Run, 20);
});
</script>
<canvas id="MyCanvas" width=800 height=600>
Canvas is not supported.
</canvas>
</body>
</html>
문서 로딩이 끝나면 Init()함수로 초기화,
setInterval 로 Run 함수를 지속실행하는 부분은 지난 소개 부분과 동일합니다.
이번에 핵심적인 부분은 초기화할 때 객체를 생성하는 부분인데요.
여러개의 눈을 사용할거니까 전역변수에서는 snow 라는 이름의 배열을 생성해 놓습니다.
// 떨어질 눈의 갯수
var snow_max = 150;
var snow=Array();
그리고 초기화 할때 객체를 생성해서 배열에 집어 넣습니다.
// 초기화
function Init()
{
if(init==false)
{
myCanvas=document.getElementById("MyCanvas");
Context=myCanvas.getContext("2d");
for(i=0;i<snow_max;++i)
{
var obj=new Object();
obj.x=Math.random()*myCanvas.width;
obj.y=Math.random()*myCanvas.height;
obj.size=Math.sqrt(Math.random()*100)+1;
obj.alpha=Math.random();
snow.push(obj);
}
init=true;
}
}
객체를 생성하는 부분은 이 부분입니다.
var obj=new Object();
그리고 객체에 속성을 미리 추가해놓는데,
자바스크립트에서는 속성을 미리 정의할 필요가 없습니다.
그냥 점(.)기호화 함께 새로운 명칭을 써서 정의해주면 바로 속성이 되지요
obj.x=Math.random()*myCanvas.width;
obj.y=Math.random()*myCanvas.height;
obj.size=Math.sqrt(Math.random()*100)+1;
obj.alpha=Math.random();
참고로 Math.random() 함수는 0부터 0.99999999.... 의 난수를 발생합니다.
난수란 무엇일까요? 그 때 그때마다 컴퓨터가 마음먹은대로 발생하는 수입니다.
그 수의 범위가 0~1 사이니까
여기에 100을 곱하면 0~100이 되고,
여기에 1000을 곱하면 0~1000이 됩니다.
눈덩이 1개의 x좌표와 y좌표, 크기와 투명도를 정해줍니다.
투명도는 범위가 0~1까지이면 되므로 따로 곱해주지 않아도 되지요.
그 다음으로 생성한 눈덩이 객체 1개를 눈배열에 집어 넣습니다.
snow.push(obj);
여기까지는 그냥 150개의 눈덩이의 속성을 논리적으로만 정의해준 것이지 아직 화면에 보이는 부분은 없습니다.
이제 Run() 함수로 가볼까요?
이 함수는 0.02초마다 호출됩니다.
function Run()
{
for(i=0;i<snow_max;++i)
{
snow[i].y+=snow[i].size*0.2;
if(snow[i].y>=myCanvas.height)snow[i].y=-10;
}
사실 이 함수에서는 눈덩이가 떨어지는 부분을 시뮬레이션 해줍니다.
각 눈덩이는 이제 마치 작은 생명체와 같이 된 상태인데요.
자신의 x, y 위치와 투명도 크기 등의 정보를 가지고 있기 때문이지요.
눈덩이를 아래쪽으로 떨어뜨리려면 우선 논리적인 y좌표값을 증가시켜주면 됩니다.
그냥 눈덩이의 크기에 0.2를 곱하는 정도면 적당할 것 같습니다.
snow[i].y+=snow[i].size*0.2;
그리고 만일 눈덩이가 바닥까지 내려와 캔바스의 경계를 벗어나면 다시 위에서 떨어지도록 합니다.
if(snow[i].y>=myCanvas.height)snow[i].y=-10;
여기까지는 사실 눈덩이가 논리적으로 메모리에서만 지지고 볶고 한 것이지 화면에 보여준 것이 아닌데요.
onDraw() 함수에서 실제 보여지는 부분을 담당합니다.
// draw 이벤트
function onDraw()
{
if(init==false)return;
Context.fillStyle="#000";
Context.fillRect(0, 0, myCanvas.width-1, myCanvas.height-1);
for(i=0;i<snow_max;++i)
{
Context.beginPath(); //
Context.fillStyle = // 채울색상, 투명도
'rgba(255,255,255,' + snow[i].alpha + ')';
Context.arc(
snow[i].x, // 가로좌표
snow[i].y, // 세로좌표
snow[i].size, // 원 크기
0, // 원호의 시작
Math.PI * 2 // 원호의 끝
);
Context.closePath();
Context.fill();
}
Context.filter = "none";
}
먼저 배경을 검게 칠합니다.
Context.fillStyle="#000";
Context.fillRect(0, 0, myCanvas.width-1, myCanvas.height-1);
그 다음으로는 반복문을 실행하면서 각 눈덩이에 대한 작동을 하는데요.
for(i=0;i<snow_max;++i)
{
:
}
arc 라는 원호를 그리는 함수를 사용할 겁니다.
이 함수를 사용할때는 기본적으로 beginPath() 함수와 closePath() 함수를 병행해서 사용해야 하는데요. 보통은 beginPath(), 그리기 명령들, closePath() 를 사용하는 것이 순서입니다. 아울러 내부를 색칠로 채워야 할 경우는 fill() 명령어가 뒤에 따라 붙습니다.
Context.beginPath();
:
Context.closePath();
Context.fill();
beginPath() 다음으로 먼저 채울 색상을 정의한 다음
Context.beginPath();
Context.fillStyle = // 채울색상, 투명도
'rgba(255,255,255,' + snow[i].alpha + ')';
눈을 그려줍니다.
Context.arc(
snow[i].x, // 가로좌표
snow[i].y, // 세로좌표
snow[i].size, // 원 크기
0, // 원호의 시작
Math.PI * 2 // 원호의 끝
);
그러면 예쁜 눈이 하늘에서 숑숑숑~
수고하셨습니다~
다음강좌 보러가기 / https://itadventure.tistory.com/132
'자바스크립트와 캔버스' 카테고리의 다른 글
자바스크립트와 캔바스 4번째 시간. 마우스의 파동을 느껴봐! (2) | 2019.09.21 |
---|---|
자바스크립트와 캔버스 3번째 시간, 공튀기기 놀이 (4) | 2019.09.21 |
HTML 표준 CANVAS 기술 소개 (2) | 2019.09.20 |
jQuery 함수 ( prototype ) 추가 (1) | 2019.08.25 |
자바스크립트 일반메소드 vs 프로토타입 (0) | 2019.08.24 |