CraftyJS 라이브러리로 게임 개발 - 소개

소개

이 문서의 목적은 개발자가 CraftyJS 프레임워크에 친숙해지고 Tizen 애플리케이션에서 사용하는 방법을 설명하는 것입니다. 이러한 주제는 샘플 애플리케이션인 퀴즈 게임을 사용해서 설명합니다. CraftyJS-s 기본 사항을 다루는 시리즈의 첫 번째 문서입니다. 프레임워크의 구조, 장면 및 엔터티/구성 요소 시스템을 설명합니다. 그런 다음 스프라이트 작업 방법과 간단한 엔터티를 생성하는 방법을 보여줍니다. 끝으로 몇 가지 기본 애니메이션이 나옵니다.

Crafty

CraftyJS는 최근에 활발하게 개발된 JavaScript HTML5 게임 엔진입니다. MIT 또는 GPL 라이센스 하에 배포되는 오픈 소스입니다. 비교적 쉽게 사용할 수 있습니다. 작은 라이브러리 파일 하나만 프로젝트에 포함시켜야 합니다. 호환되는 교차 브라우저이며 Tizen에서도 잘 작동합니다. Crafty는 기존 상속 시스템 대신 엔터티 구성 요소 시스템을 기반으로 합니다. 재사용 가능한 구성 요소를 쉽게 만들 수 있으며 DOM 또는 캔버스를 사용하여 렌더링을 수행할 수 있습니다. 또한 Crafty는 스프라이트, 자산 로드 및 오디오를 처리하는 도구를 제공합니다.
이 문서에서는 이러한 모든 기능을 사용하여 빠르고 쉽게 Tizen에서 만드는 JaveScrip 게임을 만드는 방법을 설명합니다. 이 문서에서는 주로 스프라이트 시트 및 애니메이션을 사용하여 세련된 UI를 만드는 방법을 설명합니다.

자세히 알아보려면 이 프레젠테이션, JavaScript와 Crafty로 게임 만들기 자습서 또는 공식 자습서를 참조할 수 있습니다. 공식 문서는 http://craftyjs.com/api/에서 확인할 수 있습니다. 라이브러리의 코드는 매우 읽기 쉽고 설명이 잘 되어 있어 자세히 살펴보는 것도 좋습니다.

샘플 애플리케이션 및 필수 구성 요소

퀴즈라고 하는 샘플 게임은 CraftyJS 프레임워크 사용을 보여주기 위해 제공됩니다. 게임의 목표는 제한 시간 내에 모든 질문에 올바르게 대답하는 것입니다. 가로 모드에서 작동합니다. 샘플 애플리케이션은 직관적이고 일관된 사용자 인터페이스와 확장성이 높은 웹 애플리케이션을 만들 수 있는 jQuery Mobile 1.2.0 프레임워크를 기반으로 합니다. JQuery Mobile을 사용할 수 있으려면 애플리케이션에 jQuery 라이브러리가 포함되어 있어야 합니다.

퀴즈 게임그림 1 퀴즈 게임

코드 샘플은 사용자 지정 함수를 사용하여 콘솔에 로그 메시지를 보냅니다. 애플리케이션의 js/lib/tlib 폴더에서 찾을 수 있습니다.

프로젝트에 Crafty 추가

다음 사이트에서 최신 Crafty 라이브러리를 다운로드할 수 있습니다.
- 공식 사이트(http://craftyjs.com)
- Github의 Crafty 소스(https://github.com/craftyjs/Crafty).

Tizen 프로젝트에 Crafty를 추가하려면 crafty.js 파일을 리소스에 복사하고 index.html 파일에 추가하기만 하면 됩니다.

그런 다음 Crafty.init() 함수로 Crafty를 초기화해야 합니다.

// init Crafty
Crafty.init(this.config.width, this.config.height);
두 개의 매개 변수(스테이지 너비 및 높이)를 사용합니다. 스테이지는 Crafty 요소를 배치할 수 있는 화면의 일부입니다. 이 경우에는 전체 화면입니다. this.config.width 및 this.config.height 값은 각각 화면 너비와 높이입니다. 캔버스에 그리려면 초기화해야 합니다.
Crafty.canvas.init();

장면

장면은 개체를 구성하는 방법입니다. 게임의 고유한 부분을 나타냅니다. 이들은 다른 화면 또는 수준일 수 있습니다. 퀴즈 게임에는 메뉴(주 메뉴 표시), 옵션(설정 게임 옵션), 정보, 도움말, 실제 게임을 포함한 주요 게임 장면 등의 장면이 있습니다.

장면을 실행하기 위해 수행해야 하는 작업은 코드에서 Crafty.scene(scene) 함수를 호출하는 것입니다. 한 개의 인수(장면의 이름)만 사용합니다.

Crafty.scene("menu");

장면을 호출하면 현재 표시된 모든 엔터티를 삭제합니다.

다음과 같은 방법으로 장면을 정의할 수 있습니다.

Crafty.scene("menu", function() {
    // define game objects here
});

각 장면을 별도 파일에 정의하는 것이 좋습니다. 애플리케이션을 모듈식으로 설정하고 더욱 쉬워질 수 있습니다.

모든 장면에 일반적인 애플리케이션에 대한 배경을 정의할 수 있습니다.

// set background
Crafty.background("url('images/game_bg.png')");

각 장면에 대한 별도 배경이 필요한 경우 각 장면 초기화에서 Carfty.background() 함수를 사용해야 합니다.

자산 로드

Crafty 라이브러리에서 제공된 자산에 대한 preloader 함수가 있습니다. url의 목록을 가져오고 afty.assets 개체에 추가합니다.

Crafty.load([ "images/quiz_sprite.png", "images/quiz_sprite_help.png",
        "sounds/game_correct.mp3" ],

        // on load finish
function() {
    Crafty.scene("menu"); // go to menu scene
},

// on load progress
function(e) {
    // do sth
},

// on error
function(e) {
    // do sth
});

Crafty.load() 메서드는 4개의 매개 변수를 사용합니다.

  • assets - 로드할 자산 배열. 사운드와 이미지일 수 있습니다.
  • onLoad - 자산이 로드되는 경우 콜백.
  • onProgress - 자산이 로드되는 경우 콜백. 로드의 진행 상황에 대한 정보와 함께 개체가 전달됩니다.
  • { loaded: j, total: total, percent: (j / total * 100), src:src}
  • onError - 자산이 로드에 실패하는 경우 콜백. 이 함수는 로드될 수 없는 자산에 전달됩니다. 이 콜백을 제공하지 않는 경우 onLoad 메서드는 자산 로드 여부에 관계없이 호출됩니다.

엔터티/구성 요소 시스템

개체 지향 프로그래밍은 매우 인기 있는 애플리케이션 코드 구성 방법입니다. 상위 클래스로부터 상속된 클래스 구조가 생성됩니다. Crafty의 방법은 조금 다릅니다. 엔터티/구성 요소 시스템을 사용합니다. 단일 수준의 다중 상속과 유사합니다. 2개의 주요 개념이 있습니다.
  • 엔터티 - 플레이어, 공 또는 애니메이션된 UI 항목과 같은 게임 개체. 이 개체의 단일 인스턴스입니다.
  • 구성 요소 - 추상적 개체 또는 함수/속성의 집합. 엔터티("상속됨")에 적용될 수 있습니다. 다시 사용할 수 있으며 단일 엔터티에는 여러 가지 다른 구성 요소로 구성될 수 있습니다.
아래 예제로 엔터티와 구성 요소 간의 관계에 대해 설명합니다.
var answerText = Crafty.e("2D, DOM, Text, Mouse");

answerText는 샘플 엔터티, 즉 화면에 표시된 텍스트입니다. "2D", "DOM", "텍스트", "마우스" 등 4개의 다른 구성 요소("에서 상속됨")로 구성되어 있습니다. 이러한 모든 구성 요소는 Crafty 엔진에서 사전 정의되었습니다. 선언에서 쉼표로 분리합니다. 엔터티로 작업하고 사용자 지정 구성 요소를 만드는 방법에 대한 설명은 나중에 나옵니다.

스프라이트 작업

많은 별도 이미지를 로드하면 애플리케이션의 성능 및 코드 가독성이 크게 손상될 수 있습니다. 많은 이미지 리소스, 특히 여러 가지 단일 개체의 애니메이션 스테이지를 나타내는 많은 리소스의 경우 스프라이트 시트를 만드는 것이 좋습니다.

퀴즈 스프라이트 시트 중 하나그림 2 퀴즈 스프라이트 시트 중 하나

Crafty는 스프라이트 시트 처리를 개선하기 위해 몇 가지 기본 제공 함수를 제공합니다. 스프라이트 맵을 개별 구성 요소에 연결하는 메서드입니다. 이러한 구성 요소는 2D 엔터티에 적용될 수 있습니다.
예를 살펴보겠습니다.

// load main sprite sheet
Crafty.sprite(5, "images/quiz_sprite.png", {
    // menu scene buttons
    startBtn : [ 0, 0, 74, 22 ],
    normalBtn : [ 0, 22, 74, 22 ],
    ...
});

Crafty에서 스프라이트 시트를 더 작은 요소, 즉 타일로 분할합니다. 타일은 사각형이며 스프라이트 시트는 단일 타일이 정확히 하나의 스프라이트에 속하는 방식으로 분할되어야 합니다. 아래 그림에서는 이러한 개념을 보여줍니다. 5개의 스프라이트(다른 색상)로 구성되고 15개의 타일로 분할된 스프라이트 시트를 보여줍니다.

타일로 분할된 예제 스프라이트 시트그림 3 타일로 분할된 예제 스프라이트 시트

Crafty.sprite() 함수는 3개의 인수를 사용합니다.

  • tile - 타일 크기(픽셀 단위). 기본값은 1입니다. 최상의 성능을 위해 스프라이트 시트에 가능한 가장 큰 타일 크기를 선택하십시오. 동일한 크기의 개체로 구성된 스프라이트 시트가 자주 있습니다. 사각형인 경우 완벽한 크기의 타일을 선택하는 것이 쉽습니다. 단일 사각형의 측면 길이입니다. When 다른 스프라이트의 크기와 셰이프가 다를 때 크기의 최대 공약수를 선택합니다. 샘플 퀴즈 게임의 경우 모든 스프라이트 크기는 5의 배수입니다.
  • url - 스프라이트 이미지에 대한 경로.
  • map - [key : position] 개체 배열. 위치는 스프라이트 시트에서 스프라이트의 왼쪽 상단 모서리에 있는 x 좌표, 스프라이트 시트에서 스프라이트의 왼쪽 상단 모서리에 있는 y 좌표, 스프라이트의 너비, 스프라이트의 높이 등 네 가지 값의 배열입니다. 이러한 모든 값의 단위는 픽셀이 아니라 타일입니다.

타일은 코드를 보다 쉽게 읽을 수 있도록 하는 데 사용됩니다. 특히 단일 스프라이트 시트의 스프라이트가 모두 똑같이 사각형일 때 잘 작동합니다. 언제든지 가능할 때 이 규칙에 적용되는 스프라이트 맵을 만드는 것이 좋습니다. 샘플 퀴즈 게임의 경우 여러 가지 크기의 다양한 스프라이트가 있으므로 타일을 사용하면 코드의 숫자를 더 작게 만듭니다. 값을 픽셀 단위로 제공하는 대신 타일을 사용합니다(여기서 1타일 = 5픽셀). 기본 타일 값 (1)과 함께 코드의 동일한 조각은 다음과 같습니다.

Crafty.sprite(1, "images/quiz_sprite.png", {
    // menu scene buttons
    startBtn : [ 0, 0, 370, 110 ],
    normalBtn : [ 0, 110, 370, 110 ],
    ...
});

스프라이트 시트가 로드되면 모든 스프라이트는 "키"에서 정의된 이름을 가진 엔터티가 됩니다. 즉 다음과 같이 엔터티 정의에서 사용할 수 있습니다.

varstartButton = Crafty.e("2D, DOM, startBtn").attr({
    x : 455,
    y : 225
});

위의 코드에서 엔터티, startButton이 생성됩니다. "2D", "DOM", "startBtn" 등 세 가지 구성 요소를 사용합니다. 스프라이트를 로드할 때 "startBtn" 구성 요소가 정의되었습니다. 속성 x 및 y를 설정하면 개체에 위치가 제공됩니다. 위의 코드는 화면에 "startBtn" 이미지를 보여줍니다.

엔터티

전에 언급했듯이 엔터티는 Crafty.e() 함수에 문자열로 전달된 여러 가지 다른 구성 요소로 구성되었습니다. 새 구성 요소를 엔터티에 추가함으로써 이러한 구성 요소의 함수도 추가할 수도 있습니다. 이 예를 살펴보겠습니다. 이 엔터티는 질문의 텍스트를 보여줍니다.

var questionText = Crafty.e("2D, DOM, Text").attr({
    w : 1170,
    h : 200,
    x : 55,
    y : 185
}).text("The country famous for Samba dance is?").textFont({
    size : '20px'
});

이 개체를 정의하는 데 사용된 체인이 JQuery 스타일과 유사하다는 것을 볼 수 있습니다. 대부분의 Crafty 요소가 지원합니다. attr() 함수는 "2D" 구성 요소용이며 text() 함수 및 textFont() 함수는 "텍스트" 구성 요소용입니다. 구성 요소의 문서에서 사용할 수 있는 메서드의 전체 목록을 볼 수 있습니다. 여기서 일부만 설명하겠습니다.

Attr() 함수로 2D 요소의 기본 속성을 설정할 수 있습니다.

  • x - 스테이지의 수평 위치
  • y - 스테이지의 수직 위치
  • w - 너비
  • h - 높이
  • alpha - 엔터티 투명도(0: 완전 투명, 1: 완전 불투명)
  • rotation - 엔터티 회전(도 단위로 시계 방향으로 회전)
  • visible - 엔터티가 표시되는지 여부(true/false)

체인도 생략할 수 있습니다. 빈 엔터티를 만들고 나중에 일부 구성 요소를 추가할 수 있습니다.

var questionText = Crafty.e();
questionText.addComponent("2D, DOM, Text");

questionText.attr({
    w : 1170,
    h : 200,
    x : 55,
    y : 185
});
questionText.text("The country famous for Samba dance is?");

questionText.textFont({
    size : '20px'
});

이제 다양한 구성 요소에 기반한 엔터티를 만드는 방법을 이해해야 합니다. 사용자 지정 구성 요소 생성에 대한 설명은 나중에 나옵니다.

트윈 애니메이션

트윈은 가장 간단한 애니메이션 중 하나입니다. Crafty에서 구성 요소로 정의됩니다. 일정 기간 동안 2D 엔터티의 속성을 애니메이션할 수 있습니다. 변경할 수 있는 속성은 x, y, w, h, alpha, rotation입니다.

Crafty.e("2D, DOM, Tween").attr({
    x : 0,
    y : 0
}).tween({
    x : 100,
    y : 100
}, 60).bind("TweenEnd", function() {
    // todo
});

위의 예제에는 간단한 트윈 애니메이션을 만드는 방법을 보여줍니다. 수행해야 하는 작업은 "Tween" 구성 요소를 엔터티에 추가하고 일부 2D 속성을 설정하며 tween() 함수를 사용 하여 일정 시간 동안 변경하는 것입니다. tween() 함수는 두 개의 매개 변수를 사용합니다.

  • properties - 변경할 개체 속성(최종 값 포함),
  • duration - 애니메이션 기간(프레임 수)

애니메이션이 끝날 때 트리거되는 이벤트 수신기를 추가할 수도 있습니다. bind() 함수는 두 개의 매개 변수를 사용합니다.

  • 이벤트 유형(여기서는 "TweenEnd")
  • 트리거될 함수

이 이벤트 수신기로 하나의 트윈이 끝날 때 다른 트윈이 시작되는 트윈 체인을 생성할 수 있습니다. 예로 이것을 설명합니다.
퀴즈 애플리케이션에서 주 메뉴 타일이 화면 상단에서 떨어집니다. 위에서 천천히 나타나 미끄러져 내려가고 펄쩍 뛰어오른 후 다시 아래로 떨어집니다. 아래 그림에 나와 있습니다.

타일 트윈 애니메이션의 단계그림 4 제목 트윈 애니메이션의 단계

이렇게 하려면 다음 코드를 사용합니다.

Crafty.e("2D, DOM, gameTitle, Tween").attr({
    x : 295,
    y : 0
}).tween({
    y : 65
}, 60).bind("TweenEnd", function() {
    this.unbind("TweenEnd");
    this.tween({
        y : 55
    }, 20);
    this.bind("TweenEnd", function() {
        this.tween({
            y : 65,
        }, 20);
    });
});

예를 들어 트윈 애니메이션은 제목의 세로 위치만 변경합니다. 또한 추가된 그래픽으로 "gameTitle" 구성 요소를 주목할 수 있습니다. 이 구성 요소는 게임 타이틀 스프라이트를 나타내고 스프라이트 시트를 로드할 때 Crafty.sprite() 메서드에 의해 생성되었습니다.

스프라이트 애니메이션

스프라이트 애니메이션은 애니메이션의 또 다른 유형입니다. 애니메이션의 다른 단계는 스프라이트 시트에 별도 이미지로 저장됩니다. 스프라이트의 너비가 동일할 때 특히 효율적입니다.

예제 스프라이트 시트그림 5 예제 스프라이트 시트

사각형 1-5는 애니메이션의 프레임이며 각 사각형의 측면 길이가 10픽셀이라 가정해 보겠습니다. 프레임 번호 1부터 2, 3, 4, 5까지 개체를 애니메이션하려고 합니다. 우선, 그림 5에 나온 스프라이트를 로드합니다. 이미 알다시피, Crafty.sprite() 메서드를 사용하여 수행합니다.

Crafty.sprite(10, "sprite.png", {
    object : [ 0, 0 ]
});

타일 크기로 10을 사용해야 합니다. 이제 애니메이션으로 엔터티를 정의할 수 있습니다. "SpriteAnimation" 구성 요소를 사용해야 합니다.

var player = Crafty.e("2D, DOM, object, SpriteAnimation").attr({
    x : 0,
    y : 0
}).animate("anim", 0, 0, 4); // setup animation

애니메이션을 설정하기 위한 animate() 함수는 4개의 매개 변수를 사용합니다.

  • id - 애니메이션의 이름
  • formX - 스프라이트 맵의 수평 위치 시작(타일 단위)
  • y - 스프라이트 맵의 수직 위치(타일 단위)
  • toX - 최종 수평 위치(타일 단위)

y 위치는 애니메이션을 통해 일정하게 유지됩니다. 변경해야 하는 경우 나중에 설명될 메서드를 사용해야 합니다.
애니메이션이 설정되었으므로 3개의 인수를 포함한 animate() 함수를 사용하여 실행할 수 있습니다.

  • id - 애니메이션 id
  • duration - 전체 애니메이션의 지속 시간(프레임 단위)
  • repeatCount - 애니메이션을 반복하는 횟수
player.animate('PlayerRunning', 15, 0); // play animation once
player.animate('PlayerRunning', 15, -1); // play animation infinitely

애니메이션을 무한 재생하면 게임에서 캐릭터가 항상(예: 실행 중인 경우) 움직여야 할 때 매우 유용합니다. stop() 및 reset() 등 애니메이션을 처리하기 위한 몇 가지 추가 함수가 있습니다.

player.stop(); //stop all entity's animiations
player.reset(); //reset all entity's animations

애니메이션이 현재 재생 중인지 확인하려면 isPlaying() 함수를 사용합니다.

player.isPlaying("anim"); //check if the animation if currently playing

빈 매개 변수로 호출하는 경우 재생 중인 애니메이션이 있는지 여부를 확인합니다.

이전 단락에서 나온 메서드는 애니메이션 프레임 너비가 동일하며 스프라이트 맵의 한 행에 배치될 때 매우 효율적이고 구성하기 쉽습니다. 그렇지 않은 경우 각 프레임의 좌표를 별도로 전달해야 합니다.

button.animate("blink", [ [ 222, 50 ], [ 222, 75 ], [ 222, 50 ], [ 222, 75 ], [ 222, 50 ], [ 222, 75 ] ]);

위의 코드에서 정의된 애니메이션이 세 번 깜박입니다. 다음 문서에서 이러한 애니메이션 유형에 대한 자세한 내용을 확인할 수 있습니다.

요약

이 문서에서 CraftyJS 프레임워크 및 Tizen 애플리케이션에서 사용하는 방법이 소개되었습니다. 화면 및 엔터티/구성 요소 시스템을 포함하여 프레임워크의 구조를 설명했습니다. 스프라이트를 사용하여 작동하는 방법과 간단한 엔터티를 생성하는 방법을 설명했습니다. 끝 부분에는 몇 가지 기본 애니메이션이 소개되었습니다. Tizen의 Crafty를 사용한 작업에 대해 자세히 알아보려면 시리즈의 다음 문서인 "CraftyJS 라이브러리 작업 - 추가 작업"을 참조하십시오.

첨부 파일: