이번 시간은 지난 시간에 이어서 턴제 게임 만들기를 계속 하겠습니다. 전 시간에 간단히 메뉴만 만들었을 뿐인데 코드가 많이 기네요. 원래 프로그램이 그렇습니다. 제 홈페이지는 게임이 아닌데도 코드가 만 줄 가까이 됩니다. 이번 시간에도 코드가 많이 필요할 것 같습니다.
지금은 메뉴가 선택이 안 되는데 이제 메뉴를 선택해봅시다. 일단 저 메뉴 입력 버튼에 이벤트 리스너를 달아야겠죠? 이전 파일에서 다음과 같이 수정해줍니다.
document.getElementById('menu-button').onsubmit = function(e) {
var input = document.getElementById('menu-input');
var option = input.value;
e.preventDefault();
input.value = '';
TurnGame.getInstance().menuInput(option); // 새로 추가
};
document.getElementById('battle-button').onsubmit = function(e) {
var input = document.getElementById('battle-input');
var option = input.value;
e.preventDefault();
input.value = '';
TurnGame.getInstance().battleInput(option); // 새로 추가
};
입력버튼에 들어간 menuInput, battleInput 메소드를 instance에 추가합시다. 아, 그리고 몬스터 객체 리스트도 같이 만들어보죠. 간단히 세 종류만 만들겠습니다. (보스는 제 친구의 부탁으로 친구 이름입니다...)
menuInput 메소드에는 1, 2, 3번 선택지에 따라 다르게 행동하도록 코드가 들어있습니다. 1번 모험을 선택하면 몬스터를 만들고, 2번일 경우엔 hp를 전부 회복합니다. 3번일 경우에는 게임을 종료하고요. 따라서 exit과 generateMonster 메소드도 만들었습니다.
var TurnGame = (function() {
var instance;
var initiate = function(heroName) {
var hero = {
name: heroName,
lev: 1,
maxHp: 100,
hp: 100,
xp: 0,
att: 10
};
var monsters = [{
name: '슬라임',
hp: 25 + hero.lev * 3,
att: 10 + hero.lev,
xp: 10 + hero.lev,
}, {
name: '스켈레톤',
hp: 50 + hero.lev * 5,
att: 15 + hero.lev * 2,
xp: 20 + hero.lev * 2,
}, {
name: '찬호[보스]',
hp: 100 + hero.lev * 10,
att: 25 + hero.lev * 5,
xp: 50 + hero.lev * 5,
}];
var monster = null;
var turn = true;
return {
... // 이전과 동일 다음 메소드 추가
generateMonster: function() {
monster = JSON.parse(JSON.stringify(monsters[Math.floor(Math.random() * monsters.length)]));
document.getElementById('monster-name').innerHTML = monster.name;
document.getElementById('monster-hp').innerHTML = 'HP: ' + monster.hp;
document.getElementById('monster-att').innerHTML = 'ATT: ' + monster.att;
this.setMessage(monster.name + '이(가) 공격해옵니다');
return this.toggleMenu();
},
menuInput: function(input) {
if (input === '1') {
return this.generateMonster();
} else if (input === '2') {
hp = maxHp;
return this.updateStat().setMessage('체력을 회복했습니다');
} else if (input === '3') {
return this.exit();
} else {
alert('잘못된 입력');
}
},
battleInput: function(input) {}, // 구현필요
attackMonster: function() {}, // 구현필요
attackHero: function() {}, // 구현필요
nextTurn: function() {}, // 구현필요
win: function() {}, // 구현필요
clearMonster: function() {}, // 구현필요
gameOver: function() {}, // 구현필요
exit: function(input) {
document.getElementById('screen').innerHTML = '이용해주셔서 감사합니다.새로 시작하려면 새로고침하세요';
}
};
};
return {
getInstance: function(name) {
if (!instance) {
instance = initiate(name);
}
return instance;
}
};
})();
이제 전투 메뉴까지는 뜹니다. 이제 전투 메뉴도 구현해보겠습니다! 구현 필요라고 되어있는 메소드들을 만들어보겠습니다. 턴제 게임이기 때문에 nextTurn 메소드는 몬스터에게 턴을 넘기는 동작을 합니다. battleInput은 menuInput처럼 각 입력별로 그에 따른 함수를 호출해줍니다.
battleInput: function (input) {
if (input === '1') {
return this.attackMonster();
} else if (input === '2') {
if (hero.hp + hero.lev * 20 < hero.maxHp) {
hero.hp += hero.lev * 20;
} else {
hero.hp = hero.maxHp;
}
return this.showHp().setMessage('체력을 회복했습니다').nextTurn();
} else if (input === '3') {
return this.clearMonster().setMessage('도망쳤습니다');
} else {
alert('잘못된 입력');
}
},
attackMonster: function () {
monster.hp -= hero.att;
document.getElementById('monster-hp').innerHTML = 'HP: ' + monster.hp;
if (monster.hp > 0) {
return this.setMessage(hero.att + '의 데미지를 입혔습니다.').nextTurn();
}
return this.win();
},
attackHero: function () {
hero.hp -= monster.att;
return this.showHp();
},
nextTurn: function () {
var self = this;
turn = !turn;
document.getElementById('battle-button').disabled = true;
if (!turn) {
window.setTimeout(function () {
self.setMessage(monster.name + '의 턴입니다');
window.setTimeout(function () {
document.getElementById('battle-button').disabled = false;
if (self.attackHero()) {
self.setMessage(monster.att + '의 데미지를 입었습니다');
window.setTimeout(function () {
self.setMessage(hero.name + '의 턴입니다');
}, 1000);
}
}, 1000);
}, 1000);
return this.nextTurn();
}
return this;
},
win: function () {
this.setMessage(monster.name + ' 사냥에 성공해 경험치 ' + monster.xp + '을 얻었습니다');
hero.xp += monster.xp;
return this.clearMonster().showXp();
},
clearMonster: function () {
monster = null;
document.getElementById('monster-name').innerHTML = '';
document.getElementById('monster-hp').innerHTML = '';
document.getElementById('monster-att').innerHTML = '';
return this.toggleMenu();
},
gameOver: function () {
document.getElementById('screen').innerHTML = hero.name + '은 레벨' + hero.lev + '에서 죽었습니다. 새로 시작하려면 새로고침하세요';
return false;
},
이제 게임을 즐기면 됩니다! nextTurn 함수를 잘 봐주세요. window.setTimeout으로 메세지를 1초마다 순차적으로 표현합니다.
다음 강좌에 전체 코드를 올리겠습니다! 작동이 잘 안 되는 분들은 다음 강좌 코드를 복사하세요!