본문 바로가기
자바스크립트&캔버스

자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자

1. HTML 표준 CANVAS 기술 소개 / https://itadventure.tistory.com/130

◐ 2. 자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자 ◑

 

어릴 때 오락실에서 비행기 게임을 해본 적이 있다면,

수많은 적의 비행기와 총탄들이 자연스럽게 동시에 움직이는 것을 볼 수 있는데요.

크레이는 이제 평화주의인지라 전쟁과 관련된 것을 만들기는 싫고,

겨울에 내리는 눈송이들이 각각 속도와 크기, 속도(크기에 좌우됨) 등의 정보를 가지고 하늘에서 땅으로 떨어지는 장면을 묘사하려 합니다 :)

아래 URL에서 먼저 확인해보실 수 있습니다.
http://dreamplan7.cafe24.com/canvas/cray02.php

 

캔바스 샘플#2

 

dreamplan7.cafe24.com

먼저 크레이가 준비한 소스 공개합니다.

역시 기본적인 웹페이지는 꾸며서 볼 수 있다는 전제하에 진행됩니다.

<!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

 

자바스크립트와 캔버스 3번째 시간, 공튀기기 놀이

자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자 1. HTML 표준 CANVAS 기술 소개 / https://itadventure.tistory.com/130 2. 자바스크립트와 CANVAS 두번째시간. 캔바스에 눈을 내리자 / https://itadve..

itadventure.tistory.com