저번시간에 이어 엑터를 상속받는 자식, 캐릭터와 Enemy를 작성해본다!
#pragma once
#include "Actor.h" //캐릭터가 actor을 상속할 것이기 때문에 정의가 필요하다
class Character : public Actor //actor의 public 기능이 제대로 동작하기 위해서 public을 붙여준다
{
public:
Character(int hp, int ad);
void Damaged(int damage) override; //virtual 달린 함수의 기능을 재구현한다는 의미(override)
void Heal(); //상속받은 것은 자식이 선언한 함수 외에도 getposition, gethp등 함수를 사용할 수 있다.
private:
int Healcount;
int healShlot[3] = { 3.2,1 };
};
다음은 character에 대한 cpp코드!
#include "character.h"
#include <iostream>
Character::Character(int hp, int ad) : Actor(hp, ad, "용사") //character생성자를 작성 시 Actor의 생성자도 채워준다.
{
Healcount = 0;
}
void Character::Damaged(int damage)
{
std::cout << damage << "의 데미지를 입었다" << std::endl;
std::cout << "남은 체력" << ((HP - damage > 0) ? HP - damage : 0)<< std::endl;//((HP - damage > 0) ? HP - damage : 0)에서 참이면 앞에 있는 HP-damage를, 거짓이면 0을 반환한다.
Actor::Damaged(damage); // 덮어써졌지만, 기존의 값도 변경하기 위해서 actor의 damaged를 호출
}
void Character::Heal() {
if (Healcount < 3)
{
HP += healShlot[Healcount];
Healcount++;
std::cout << healShlot[Healcount - 1] << "를 회복했다! 남은 회복횟수" << 3 - Healcount << std::endl;
}
else
{
std::cout << "회복을 다 써버렸다!" << 3 - Healcount << std::endl;
}
}
아래는 Enemy의 헤더소스!
#pragma once
#include "Actor.h"
class Enemy :public Actor
{
public:
Enemy(int hp, int ad, std::string name, bool named);
bool Named;
void Damaged(int damage) override;
void Move(bool front) override;
};
마지막으로 Enemy의 소스파일
#include "Enemy.h"
#include <iostream>
Enemy::Enemy(int hp, int ad, std::string name, bool named) :Actor(hp, ad, name)
{
Named = named;
}
void Enemy::Damaged(int damage)
{
if (Named)
{
std::cout << "울부짖으며," << std::endl;
}
std::cout << "감히 나를 때렸겠다?" << std::endl;
Actor::Damaged(damage);
}
void Enemy::Move(bool front)
{
if (front) //왼쪽에서 시작이므로
{
Position--;
}
else
{
Position++;
}
}
모든 코드를 종합하여 main 코드를 작성한다.
#include "character.h"
#include "Enemy.h"
#include <iostream>
void main() //컴퓨터 프로그램이 동작시 먼저 실행되는 것. 단 하나만 존재해야함
{
Character* character = new Character(20, 3); //컴퓨터 공간의 남는 공간에 character라는 것을 생성한다. 생성된 것의 주소값을 저장하기 위해 포인터에게 가리키게함
for (int i = 0; i < 3; i++)
{
Enemy* enemy = nullptr; //아무것도 가리키지 않는 포인터
switch (i)
{
case 0:
enemy = new Enemy(3, 1, "잡몹", false);
std::cout << "잡몹을 만났습니다." << std::endl;
break;
case 1:
enemy = new Enemy(5, 3, "네임드몹", true);
std::cout << "네임드몹을 만났습니다." << std::endl;
case 2:
enemy = new Enemy(5, 6, "보스몹", true);
std::cout << "보스몹을 만났습니다." << std::endl;
}
enemy->SetPosition(5);
character->SetPosition(0);
while (enemy != nullptr) //위에서 잡몹, 네임드몹, 보스몹 등 넣어줬으므로 nullptr이 아님
{
std::cout << "내 위치: " << character->GetPosition() << "적 위치: " << enemy->GetPosition() << std::endl;
char input;
std::cout << "행동을 선택하세요" << std::endl;
std::cin >> input;
if (input == 'e')
{
std::cout << "도망쳤습니다" << std::endl;
break;
}
else if (input == 'a')
{
if (enemy->GetPosition() == character->GetPosition() + 1)
{
character->Attack(enemy);
}
else
{
std::cout << "공격을 했으나 닿지 않습니다." << std::endl;
}
}
else if (input == 'f')
{
if (enemy->GetPosition() > character->GetPosition() + 1)
{
character->Move(true);
}
else
{
std::cout << "적이 가로막고 있습니다" << std::endl;
}
}
else if (input == 'b')
{
if (0 < character->GetPosition())
{
character->Move(false); //뒤로가라
}
else
{
std::cout << "막다른 골목입니다" << std::endl; //0일때 출력
}
}
else if(input=='h')
{
character->Heal();
}
if (enemy->GetHP() <= 0)
{
delete(enemy); //포인터 안의 내용을 삭제하라
enemy = nullptr;
}
if (enemy == nullptr)
{
break;
}
if (enemy->GetPosition() == character->GetPosition() + 1) //적의 위치가 바로 내 앞일 때
{
enemy->Attack(character); //적은 날 공격
}
else
{
enemy->Move(true);
}
if (character->GetHP() <= 0)
{
delete(character);
character = nullptr;
}
if (character == nullptr)
{
break;
}
}
if (character == nullptr) {
break;
}
}
std::cout << "게임 끝" << std::endl;
}
이번 시간엔 정말 오랜만에 main코드 안에다가 주요 코드를 엮어 동작하는 작은 게임을 만들어보았다.
중간 중간 -> 기호때문에 잠깐 햇갈렸다가 다시 복습하니 코드가 이해가 되었다.
override 개념이 아직은 햇갈려서 나중에 게임을 만들게 되면 복습하는 시간을 가져봐야겠다!