Game Tutorial OOP 3

목표

  • TM.IProgram 클라스를 상속하여 frame, enemy를 관리하는 Program_Main 클라스를 만듭니다.

코드

**소스 코드: game-tutorial-oop3.js

이전 튜토리얼에서 변경이 없는 부분은 설명을 생략합니다.

//=============================
// Program_Main
//=============================
// Object Type: TM.IProgrm
var Program_Main = function(){
  this.speed = 30;
  this.data = {};
  this.objects = {
    frame: null,
    enemy: null,
  };
  TM.IProgram.call(this, speed);
};
Program_Main.prototype = Object.create(TM.IProgram.prototype);
Program_Main.prototype.constructor = Program_Main;

TM.IProgram를 상속하여 Program_Main 클라스를 만들었습니다. TM.IProgram은 TM.IObject나 TM.ILoopObject를 상속받은 클라스들을 관리하는 클라스를 만들때 사용됩니다. TM.IProgram는 TM.ILoopObject를 상속받은 클라스이므로 data, speed를 가지고 있고, objects를 추가로 갖습니다. data는 사용되지 않지만 명시적으로 표시하였습니다. objects에는 관리할 인스턴스들의 구조를 넣습니다.

// TM.IProgram functions implementation
Program_Main.prototype._init = function(){
  TMS.cursor.hide();
  this.objects.frame = new Frame({x:5,y:2});
  this.objects.enemy = new Enemy({refMainObjects:this.objects});
};
Program_Main.prototype._inactivate = function(){};
Program_Main.prototype._calculate = function(){};
Program_Main.prototype._draw = function(){};
Program_Main.prototype._timeline = function(loopCount){};
Program_Main.prototype._getInput = function(){};

TM.IProgram는 init, inactivate, calculate, draw, timeLine, getInput 함수를 가지고 있습니다. init, inactivate, calculate, draw은 TM.ILoopObject와 같으며 timeline과 getInput은 TM.IProgram에서 추가된 함수로 this.speed를 간격(단위:milliseconds)으로 계속하여 반복되는 함수입니다. timeline에는 loopCount라는 현재 몇번째 loop를 진행중인지 알 수 있는 변수가 전달되어 해당 회차에 해야할 일이 실행됩니다. getInput은 사용자의 입력을 확인하고 해야할일이 실행됩니다. TM.IObject, TM.ILoopObject와 마찬가지로 직접 상속받지 말고, _init, _inactivate, _calculate, _draw, _timeline, _getInput에 코드를 넣어 줍니다. 코드가 없더라도 빈함수를 넣어 해당 함수들이 존재함을 표시하였습니다.

Program_main의 초기화(init)시에 커서를 숨기고 this.objects에 frame과 enemy를 생성합니다. enemy는 이제 frame을 직접적으로 참조할 수 없으므로, refMainObjects를 통해서 frame을 참조해야 합니다.

//=============================
// Enemy
//=============================
// Object Type: TM.ILoopObject
var Enemy = function(data){
  this.speed = null;
  this.data = {
    refMainObjects: undefined,
    x: null,
    y: null,
    pX: null,
    pY: null,
    dX: 0,
    dY: 1,
    text: "X",
  };
  TM.ILoopObject.call(this, this.speed, data);
};

enemy의 생성시 refMainObjects을 전달받을 수 있도록 Enemy의 생성자가 변경되었습니다. 

// TM.ILoopObject functions implementation
Enemy.prototype._init = function(){
  var frame = this.data.refMainObjects.frame;
  this.interval.setSpeed(50+Math.floor(Math.random()*100));
  this.data.x = 2+Math.floor(Math.random()*(frame.data.width-4));
  this.data.y = 1;
};
Enemy.prototype._inactivate = function(){
  var frame = this.data.refMainObjects.frame;
  TMS.deleteTextAt(frame.data.x+this.data.x,frame.data.y+this.data.y,this.data.text);
};
Enemy.prototype._calculate = function(){
  var frame = this.data.refMainObjects.frame;
  this.move();
  if(this.checkHitFrame(frame)){
    this.init();
  }
};
Enemy.prototype._draw = function(){
  var frame = this.data.refMainObjects.frame;
  if(this.data.pX && this.data.pY){
    TMS.deleteTextAt(frame.data.x+this.data.pX,frame.data.y+this.data.pY,this.data.text);
  }
  TMS.insertTextAt(frame.data.x+this.data.x,frame.data.y+this.data.y,this.data.text);
};

enemy에서 frame은 this.data.refMainObjects.frame을 통해 접근할 수 있습니다. enemy의 _함수들의 첫줄에 var frame = this.data.refMainObjects.frame;를 추가하였습니다.

var main = new Program_Main();
TMS.onReady(function(){
  main.init();
});

TMS.onReady에는 main.init이 들어갑니다.

예제의 실행

현재 페이지의 브라우저 콘솔을 연 다음 아래의 명령어들을 입력하여 바로 테스트해 봅시다.

main.inactive() //main과 main.objects들을 비활성화 시킵니다.(frame, enemy가 비활성화됩니다.)
main.init() //main과 main.object들이 생성됩니다. (frame, enemy가 생성됩니다.)
main.objects.enemy.inactivate() //enemy를 비활성화 시킵니다.
main.objects.enemy.init() //enemy를 초기화 시킵니다.
main.objects.frame.inactivate() //frame을 비활성화 시킵니다.
main.objects.frame.init() //frame을 초기화 시킵니다.

댓글

댓글쓰기

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

UP