이번 시간에는 텍스트 RPG를 만들어보겠습니다. 그래픽 작업은 아직 못 하지만, 텍스트 RPG정도는 만들 수 있을 것 같습니다. html을 어느 정도 할 수 있다는 전제 하에 진행되지만, html을 못 한다면 그냥 복사 붙여넣기 하시면 됩니다. 중요한 건 자바스크립트 코드니까요.
<html>
<head>
<title>텍스트RPG</title>
</head>
<body>
<div id="log"></div>
<script>
// 여기에 자바스크립트 코드를 넣습니다.
</script>
</body>
</html>
이제는 콘솔에서 벗어나 html 파일에 만들 겁니다. 실행은 브라우저에서 할 거고요. 위의 코드를 복사해서 메모장에 붙여넣은 후 저장할 때 확장자가 html인 파일로 저장하세요.
다음 코드를 script에 넣으면 됩니다. 물론 아직은 화면에 아무것도 안 뜰 겁니다.
function logMessage(msg, color) {
if (!color) { color = 'black'; }
var div = document.createElement('div');
div.innerHTML = msg;
div.style.color = color;
document.getElementById('log').appendChild(div);
}
메세지를 #log 태그에 추가하는 코드입니다. color 값을 따로 인자로 제공하면 해당하는 색의 에러 메시지가 표시됩니다.
var gameover = false;
var battle = false;
function Character(name, hp, att) {
this.name = name;
this.hp = hp;
this.att = att;
}
Character.prototype.attacked = function (damage) {
this.hp -= damage;
logMessage(this.name + '의 체력이 ' + this.hp + '가 되었습니다');
if (this.hp <= 0) {
battle = false;
}
};
Character.prototype.attack = function (target) {
logMessage(this.name + '이 ' + target.name + '을 공격합니다');
target.attacked(this.att);
};
일단 캐릭터들을 관장하는 캐릭터 생성자를 만들어줍니다. hp, att는 각각 체력, 공격력이고요. attack과 attacked 메소드는 각각 공격하고, 공격받는 겁니다. 공격받는 것을 보면, hp에 데미지를 받죠? 공격하는 것은 타겟에 공격력을 가합니다. 아, 그리고 게임오버와 전투중인지를 알려주는 변수 두 개를 만들었습니다.
이제 캐릭터를 상속하는 영웅과 몬스터를 만들겁니다.
function Hero(name, hp, att, lev, xp) {
Character.apply(this, arguments);
this.lev = lev || 1;
this.xp = xp || 0;
}
Hero.prototype = Object.create(Character.prototype);
Hero.prototype.constructor = Hero;
Hero.prototype.attacked = function(damage) {
this.hp -= damage;
logMessage(this.name + '님의 체력이 ' + this.hp + '남았습니다');
if (this.hp <= 0) {
logMessage('죽었습니다. 레벨' + this.lev + '에서 모험이 끝납니다. F5를 눌러 다시 시작하세요', 'red');
battle = false;
gameover = true;
}
};
Hero.prototype.attack = function (target) {
logMessage(this.name + '님이 ' + target.name + '을 공격합니다');
target.attacked(this.att);
if (target.hp <= 0) {
this.gainXp(target);
}
};
Hero.prototype.gainXp = function(target) {
logMessage('전투에서 승리하여 ' + target.xp + '의 경험치를 얻습니다', 'blue');
this.xp += target.xp;
if (this.xp > 100 + 10 * this.lev) {
this.lev++;
logMessage('레벨업! ' + this.lev + ' 레벨이 되었습니다', 'blue');
this.hp = 100 + this.lev * 10;
this.xp -= 10 * this.lev + 100;
}
};
Hero가 Character을 상속하고 있습니다. 거기에 lev(레벨), xp(경험치) 속성이 추가되었네요. 그리고 원래 있던 attacked, attack 메소드를 확장했고, gainXp라는 메소드를 프로토타입에 하나 추가했습니다.
function Monster(name, hp, att, lev, xp) {
Character.apply(this, arguments);
this.lev = lev || 1;
this.xp = xp || 10;
}
Monster.prototype = Object.create(Character.prototype);
Monster.prototype.constructor = Monster;
뭔가 프로그래밍하는 것 같나요? 이제 영웅과 몬스터를 만들었으니 게임 진행하는 알고리즘을 짜야겠죠? 단순하게 전투->승리->경험치획득->전투->승리->레벨업->전투->... 이런 반복이면 됩니다.
몬스터를 랜덤으로 만드는 함수입니다. 5종류 정도만 만들어보죠. 5종류 중에 골라서 몬스터 객체를 만듭니다.
function makeMonster() {
var monsterArray = [
['rabbit', 25, 3, 1, 35],
['skeleton', 50, 6, 2, 50],
['soldier', 80, 4, 3, 75],
['king', 120, 9, 4, 110],
['devil', 500, 25, 6, 250]
];
var monster = monsterArray[Math.floor(Math.random() * 5)];
return new Monster(monster[0], monster[1], monster[2], monster[3], monster[4]);
}
흠.. 몬스터 중 하나가 밸런스 붕괴네요... 20% 확률로 게임오버...
var hero = new Hero(prompt('이름을 입력'), 100, 10);
logMessage(hero.name + '님이 모험을 시작합니다. 어느 정도까지 성장할 수 있을까요?');
while (!gameover) {
var monster = makeMonster();
logMessage(monster.name + '을 마주쳤습니다. 전투가 시작됩니다', 'green');
battle = true; while(battle) {
hero.attack(monster);
if (monster.hp > 0) {
monster.attack(hero);
}
}
}
이렇게 텍스트RPG가 완성되었습니다. 밸런스는 조정하시면 됩니다. 어쩌다 보니 운빨 게임이 되어버렸네요. ㅎㅎ 새로고침하면서 몇 레벨까지 갈 수 있나 테스트해보세요. 그리고 자유롭게 게임을 패치해보세요.~
- 다양한 스텟들 추가하기(명중률, 방어력 등등...) (힌트: 생성자에 추가하면 됩니다)
- 자동 진행이 아닌 수동진행으로 만들기(힌트: 한 턴이 지날 때마다 멈추는 코드를 넣으면 됩니다)
- 회복같은 메소드 추가해보기 (힌트: prototype에 추가하면 됩니다)
이제 초보를 벗어났으니 중급 강좌가 진행됩니다!
질문이 있는데.. 자바스크립트의 class기능을 사용하면..
굳이 prototype 안에 함수를 넣지 않아도 저절로 들어가는거지요?
class를 아는 상황해서 이 파트를 공부해야할까요?..