Stuck on Cocos2d-x Basics :)

I’m writing my first project and I’m in trouble with things that someone more skilled surely knows :grin:

In my simplified scenario I have defined the layer GameLayer like this

bool GameLayer::init() {
  ...
  auto eventListener = EventListenerKeyboard::create();
  eventListener->onKeyPressed = [&](EventKeyboard::KeyCode keyCode, Event* event) {
    DoAction();
  };
  _eventDispatcher->addEventListenerWithSceneGraphPriority(eventListener, this); 
  return true;
}

For my example purposes GameLayer has 2 members:

MySprite* m_pMySprite;

and

bool m_bActionRunning;

Now the problems :sweat:

I have defined GameLayer::DoAction this way

void GameLayer::ParseInput(Direction direction) {

  if (m_bActionRunning) return;
  m_bActionRunning = true;

  CallFunc* restoreCallback = CallFunc::create([&]() { m_bActionRunning = false; });
  
  runAction(Sequence::create(
    mySprite->DoAction(),
    restoreCallback 
  ));

and MySprite::DoAction() this way

Sequence* MySprite::DoAction() {
  // update MySprite internal state
  CallFunc* updateMySpriteInternalState = CallFunc::create([&]() {
    m_PositionX = m_PositionX + 100;
  }
  // update MySprite graphical state (using m_PositionX)
  TargetedAction* updateMySpritePosition = TargetedAction::create(this, MoveTo::create(5.0f, Vec2(0, m_PositionX)));
 // returns the sequence
  return Sequence::create(
    updateMySpriteInternalState ,
    updateMySpritePosition,
    nullptr
  );
}

Since I want to keep separation logic I have defined MySprite behaviour in MySprite and not in GameLayer. GameLayer can do something on m_pMySprite returning and running the sequence object returned from m_pMySprite->DoAction(). Also at the end of the sequence GameLayer restores m_bActionRunning enabling other inputs.

Well, my questions are pretty simple

  1. is this design pattern logical or it is completely non-sense?
  2. updateMySpritePosition runs a targeted action that requires m_PositionX incremented by 100, but when the action is created m_PositionX is not incrementd because updateMySpriteInternalState is not executed yet. How can I have such variable incremented instead?

Hi.
The action system in cocos helps you separate sprite properties and sprite behaviour (called actions).
Then don’t combine them.
You ask question about design pattern. I think my style is a good one in cocos2d-x.
I create a discussion about design pattern for games.

Thank you for your time. I’m not sure to understand when you say

Basically in my example I’m returning a Sequence to update both sprite properties and sprite position (with a TargetedAction). If the caller doesn’t run the sequence, the sprite simply doesn’t change. In my head this looks good. Why should I separate sprite properties and behaviour?

because you can reuse this action for another sprite.
With 4 different sprites and 4 different actions you can create 4*4 = 16 behaviours. But with 4 sprites (all have own actions) you can create 4 behaviours.

So you are saying I should define my 4 different actions inside the GameLayer and remember to update both sprite properties and positions (with different calls)? This looks quite dangerous to me. What happens if i run the action but I forgot to update the internal state? In pattern I tried to implement such problem never happens.

you can update internal state of sprites with actions. (maybe custom actions)

Ok, I’ll think about what you are saying.
Thanks for your time :smile: