본문 바로가기

프로젝트/팀 프로젝트

230317~230321_toy project_마리오 골드 턴게임 제작

728x90

개요

첫 팀 프로젝트로 턴게임 제작에 들어갔다.

간단한 토이프로젝트로 주말을 포함하여 5일간의 작업을 통해 제작되었다.

제작조건은 다음과 같다.

제작조건
- 간단한 로그인 페이지 제작
   - 회원가입 없이, 정해진 아이디, 패스워드 입력 시 게임시작 페이지로 이동.
   - 잘못 입력 시 다시 입력
- 게임 시작 페이지 제작
- 상점 페이지 제작
- 인벤토리 제작
- 게임 플레이. 턴 게임으로 제작
   - 플레이어는 체력, 공격력, 방어력, 경험치, 돈을 가지고 있다.
   - 몬스터는 체력, 공격력, 방어력, 보상을 가지고 있다.
   - 플레이어와 몬스터는 턴 방식으로 공격한다.
   - 공격 시 일정 확률로 크리티컬이 발생한다. (공격력 * 2) 

 

 


기획과정

 기획 단계 시, 현재 우리가 만들 방식의 게임을 모티브 할 수 있는 게임이 있는지 고민하였고, 어렸을 때 즐겨하였던 '포켓몬스터 골드버전'을 떠올리게 되었다. 따라서, 해당 게임을 바탕으로 비슷한 모습의 게임을 제작하고자 하였다.

 하지만, 이미지까지 똑같이 하기에는 심심한 부분이 있고 아쉬운 부분이 있어, 게임의 모션이나, 이펙트가 자연스럽지 않을 경우를 고려하여 도트이미지를 가진 게임을 제작하고자 하였고, 게임의 이미지를 마리오에서 가져오기로 하였다. 다행스럽게도 마리오는 유명한 게임캐릭터이기 때문에 관련 이미지를 구하는 것이 어렵지 않았고, 턴 게임은 고전 게임의 이미지가 있는 편이기 때문에 게임의 방식과 이미지가 부합하기도 하였다.

 게임을 제작하기에 앞서 팀원 4명이서 각자의 제작할 분량을 나누고자 하였다. 17일에 프로젝트가 시작되었고, 17일에 배운 내용을 기반으로 게임을 제작하여야 했으나, 그날 배운 내용은 그 당시 나에게는 감도 오지 않았던 내용이라 많은 걱정이 되었다. 하지만, 주말도 있으니 알아보면서 제작하면 해낼 수 있을 것이라는 생각으로 아직 이해가 온전하지 않은 내용의 제작분량을 가져가게 되었다.

 나의 분량은 '플레이어와 몬스터는 턴 방식으로 공격된다.'라는 단계와 '공격 시 일정 확률로 크리티컬 공격력 * 2의 데이미를 갖는다.'라는 내용의 제작을 담당하였다.

 

 


제작과정

나는 주말동안 내 분량의 작업을 하기 위해서 노력을 하였다. 우선 '플레이어와 몬스터는 턴 방식으로 공격된다.'의 작업을 진행하였다. 작업을 진행하기 위해서는 다른 팀원이 제작하기로 한 영역인 몬스터와 플레이어를 생성하는 생성자 함수를 진행해야 했었다. 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./jiwon.css">
</head>
<body>
    <div class="player">
            <p class="playerName">이름</p>      <!--플레이어 이름-->
            <p class="playerHP">피통</p>        <!--플레이어 HP-->
            <p class="playerDef">방어력</p>       <!--플레이어 def-->
    
    </div>
    
    <div class="monster">몬스터</div>
    <div>
        <div class="fightMode" onclick="divFight()">공격</div>
    </div>
</body>
<script>
function basicsetting(name, hp, atk, def, money){   //플레이어, 몬스터 생성자 함수
    this.name = name;
    this.hp = hp;
    this.atk = atk;
    this.def = def;
    this.money = money;

}


let player = new basicsetting("플레이어", 500, 100, 30, 20000); //이름, hp, 공격력, 방어력, 소지금
console.log(player);

let monster = new basicsetting("몬스터", 300, 100, 30); //이름, hp, 공격력, 방어력
console.log(monster);

function divFight(){
    console.log("공격버튼 눌림");
    playerTurn();
}


let playerAtk = true;      //플레이어 선공권
let monsterAtk = true;  //몬스터 선공권


function playerTurn(platerAtteck){         // 플레이어 주도 공격턴. 만들어져 있던 변수 player애서 가져와야 한다.
    let playerAtteckTurn = document.querySelector(".player");
    while (player.hp > 0 && playerAtk == true) {
        if(player.hp > 0 && monster.hp >= 0){       //플레이어 hp가 0이 아니면 공격진행
            monster.hp = monster.hp - (player.atk - monster.def);
            alert(`플레이어 공격! 효과는 미비했다.`)
            console.log("플레이어 공격. 몬스터 hp: " + monster.hp);
            monsterTurn();
   
        }
        else if (player.hp > 0 && monster.hp <= 0){                       //플레이어가 승리하면 보상흭득
            playerAtk == false;
        }
        else if (player.hp <= 0 && monster.hp >= 0){                       //플레이어 hp가 0이면 공격x
            playerAtk == false;
        }

        break;
    }
    

    
}



function monsterTurn(monsterAtteck){         // 몬스터 주도 공격턴. 만들어져 있던 변수 monster애서 가져와야 한다.
    let monsterAtteckTurn = document.querySelector(".monster");
    while (monster.hp > 0 && monsterAtk == true) {
        if(monster.hp > 0 ){       //몬스터 hp가 0이 아니면 공격진행
            player.hp = player.hp - (monster.atk - player.def);
            alert(`몬스터 공격! 효과는 미비했다.`)
            console.log("몬스터 공격. 플레이어 hp: " + player.hp);
        
        }
        else if (monster.hp <= 0){                       //플레이어 hp가 0이면 공격x
            console.log("몬스터 사망! 보상을 흭득합니다.")
            monsterAtk == false;
           
        }
        break;
    }
    

}

</script>
</html>

토요일이라는 시간동안 해당 내용을 제작하였으나, 나와 마찬가지로 팀원들도 맡은 코드를 실행하기 위해서는 내가 맡은 부분의 코드를 작업을 해야만 했다. 다른 이들과의 코드와 부합하는지에 대한 여부를 생각하기 보다는 JS가 많이 어색한 나는 우선 동작을 하도록 코드를 작성하였고,  자신의 코드와 부함하게 이미 짜여있는 코드로 사용을 하는 것이 좋겠다고 생각하여 위에 작성한 코드를 실제로 사용되지는 않았다.

 실제로 작업을 해보니, JS를 계속 맡고 있기에는 내가 할 수 있는 영역이 많지 않을것이라는 생각이 들었고, 팀 프로젝트 할 때 민폐를 끼치고 싶지 않아, JS보다는 할 수 있을 것이라고 생각이 드는 홈페이지 제작을 맡아 팀원들에게 힘이 되어주고자 하였다. 건의를 하여 로그인 후 상점과 전투페이지를 선택하는 페이지, 상점페이지 총 2개의 페이지를 만들고자 하였다. 

 상점, 전투 중 하나를 선택하여 이동하는 페이지는 말 그대로 간단하게 제작이 가능하였다. 페이지에 버튼 2개를 만들어 주고, onload를 이용하여 페이지이동만 시키면 되는 것으로,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>상점&산책 선택</title>
    <style>
    @font-face{
    font-family: 'dos';
    src: url('../DOSGothic.ttf') format('truetype');  
}


body{
    margin: 0;
    position: relative;
    font-family: 'dos';

}

.background{
    background-image: url(../배경.png);
    background-size: 100vw, 100vh;
    background-repeat: no-repeat;
    width: 100vw;
    height: 100vh;
}


.back {
    position: absolute;
    top: 0;
    left: 0;
    width: 150px;
    height: 50px;
    background-color: rgb(217, 144, 66);
    align-items: center;
    justify-content: center;
    display: flex;
    cursor: pointer;
    font-size: 20px;
    font-weight: bolder;
}

.shop {
    position: absolute;
    top: 30%;
    left: 50%;
    transform: translate(-50%);
    width: 300px;
    height: 100px;
    background-color: rgb(217, 144, 66);
    align-items: center;
    justify-content: center;
    display: flex;
    cursor: pointer;
    font-size: 30px;
    font-weight: bolder;
}

.walk {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%);
    width: 300px;
    height: 100px;
    background-color: rgb(217, 144, 66);
    align-items: center;
    justify-content: center;
    display: flex;
    cursor: pointer;
    font-size: 30px;
    font-weight: bolder;
    text-align: center;
}
    </style>
</head>
<body>
    <div class="background">
        <div class="back" onclick="location.href='./상점,산책 선택.html'">< 돌아가기</div>      //
        <div class="shop" onclick="location.href='./상점.html'">상점가기</div>
        <div class="walk" onclick="location.href='../index.html'">산책하기 <br> (monster 만나기)</div>
    </div>

</body>
</html>

이렇게 작성을 완료하였다.

 

 

 

상점페이지는 물약, 무기, 몬스터의 잔해물을 교환하는 작업이 이루어져야했다. 상단 좌측에는  돌아가기 버튼을 클릭하여, 상점에 들어오기 전 화면으로 이동할 수 있도록, onload를 걸어주었고, 상단 우측에는 플레이어가 소지하고 있는 몬스터의 잔해와 금액을 노출할 수 있도록 영역을 지정하였다.

 물약은 hp포션(빨간버섯), 공격력 증가포션(별), 방어력 증가포션(방패)로 구성되어 있고, 무기는 초보자의 검과 초보자의 갑옷으로 구성되어 있다. 몬스터의 잔해는 1회 교환 시 5개를 소비하며, 돈 1000원과 교환이 가능하다.

 

 물약과 무기는 각 상품에 마우스를 올렸을 때 hover기능을 부여하여 상품의 이미지에 불투명한 배경이 생기고,  각 상품에 대한 설명이 노출된다.

 

 몬스터의 잔해는 전투 시 몬스터에게서 이기면 1개씩 보상으로 얻을 수 있도록 세팅되어 있다. 이 잔해를 5개 마다 1번싹 교환할 수 있으며, 교환하기 버튼을 누르면 몬스터의 잔해 개수가 차감되고, 돈의 금액이 올라가도록 함수로 제작하였다 (기존에 가지고 있는 소지금과 잔해의 개수를 연결해서 제작해야 했으므로, 내가 작업한 코드에서 수정진행 되었다.)

.

 상점에서 상품을 구매하기 위해 상품을 클릭하면 팝업창이 노출되며 상품을 구매할 수 있는 화면이 구성된다. 해당 팝업창에는 상품의 수량을 카운트 할 수 있는 버튼이 있고, 구매하기 버튼을 클릭하여 상품을 구매한다. 상품을 구매하면 소지금에서 선택한 상품의 금액만큼 차감되게 되고, 인벤토리에 구매한 상품의 개수가 늘어나게 된다. 여기서 클릭 시 팝업 노출과 카운트 수량 설정, X버튼 클릭 시 팝업창이 display = none으로 노출이 꺼지게 되는 작업은 내가 진행하였고, 그 외의 구매하기를 눌러 소지금이 차감되고, 소지하고 있는 상품의 개수가 늘어나는 작업은 팀원이 작업을 진행하게 되었다.

 내가 작업한 부분들은 여기까지로, 이제부터 순차적으로 게임이 동작하는 모습을 확인하고자 한다.

이후의 작업 내용은 내가 참여한 부분이 아닌 팀원들의 땀과 노력이다. 다들 너무 고생 많으셨습니다!

 

 


결과물

 

가장 처음 나오는 화면인 로그인 화면이다.

해당 화면에서는 지정된 아이디와 패스워드를 입력할 시에만 페이지가 넘어가도록 제작되었다. 지정된 아이디와 패스워드가 아닐경우, 경고 메세지가 뜨며, 다시 입력할 수 있도록 제작되었다.

 

로그인 후 게임 캐릭터 선택창이 노출된다. (사실 게임캐릭터의 이미지도 노출되지만 연결되어있던 이미지링크가 에러가 나서 불러오지 못하고 있는 모습이다.)  게임 캐릭터는 마리오, 루이지 총 2개의 캐릭터 중 택 1로 선택할 수 있으며, 캐릭터별로 능력치가 다르다. 또, 상점가기 버튼을 누르면 게임 시작 전, 상점에서 물건을 산다던지 등의 행위를 할 수 있다.

 

 게임 캐릭터 또한 랜덤으로 등장한다. '도망'버튼을 누르면 몬스터가 사라지고, '몬스터 재소환'버튼을 누르면 몬스터가 다시 랜덤으로 나타나는 것을 확인할 수 있다.

 

 공격은 플레이어가 선공격을 가지고 있다. 공격 시 공격모션 이미지가 뜨도록 설정이 되어 있으며, 플레이어의 공격에는 일반 공격과 크리티컬 공격이 있다. 해당 크리티컬은 확인하기 쉽도록 50%로 설정되어있다. 또한 몬스터에게서 이기면 몬스터의 잔해물과 물약 아이템중 하나가 랜덤으로 나오고 경험치가 5씩 오르는 것을 확인할 수 있다. 이 물약은 가방에 가면 해당 아이템의 개수가 증가한 것을 확인할 수 있으며, 해당 아이템을 선택하면 물약의 효과만큼 캐릭터의 정보가 바뀌는 것을 확인해볼 수 있다. 

 캐릭터는 무기를 착용할 수 있다. 무기 착용 시 공격력이 +10이 향상되며, 그에 맞게 캐릭터 이미지가 변경되는 것을 확인해볼 수 있다. 해당 이미지에는 나와있지 않지만, 무기를 착용한 상태에서 한 번더 무기를 누르면 이미 착용한 상태라는 경고창이 뜨도록 작성되어 있다.

 

 


이슈사항(에러사항)

 

캐릭터 무기 착용 시 무조건 마리오가 검을 든 이미지 노출

 

hp회복 물약 사용 시 체력이 일정 범위 이상 증가하는 현상 발생

 

상품 선택 시 노출되는 팝업창이 바뀌지 않고 밑으로 이어서 노출되는 현상 발생 

 


제작 후기

 아쉽지 않은 조가 어디있겠냐만, 나는 나 스스로도 매우 아쉬운 팀프로젝트였다고 생각한다. 수업이 진행되면서 JS를 만나고 나서 총체적난국이었다. 머릿속은 복잡하고 수업시간에 배운 내용은 여러 번 들여다 봐야 겨우 이건가? 싶을 정도였으니 말이다. 구글링을 수도 없이 하고 그 안에서 알아들을 수 있는 예제를 만나 몇번이고 들여다보는 과정의 연속이었다. 하지만 과제에 중요한 내용을 배운 17일 과정은 정말 역대급으로 이해가 되지 않았고, 별도의 내용을 들여다 볼 시간도 없이 게임제작에 들어가야 했으니 내가 짠 코드에 대해서도 확신이 서지 않고, 내가 책임져야 할 부분도 제대로 처리하지 못했다는 사실이 더욱 나를 힘들게 했었던 것 같다.

 그래도 포기하지 않고 그 안에서 내가 당장 도움이 될 수 있는 부분은 어떤 부분일지 빠르게 생각하였고, 홈페이지 제작을 진행하였다. 홈페이지를 제작하면서 JS로 기능이 들어가야하는 일부분에는 이전 수업시간에서 배웠던 내용인 팝업창 띄우기와 X버튼으로 팝업창을 내리는 것을 진행해보았고, 상품의 수량을 선택할 수 있도록 구글링을 통하여 카운트 함수를 제작하였다. 또 팀원들의 도움을 받아 몬스터의 잔해를 교환하는 함수를 제작해 볼 수 있게 되었다.

 앞으로도 지금보다 더욱 어렵고 힘든 과제를 하게 될 것이다. 그때마다 어렵다고 힘들다고 포기할 순 없으니, 맡은 부분에 대해 최선을 다해 임하고, 그 또한 어려우면 팀원들과의 소통으로 이겨낼 것이다.

728x90