void Unit::changeState class Unit : public Sprite { public: bool init(); CREATE_FUNC(Unit); virtual void update(float delta); void changeState(UnitState* state); CC_SYNTHESIZE(UnitState*, _state, State); private: };
유닛 구조를 대충 잡고
class Swordman : public Unit { public: bool init(); CREATE_FUNC(Swordman); };
유닛 종류를 하나 만들어 주었다.
bool Swordman::init() { if (!Unit::init()) return false; _attackSpeed = 1.f; _moveSpeed = 30.0; this->setUnitName("swordman"); this->initWithFile("SpriteSource/swordman/swordman_walk_1.png"); AnimationManager::getInstance()->addAnimation(_unitName, "walk", 0.1f,{ "SpriteSource/swordman/swordman_walk_1.png", "SpriteSource/swordman/swordman_walk_2.png", "SpriteSource/swordman/swordman_walk_3.png", "SpriteSource/swordman/swordman_walk_4.png", "SpriteSource/swordman/swordman_walk_5.png", "SpriteSource/swordman/swordman_walk_6.png"}); this->changeState(UnitState_Walk::create()); return true; }
추가한 유닛 종류에 대해 셋팅도 해주고
(AnimationManager 클래스도 구현했는데, addAnimation클래스는 이미 있는지 검사해서 없으면 검사하는 클래스. 게임 시작할 때 한 번만 호출되게 바꿀 예정)
class UnitState : public Node { public: virtual void StartState(Unit* unit) = 0; virtual void RunState(Unit* unit) = 0; virtual void EndState(Unit* unit) = 0; };
상태에 대한 인터페이스도 정해주었다.
class UnitState_Walk : public UnitState { public: CREATE_FUNC(UnitState_Walk); bool init() { return true; } void StartState(Unit* unit); void RunState(Unit* unit); void EndState(Unit* unit); }; void UnitState_Walk::StartState(Unit* unit) { auto animation = AnimationManager::getInstance()->getAnimation(unit->getUnitName(), "walk"); auto animate = Animate::create(animation); unit->runAction(RepeatForever::create(animate)); auto moveAction = MoveBy::create(1.f, Vec2(-unit->getMoveSpeed()*3, 0)); unit->runAction(RepeatForever::create(moveAction)); } void UnitState_Walk::RunState(Unit* unit) { if (unit->getPositionX() < 10) { unit->removeFromParentAndCleanup(true); } } void UnitState_Walk::EndState(Unit* unit) { }
state 인터페이스를 상속받아 걷는 상태를 구현하였다.
bool BattleScene::onSprTouchBegan(Touch* touch, Event* event) { auto target = event->getCurrentTarget(); Point pos = target->convertToNodeSpace(touch->getLocation()); Rect rect = Rect(0, 100, target->getContentSize().width, 320); if (rect.containsPoint(pos)) { auto swordman = Swordman::create(); swordman->setPosition(pos); this->addChild(swordman,2); swordman->scheduleUpdate(); } return false; }
그 다음 클릭할 때마다 생성되게 해놓으면
autorelease pool도 잘 작동하고 있는 것을 볼 수 있다.
처음에는 std::unordered_map으로 짰다가 바로 버그를 여러개 만들었는데, cocos2d::Map으로 바꿔서 간단하게 해결하였다.
역시 엔진에서 정해놓은 대로 쓰는 것이 맘 편한 듯..
상태 머신을 처음으로 구현해본데다, 그냥 느낌 가는대로 만들어서 이렇게 만들어도 되는 것인지 잘 모르겠다.
기능 하나씩 추가하다 보면 분명 문제가 생기지 않을까?
그러면 그때 또 해결하는 것이 공부가 되겠지~
'개발일지 > SiegeMode!' 카테고리의 다른 글
많은 버그를 잡고, 구조도 많이 수정했다. (0) | 2016.05.11 |
---|---|
전투시스템도 대충 구현했다. (0) | 2016.04.30 |
SiegeMode! 모바일 버전 컨셉 스크린샷 완성. (0) | 2016.04.12 |
모바일에서는 아무리 생각해도 사이드뷰가 나을 것 같다. (0) | 2016.04.10 |
SiegeMode! 1차 기획 완료 (1) | 2016.04.09 |