TM.IProgram

소스 코드 보기: https://github.com/a-mean-blogger/text-game-maker-js/blob/master/src/base-objects/i-program.js

타입

인터페이스 클라스(TM.ILoopObject를 상속받음)

**클라스의 역할이 인터페이스라는 뜻으로 자바스크립트에는 실제로 인터페이스 클라스가 없습니다. 코드 작성시 이 클라스를 직접 사용하지 않고 이 클라스를 상속받는 새로운 클라스를 만들어 사용합니다.

용도

TM.IObject나 TM.ILoopObject을 상속받은 클라스로 부터 생성된 인스턴스들을 모아서 관리하는 클라스입니다.

사이클

생성생성자에 의해 인스턴스가 생성됩니다.
활성화init 함수로 활성화가 됩니다. 반복이 시작됩니다.
반복calculatecalculate 함수를 실행합니다.
drawdraw 함수를 실행합니다.
timelinetimeline 함수를 실행합니다.
getInputgetInput 함수를 실행합니다.
비활성화inactivate 함수로 비활성화가 됩니다. 반복이 중지됩니다.

생성자 인자들

new TM.IProgram(speed, data, objects)
  • speed: 반복되는 함수들을 호출하는 속도를 숫자(단위: millisecond)로 받습니다. 즉, 숫자가 작을 수록 반복이 빠릅니다.
  • data(옵션): 클라스에서 사용되는 데이터들을 object 형태로 받습니다(예 {x:1,y:2}). 전달받은 data는 this.data에 저장됩니다.
  • objects(옵션): 클라스에서 관리하게 될 TM.IObject나 TM.ILoopObject 타입의 인스턴스들이나 그 구조를 object 형태로 받습니다(예 { player: player, enemies: [] }). 전달받은 objects는 this.objects에 저장됩니다.

항목들

  • isActive: init 함수가 실행되면 true(활성화 상태)가 되고 inactivate 함수가 실행되면 false(비활성화 상태)가 됩니다. 현재 활성화/비활성화 상태를 확인할 수 있는 항목입니다.
    **비활성화가 되었다고 해서 해당 인스턴스를 사용할 수 없는 것이 아닙니다. 활성화(this.isActive == true)일 때 행동와 비활성화(this.isActive == false)일 때 행동의 차이가 필요한 함수들은 이 값을 참조하여 직접 그 행동들을 만들어 주어야 합니다.
  • speed: init함수가 실행되면 이 값(단위: millisecond)을 간격으로 해서 반복 사이클의 함수들이 실행됩니다.
  • interval: TM.Interval의 인스턴스로 반복을 조정합니다.
  • objects: TM.IProgram에서 관리하게 될 인스턴스들을 넣는 항목입니다. 인스턴스를 하위 object로 넣거나, 인스턴스들의 배열을 하위 object로 넣습니다. 아래 예제를 참고해 주세요.
  • loopCount: init 함수가 실행되면 0이되며 활성화 도중 반복이 될 때마다 숫자가 1씩 증가합니다.

함수들

  • init(): 인스턴스를 활성화 상태로 만듭니다. TM.IProgam의 인스턴스들은 생성될 때 init을 자동으로 호출하지 않습니다. 이 함수를 직접 호출하여 활성화시켜주어야 합니다.
  • inactivate(): 인스턴스를 비활성화 상태로 만들고 반복을 멈춥니다. init함수를 호출하여 다시 활성화시킬 수 있습니다.
  • calculate(): 인스턴스가 활성화 상태일 때 반복하여 실행됩니다. this.data의 값을 변경하는 함수입니다.
  • draw(): 인스턴스가 활성화 상태일 때 반복하여 실행됩니다. this.data의 값을 바탕으로 화면에 텍스트를 그리는 함수입니다.
  • timeline(loopCount): 인스턴스가 활성화 상태일 때 계속하여 실행됩니다. 자동으로 this.loopCount가 인자로 들어오며, 이를 통해 현재 몇번째 반복이 실행되는지 알 수 있습니다. 반복 횟수에 따라(시간의 지연에 따라) 해야할 일을 가지는 함수입니다.
  • getInput(): 인스턴스가 활성화 상태일 때 계속하여 실행됩니다. 사용자의 입력을 확인하는 코드를 가집니다.

calculate, draw, timeline, getInput은 그 근본이 다른 것이 아니라 this.speed를 간격으로 반복하는 빈 함수입니다. 역할에 따라 코드를 분리하여 코딩을 알아보기 쉽게 하는 것이 목적입니다.

함수의 상속(확장)

TM.IProgram를 상속할 때 위 함수들의 코드는 해당 함수를 직접 상속받아 작성하지 말고 아래의 함수들(_가 붙어있는 함수들)에 코드를 작성하여야 합니다. 아래 함수들에 코드를 작성하면 _가 없는 함수를 호출하면 _가 있는 함수가 자동으로 실행됩니다.

  • _init(): 인스턴스가 활성화 될 때 해야할 일을 작성합니다.(예: 게임 테두리를 화면에 그림)
  • _inactivate(): 인스턴스가 비활성화 될 때 해야할 일을 작성합니다.(예: 게임 테두리를 화면에서 지움)
  • _calculate(): 반복중에 this.data의 값들을 계산하는 코드를 작성합니다.
  • _draw(): 반복중에 this.data의 값들 바탕으로 화면에 텍스트를 그리는 코드를 작성합니다.
  • _timeline(loopCount): 반복중에 this.loopCount의 값을 기준으로 할 일의 코드를 작성합니다. 자동으로 this.loopCount가 인자로 들어오며, 이를 통해 현재 몇번째 반복이 실행되는지 알 수 있습니다. 반복 횟수에 따라(시간의 지연에 따라) 해야할 일의 코드를 작성합니다.
  • _getInput(): 사용자의 입력을 확인하고 그에 따라 할 일의 코드를 작성합니다.

코드 작성 예제

**예제 소스 코드 보기: i-program-tutorial.js

TM.IObject의 예제에서 만든 Frame 클라스, TM.ILoopObject의 예제에서 만든 MovingObject 클라스의 인스턴스들을 관리하는 Program_main 클라스를 만들어 봅시다. 전체 소스 코드(i-program-tutorial.js)와 함께 보시면 더 이해하기 쉽습니다.

Frame, MovingObject 클라스의 설명은 생략합니다. 해당 예제 문서에서 설명을 읽어 주세요.

메니저 인스턴스 생성

var TMS = new TM.ScreenManager(),
    TMI = new TM.InputManager(null,true);

화면에 텍스트를 그리기 위해 TM.ScreenManager의 인스턴스를 생성하여 변수 TMS에 저장하였고, 사용자 입력을 받기 위해 TM.InputManager의 인스턴스를 생성하여 변수 TMI에 저장하였습다.

TM.IProgram의 상속

//=============================
// Program_main
//=============================
// Object Type: TM.IProgram
var Program_main = function(){
  var speed = 100;
  this.data = {};
  this.objects = {
    frame: null,
    movingObjects: [],
  };
  TM.IProgram.call(this, speed);
};
Program_main.prototype = Object.create(TM.IProgram.prototype);
Program_main.prototype.constructor = Program_main;

TM.IProgram를 상속받아 Program_main 클라스를 작성하였습니다.

this.data는 내용이 없지만 그냥 모양을 남겨 놓았습니다.
this.objects는 나중에 생성될 인스턴스들을 위한 구조를 취하고 있습니다.

Static 항목 추가

// Static properties
Program_main.KEYSET = {
  ESC: 27, // esc key
};

Static 항목은 해당 클라스의 전체 인스턴스에서 동일하게 사용되는 값을 뜻합니다.

Program_main 클라스의 KEYSET 항목을 생성하고 ESC 키를 등록합니다. ESC의 키 값은 27입니다. 키값들은 TMI = new TM.InputManager(null,true);로 TMI를 생성하면 키입력이 있을 때마다 브라우저 콘솔에 표시가 되므로 알 수 있습니다.

TM.IProgram 함수들의 상속

위에서 설명한 것 처럼, 함수를 직접 상속받지 말고 함수이름 앞에 _를 붙여 코드를 작성하면 해당 함수 호출시 같이 호출됩니다. TM.IProgram은 init, inactivate, calculate, draw, timeline, getInput을 가지고 있으므로 _init, _inactivate, _calculate, _draw, _timeline, _getInput을 작성해 줍니다.

// TM.IProgram functions implementation
Program_main.prototype._init = function(){
  TMS.cursor.hide();
  this.objects.frame = new Frame({x:2,y:2});
};
Program_main.prototype._inactivate = function(){
  TMS.clearScreen();
};
Program_main.prototype._calculate = function(){};
Program_main.prototype._draw = function(){};
Program_main.prototype._timeline = function(loopCount){
  if(loopCount == 10) this.objects.movingObjects.push(new MovingObject(200,{x:4,y:5,dX:1}));
  if(loopCount == 20) this.objects.movingObjects.push(new MovingObject(400,{x:24,y:7,dX:-1}));
  if(loopCount == 30) this.objects.movingObjects.push(new MovingObject(300,{x:16,y:9,dX:1}));
};
Program_main.prototype._getInput = function(){
  if(TMI.keyboard.checkKey(Program_main.KEYSET.ESC)){
    this.inactivate();
    this.init();
  }
};

init에서 커서를 숨기고 frame이 생성됩니다.

timeline에서 loopCount에 의해 MovingObject 인스턴스들이 순서대로 생성됩니다. this.speed가 100(0.1초)이므로, 실행후 1초, 2초, 3초에 각각 인스턴스들이 순서대로 생성됩니다.

getInput에서 ESC 키가 눌려진 것이 감지되면 프로그램을 재실행시킵니다.

인스턴스의 생성과 활성화

var main = new Program_main();
main.init();

TM.IProgram은 자동으로 init이 되지 않으므로 따로 init을 해주어야 합니다. TM.IProgram이 자동실행되지 않는 이유는 여러개의 프로그램을 설정해놓고 바꿔가며 실행하기 위해서 입니다.

예제의 실행

이 스크린을 먼저 클릭한 다음 키입력을 해 주어야 키입력이 확인됩니다. 우리가 만든대로 ESC 키를 누르면 프로그램이 재시작되는 것을 볼 수 있습니다.

현재 페이지의 브라우저 콘솔을 연 다음 아래의 명령어들을 입력하여 바로 테스트해 봅시다.
혹시 단축키로 브라우저 콘솔이 열리지 않는다면, 스크린을 제외한 다른 부분을 한번 클릭한 다음 단축키를 입력해 주세요. 스크린은 다른 키입력을 차단합니다.

//main 비활성화
main.inactivate();

//main을 다시 활성화
main.init();

키입력이 있는 경우 콘솔에 해당 키의 code를 출력하는 것을 볼 수 있습니다. 이것으로 키보드의 키값을 알 수 있습니다.

댓글

댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP