Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

heenam

11. 자바스크립트와 캔버스로 게임 만들기 본문

Wep Programming/JavaScript

11. 자바스크립트와 캔버스로 게임 만들기

znzltiq 2020. 7. 16. 02:32

캔버스 요소

 캔버스 생성

  캔버스는 <canvas> 요소로 생성된다. 캔버스는 HTML 페이지 상에서 사각 형태의 영역이다.

  <canvas> 요소는 디폴트 값으로 경계를 가지지 않는다. <canvas> 요소는 단순히 그래픽을 위한 컨테이너이다.

  실제 그림은 자바스크립트를 통하여 코드로 그려야 한다.

<canvas id="myCanvas" width="300" height="100"></canvas>

  항상 id 속성을 지정해야 한다. 왜냐하면 id속성이 있어야 자바스크립트에서 참조할 수 있다.

  또 가로와 세로 크기도 꼭 설정하도록 하자. 경계를 추가하려면 style 속성을 사용한다.

<canvas id="myCanvas" width="300" height="100"
	style="border:1px dotted red;">
</canvas>

 캔버스 좌표계

  캔버스는 픽셀이 들어 있는 2차원 그리드이다. 캔버스 좌측 상단의 좌표가(0.0)이다.

  우측 하단의 좌표는 캔버스의 크기에 따라서 결정된다.

 콘텍스트 객체

  자바스크립트에서 물감과 붓을 모아놓은 객체가 있다. 바로 컨텍스트객체 이다.

  컨텍스트 객체는 캔버스에서 다음과 같이 얻을 수 있다.

var canvas = document.getElementById("myCanvas"); <- 먼저 캔버스 요소를 찾는다.
var context = canvas.getContext("2d"); <- 캔버스에서 컨텍스트를 얻는다.

 간단한 그림 그리기

  웹 페이지 위에 캔버스 요소를 생성하고 캔버스에 녹색의 사각형을 그리는 예제를 살펴보면서 그림을 그리는 기본적인

  구조에 대하여 살펴보자.

<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <canvas id="myCanvas" width="200" height="100"
            style="border: 1px dotted red"></canvas> <-요소를 정의 한다.
        <script>
            var canvas = document.getElementById("myCanvas"); <- 먼저 캔버스 요소를 찾는다.
            var context = canvas.getContext("2d"); <- 캔버스에서 컨텍스트를 얻는다.
            context.fillStyle = "yellow";
            context.fillRect(0, 0, 100, 50); <- 캔버스 위에 사각형을 그린다.
        </script>
    </body>
</html>

 직선 그리기

  캔버스에는 직선, 경로, 곡선, 사각형, 원, 이미지, 텍스트를 그릴 수 있다. 

  캔버스에 직선을 그리기 위해 다음의 2가지 메서드를 사용한다.

  + moveTo(x, y)는 직선의 시작점을 정의한다.

  + lineTo(x, y)는 직선의 끝점을 정의한다.

  경로를 형성해서 그릴 때는 마지막에 항상 stroke()을 호출해 주어야 그림이 실제로 그려진다. 

 사각형 그리기

  사각형을 캔버스에 그리려면 rect() 메서드를 이용하면 된다.

  + rect(x, y, w, h)는 (x, y)를 왼쪽 모서리로 하고 가로와 세로 각각 w, h인 사각형을 그린다.

  만약 채워진 사격형을 그리고 싶으면 stroke() 대신에 fill()을 호출하면 된다.

 원 그리기

  캔버스에 원을 그리기 위해서는 다음의 메서드를 사용한다.

  + arc(x, y, radius, starAngle, endAngle, antiClockwise) - (x, y)를 중심으로 하여 반지름이 radius인 원을 그린다.

     start는 시작 각도이고 end는 종료 각도이다.

  arc() 메서드에서 각도는 상수 PI를 이용하여 앞의 그림처럼 표시한다. 원은 startAngle에서 endAngle까지만 그려진다.

  antiClockwise는 반시계 방향인지 아니면 시계 방향인지를 true와 false를 이용하여 나타낸다.

  원호를 그린 후에 시작점과 종료점을 연결하여 그리고 싶으면 closePath()를 호출한다.

  closePath()는 경로를 닫게 된다.

 곡선 그리기

  베지어 곡선 같은 3차 곡선도 그릴 수 있다. 베지어 곡석은 4개의 제어점 안에 그려지는 3차 곡선이다.

 일반적인 도형 그리기

  일반적인 도형은 경로(path)를 형성해서 그리면 된다. 경로는 beginPath() 호출에서 시작해 closePath() 호출에서 종료

  된다.

  beginPath()를 호출한 후 moveTo(), lineTo(), quadricCurveTo(), bezierCurveTo(), arcTo(), arc()를 호출해서 경로를 실제

  로 생성한다. 경로가 생성된 후에는 closePath()를 호출해서 경로를 닫고 stroke()을 호출하여 경로의 외곽선을 그리거

  나 fill()을 호출하여 경로 안을 채워서 그리면 된다.

 텍스트 그리기

  캔버스에 텍스트를 그리기 위해서는 다음과 같은 속성과 메서드를 사용한다.

  + font: 텍스트를 그리는데 사용되는 폰트 속성을 정의한다.

  + fillText(text, x, y): 캔버스에 채워진 텍스트를 그린다.

  + stroKeText(text, x, y): 캔버스에 텍스트의 외곽선만을 그린다.

도형의 속성

 선 그리기 속성

  선을 그릴 때도 여러 가지 속성을 지정할 수 있다.

  + context.lineWidth: 선의 두께를 지정한다.

  + context.strokeStyle: 선의 색상을 지정한다.

  + context.lineCap: 선의 양쪽 끝점의 모양을 지정한다.

                           butt, round, square 중의 하나이다.

 도형 채우기

  도형의 내부는 단일 색상, 그라디언트, 패턴 등을 채울 수 있다.

  단일 색상으로 채우기

  단일 색상으로 채우려면 다음과 같이 컨텍스트의 fillStyle을 설정하면 된다.

context.fillStyle = 'red';

  그라이언트로 채우기

  그라이언트도 사각형이나 원, 텍스트를 채우는 데 사용할 수 있다.

  2가지 종류의 그라이언트가 존재한다.

  + createLinearGradient(x, y, x1, y1) - 선형 그라디언트를 생성한다.

  + createRadialGradient(x, y, r, x1, y1, r1) - 원형 그라디언트를 생성한다.

  그라디언트 객체가 생성되면 거기에다가 2개 이상의 종료 색상을 반드시 추가해야 한다.

  addColorStop() 메서드는 종료 색상과 위치를 지정한다. 그리디언트 위치는 0과 1 사이의 실수로 지정된다.

  그라디언트를 사용하려면 fillStyle 속성이나 strokeStyle 속성을 그라디언트 객체로 지정하고 도형을 그리면 된다.

  원형 그라디언트를 사용하는 예제는 다음과 같다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <canvas id="myCanvas" width="300" height="300"></canvas>
        <script>
            var canvas = document.getElementById('myCanvas');
            var context  = canvas.getContext('2d');

                                                       (x,  y,  z, x1,  y1, z1) 							
            var gradient = context.createRadialGradient(70, 50, 10, 80, 60, 120);
            gradient.addColorStop(0, "white");
            gradient.addColorStop(1, "red");

            context. fillStyle = gradient;
            context.fillRect(10, 10, 180, 90);
        </script>
    </body>
</html>

  패턴으로 채우기

  패턴으로 캔버스를 채우기 위해서는 먼저 reatePattern()을 이용해 패턴 객체를 생성한다. 다음으로 컨택스트의 fillStyle

  속성을 패턴 객체로 설정한다. 최종적으로 fill() 메서드를 호출해서 도형의 내부를 패턴으로 채우면 된다.

  createPattern() 메서드는 이미지 객체와 repeat 옵션을 요구한다. repeat 옵션은 "repeat", "repeat-x", "repeat-y",

  "no-repeat" 중의 하나가 될 수 있다. 지정되지 않으면 repeat 옵션은 디폴트로 "repeat"로 설정된다. 즉 x, y 방향으로 

  모두 반복하라는 의미가 된다.

 이미지 그리기

  캔버스에 이미지를 그리기 위해 다음의 메서드를 사용한다.

  +drawImage(image, x, y) - 화면 (x, y) 위치에 이미지를 그린다.

 

  이미지를 캔버스에 그리기 위해서는 drawImage() 메서드를 사용한다. drawImage()는 image 객체와 좌표를 필요로 한

  다. 좌표는 이미지의 좌측 상단이 위치하는 곳이다.

 

  drawImage() 메서드가 객체를 요구하기  때문에 우리는 먼저 image 객체를 생성한 후에 drawImage()를 호출하기 전에

  이미지가 로드되기를 기다린다. 이것은 image 객체의 onload 속성을 이용하면 된다.

도형 변환

  HTML5에서는 기본적인 2차원 변환인 평행이동, 신축, 회전을 비롯한 모든 변환을 지원한다. 밀림, 반사와 같은 추가적

  인 변환도 지원된다. 일반적으로는 행렬을 이용해 자신이 원하는 변환을 생성하여 적용할 수도 있다.

 평행이동

  Canvas 클래스의 translate() 메서드는 캔버스 좌표 공간의 원점을 평행 이동한다.

  통상적으로 그래픽스에서 평행이동과 같은 모든 변환은 내부적으로 행렬을 사용한다.

  (x, y) 좌표에 1을 추가한 동차 좌표를 만든 후에 다음과 같은 행렬식을 이용해 변환된 좌표를 계산한다.

                       ┌ 1  0  0 ┐

  [x' y' 1] = [x y 1]│ 0  1  0 │

                       └ Tx Ty 1 ┘

 회전

  좌표 공간을 회전시키려면 rotate()를 사용한다. rotate(float degree)는 (0, 0)을 기준으로 좌표 공간을 회전시킨다.

  만약 다른 위치를 기준으로 회전시키려면 rotate(float degree, float px, float py)를 사용한다.

  (px, py)가 회전의 중심점이 된다.

 신축

  캔버스와 신축 비율을 설정하려면 scale() 메서드를 사용한다.

 일반 변환

  기본적인 변환 이외의 일반적인 변환은 직접 변환 행렬의 값을 지정하면 된다. transform() 메서드를 사용하고 매개 변

  수 a에서 f까지를 직접 설정하면 된다.

애니메이션

  캔버스를 만들고 여기에 자바스크립트로 그림을 순차적으로 그려주는 것이다.

 Bouncing Ball 예제

  사각형 안에서 반사되면서 움직이는 공은 아주 기본적인 애니메이션 예제이다. 

  애니메이션을 작성하는 순서는 어디서나 항상 동일하다.

  1. 캔버스를 지운다

  2. (x, y) 위치에 그림을 그린다.

  3. 위치를 업데이트 한다.

  4. 위의 절차 (1부터 3까지)를 반복한다.

  각 단계를 어떻게 구현할 것인지를 생각하면서 코드를 작성하여 보자.

 STEP #1 캔버스 지우기

  HTML5 캔버스를 지우기 위해서는 clearRect() 메서드를 사용하면 된다. 이 방법은 다른 방법보다 훨씬 빠르다.

context.clearRect(0, 0, 300, 200);

  캔버스를 지우지 않으면 이전 그림이 남아있어서 현재 그림과 동시에 보이게 된다.

 STEP #2 캔버스에 그림 그리기

  웹 페이지 안에 캔버스 요소를 생성하고 여기에 자바스크립트로 그림을 그리면 된다.

context.beginPath();
context.fillStyle = "red";
context.arc(x, y, 20, 0, Math.PI*2, true);
context.closePath();
context.fill();

  그림을 그리기 전에 반드시 beginPath()를 호출해 주어야 한다. fill()을 호출하면 모든 경로를 전부 칠하게 되는데 

  beginPath()를 호출하지 않으며 경로가 초기화되지 않아서 이전 경로까지 모두 칠해지게 된다.

 STEP #3 위치를 업데이트 하기

  애니메이션은 근본적으로 무엇인가가 시간에 따라서 변화되는 것이다. 일반적으로 도형의 위치나 크기가 변경된다.

  여기서는 볼의 위치를 변화시키도록 하자. 볼의 위치는 (x, y) 변수에 저자오디어 있다. 따라서 (x, y)를 적절하게 변경시

  키면 된다.

x += dx;
y += dy;

  여기서는 dx, dy는 볼이 한 번에 움직이는 거리로서 5로 초기화되어 있다.

  바운드되는 볼을 만들려면 볼이 벽에 부딪치면 반사되도록 해야 한다. 이것은 x, y위치가 벽에 닿으면 dx, dy를 반전하

  면 된다. dx, dy가 반전되면 움직이는 방향이 반대로 될 것이다.

  따라서 위의 코드 앞에 반사시키는 코드를 추가해야 한다.

if (x < (0+20) || x > (300-20))
	dx = -dx;
if (y < (0+20) || x > (200-20))
	dy = -dy;
x += dx;
y += dy;

 STEP #4 위의 절차를 반복하기

  모든 애니메이션은 반복해야 한다.

setInterval(doSomething, 10); // 매 10밀리초마다 doSomething()을 호출한다.
setTimeout(doSomething, 10); // 10밀리초 뒤에 doSomething()을 호출한다.