MiniGame - [ 개인 작업! ]

Lumi·2021년 12월 13일
0
post-thumbnail

Github

함수 구현 영상(Youtube)

🔥 기본 구조체 및 맵핑

mapping(address => User) characterStorage;
   mapping(address => uint) checkId;
   uint levelUpstand = 0.001 ether;

   event createCharacter (string _name, Position pos);

    struct User {
        string nickname;
        string email;
        uint wincount;
        uint losscount;
        uint drawcount;
        uint point;
        Character character;
        uint checkCharacter;
    }

    struct Character {
        string name;
        uint level;
        Position pos;
        uint power;
        uint sheild;
    }

    enum Position {
        attacker, defense
    }

    enum Ability {
        power, sheild
    }

처음부터 이렇게 완전히 작성해 보는것은 처음이기 떄문에 불필요한 값들이 존재 할 수가 있습니다 ㅠㅠ

기본적으로 구조체를 두개 선언하였습니다.

User이라는 구조체 안에 Character이라는 구조체를 할당한 형태 입니다.

또한 열거형을 통해서 Character의 직업?? 을 구현을 하였고

후에 들어오는 값을 비교하기 위해서 또다른 Ability라는 열거형을 선언한 형태 입니다.

characterStorage는 특정 지갑 주소에 계정이 존재하는지를 기록하는 변수이며

checkId는 특정 계정에 가지고 있는 계정의 갯수를 말합니다.

  • 생각해보니 이 변수는 필요가 없습니다.
  • 어차피 계정은 한개만 존재하게 설정을 하였기 떄문입니다.

🔥 makingNewUser

function makingNewUser(string memory _myname, string memory _password) public returns(bool){
        require(checkId[msg.sender] < 1, "already have Id");
        User storage user = characterStorage[msg.sender];
        user.nickname = _myname;
        user.email = _password;
        user.checkCharacter = 0;
        user.wincount = 0;
        user.losscount = 0;
        user.drawcount = 0;
        user.point = 0;
        checkId[msg.sender]++;
        return true;
    }

말 그대로 새로운 User를 만드는 행위입니다.

이곳에서는 User의 구조체만을 설정을 하게되며 아직 Character구조체에는 값을 할당하지 않습니다.

기본적으로 checkId를 통해서 해당 계정이 있는지 없는지를 판단하는데 이부분은 다른 방식으로 구현할수 있다고 생각하기 떄문에 참고로만 하고 넘어가도록 하겠습니다.

🔥 makingNewCharacter

 function makingNewCharacter(string memory _name, Position _pos) public returns(bool){
        require(checkId[msg.sender] == 1);
        require(characterStorage[msg.sender].checkCharacter <1);
        User storage user = characterStorage[msg.sender];
        user.checkCharacter = 1;
        user.character.name = _name;
        user.character.level = 1;
        user.character.pos = _pos;
        if(_pos ==  Position.attacker){
            user.character.power = 2;
            user.character.sheild = 1;
        }else{
            user.character.power = 1;
            user.character.sheild = 2;
        }
        emit createCharacter(_name, _pos);
        return true;
    }

이제 User에 캐릭터를 부여하는 부분입니다.

  • 지금 생각해보니 User를 만들떄 그냥 캐릭터 이름도 받아서 바로 Character함수가 실행되게 했으면 좀더 편할것 같네요

일단 기본적으로 User가 있는지를 확인하고 기존에 캐릭터가 없는지를 확인합니다.

  • 캐릭터는 User한명당 하나만 가능하게 설정해 두었습니다.

그후 문제가 없다면 User값을 가져와서 안에 있는 character값을 수정해주면 되겠습니다.

열거형 타입의 사용에 유의하여 작성을 해야 하는 코드입니다.

🔥 attack

function attack(address _to) public {
        require(characterStorage[msg.sender].checkCharacter == 1, "my character isn't exixted");
        require(characterStorage[_to].checkCharacter == 1,"another user's character isn't exixted");

        User storage user = characterStorage[msg.sender];
        User storage user2 = characterStorage[_to];

        if(user.character.power > user2.character.sheild){
            user.wincount++;
            user2.losscount--;
        } else if(user.character.power == user2.character.sheild){
            user.drawcount++;
            user2.drawcount++;
        }else{
            user.losscount++;
            user2.wincount++;
        }
    }

이 함수는 다른 사용자의 캐릭터와 결투를 하는 함수라고 할 수가 있습니다.

단순하게 해당 사용자의 sheild값보다 크면 이기고 같으면 무승부 낮으면 지는 그런 역할을 담당하고 있습니다.

  • 좀더 복잡한 로직을 작성해보고 싶었지만 제 수준에서는 너무 오랜시간이 걸릴꺼 같아서..ㅠㅠ

일단 상대방과 저희 캐릭터가 있는지를 확인부터 하면서 함수가 실행이 이루어 지게 됩니다.

그후 문제가 없다면 간단하게 서로의 캐릭터를 불러와서 값을 비교해 싸움을 하게 됩니다.

🔥 levelUp

function levelUp() public  returns(bool) {
        require(characterStorage[msg.sender].checkCharacter == 1, "no character");
        User storage user = characterStorage[msg.sender];
        user.point++;
        user.character.level++;
        return true;
    }

이 부분은 캐릭터의 레벨을 올리는 함수입니다.

레벨이 올라가게 되면 캐릭터의 power, sheild둘중 한곳에 값을 투자 할수 있으며 이로인해 캐릭터는 더 강해지게 됩니다.

이 부분에서 payable을 통해서 특정값 이상을 받았을때 레벨업이 정상적으로 이루어지게 구현을 하고 싶었는데 원인 모르는 에러가 발생을 해서 일단 조건없이 레벨업이 가능하게 만들어 놓았습니다.

  • 이 부분은 후에 수정을 해볼 사항입니다.

🔥 growMyCharacter

function growMyCharacter(Ability  _ability) public returns(bool) {
        require(characterStorage[msg.sender].checkCharacter == 1, "no character");
        require(characterStorage[msg.sender].point >= 1, "no point");
        require(_ability == Ability.power || _ability == Ability.sheild , "there is no ability");
        User storage user = characterStorage[msg.sender];

        if(_ability == Ability.power){
            user.character.power++;
        }else{
            user.character.sheild++;
        }
        user.point--;
        return true;
    }

이제 레벨업해서 가지고 있는 포인트를 통해 캐릭터의 능력치를 올리는 함수입니다.

이 부분도 열거형의 사용에 유의해야 합니다..!!!

🔥 후기, 느낀점

설명 자체는 간단하고 짧게 끝낸거 같습니다.

하지만 완전 처음부터 아무생각없이 작성해 보는것은 처음이라서 그런지 생각보다 오랜시간이 소요 되엇습니다.

그래도 그만큼 배우는 과정은 많았고 뿌듯했던것 같습니다!!

후에 또 시간이 된다면 좀더 보완을하고 좀더 기능적으로 추가하여 작성을 해보고자 합니다! 감사합니다!

view함수는 단순히 returns하는 부분이기 떄문에 따로 다루지 않도록 하겠습니다!

profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글