Handling key events properly for smoothly moving of actor

Hi,

(Please bear with me, as I dont have access to my computer at this time. Writing in my phone)

I noticed the following: I defined a callback function to move the actor, which adds an amount to one of the actor’s coord. If i set it to “somekey”, the actor will move once by that amount increment, even if i hold the key down. If i set it to “somekey-repeat”, actor will constantly move, however theres a lag in response since i press the key and it starts moving. So i figured out Id need to bind this callback to both key definitions, right? Wrong. When i bind it to both of them, actor will start moving the moment i press the key, a small lapse will follow where the actor wont move, then itll start moving as expected.

So, how to overcome this lapse? Im thinking on the lines of changing the callback so that it sets a flag for movement instead of actually moving the actor therein, then have another time driven function which will actually operate depending on this flag. Would this be the right approach? Could you provide a code example on how to implement this? Even if mine is not the right approach, could you provide a code example for your suggestions?

Thanks in advance!

Just for the sake of completeness (and for a covered bump :laughing:) I’m posting the relevant chunks of code:

...snip...
struct datos_ke{NodePath* np; AnimControl* ac;};
...snip...

void ke_adelante(const Event *, void *datos)
{
    AnimControl *ac=((datos_ke*)datos)->ac;
    NodePath *actor=((datos_ke*)datos)->np;
    ac->loop(false);
    //actor->set_pos(actor->get_pos()+LVecBase3f(0,-0.05,0));
    actor->set_y(actor->get_y()-0.05);
}
void ke_adelante_para(const Event *, void *datos)
{
    AnimControl *ac=((datos_ke*)datos)->ac;
    ac->stop();
}

int main(int argc, char *argv[]) {
...snip...
datos_ke datos={&pandaActor, animc.get_anim(0)};
...snip...
framework.define_key("w", "Mover adelante", ke_adelante, &datos);
framework.define_key("w-repeat", "Mover adelante", ke_adelante, &datos);
framework.define_key("w-up", "Mover adelante PARAR", ke_adelante_para, &datos);
...snip...
}

I’d appreciate suggestions on how to solve my problem. I can’t think of any other thing than to solve this by setting a flag, then having a function check it and act accordingly every X ms, as I said, but maybe this is not the right approach, and anyways I don’t know how to do that in Panda3D yet… Help, please.

hi,

being italian myself I can read spanish alright but as a suggestion for future project I recommend using english language as your primary language in code. It makes it easier for 99% of people who are trying to help you AND it allows you to improve your professional communication skills (in case you intend to join the industry).

and now a response to your problem :slight_smile:

a good and commonly used approach for game logic such as the move code is something like this :

Entity::Update()
{
    sInput input;
    sOutput output;
    UpdateAITasks(input, output);
    UpdatePhysics(input, output);  
    UpdateAnimations(output);
    PostUpdatePhysics();
}

sInput : contains relevant data like “the this pointer of entity” , various supplemental initial information.
sOutput is the updated information the game code will update itself on.
Both structs are build on the stack therefore you can use quite a lot of “space” wihout actually trashing your memory or storing too much data (work data i.e.).

In your case the UpdateAITasks function would setup the “output” of a virtual gamepad to be “walking, running, stop” or whatever other information you want. The update physics would deal with the movement and colision passed through “output” and the animationUpdate would actually play your “walk-run-cycle”.

so even simpler :

UpdateAITasks - collect the button presses
UpdatePhysics - work out the position after colision checks
UpdateAnimations - play the animatios requested according to the current status of your entity (after ai AND physics are applied).

In your AITask (where you would be catching button presses) i.e. in the PlayerOnFoot task - you use simply a statement like this :

void cPlayerOnFoot::Update(const sInput& input, sOutput& output)
{
  if(gamepad.KeyPressed('W') || gamepad.KeyHold('W') )
  {
    output.gamepad.SetWalking();
  }
   //do loads of other stuff
}

hope that helps a bit to get a general idea :slight_smile:

Chrys

Hi and thank you for your reply.

Firstly, let me say your recommendation about not writing in my native language has been heard. However I dont see how the naming of several variables, functions or descriptive strings can pose a problem for the audience (target being knowledgeable people in these matters) of my question, since I also gave a explanation of what my code does and what my problem was. The main reason for naming in my native language, is of course, confort, and secondly grasping meaning at first sight since Im a newbie in this. Naming in english is certainly not the best option for me. But if I’m not going to get good feedback just because of this or it bothers someone, then Ill consider translating my code before posting, which Im not sure whether itll take more or less effort than naming in english right away in the first place. Maybe some other forumer can add to this so to change the odds so I can make my choice. And no, Im not planning to join the industry…they wouidn’t want me anyways :laughing:

Secondly, I appreciate your effort in your explanation, I really do! But im not going to lie to you: I didnt understand most of what was explained, if only, I got a general and slight idea that this is the general workflow for games. Now, if I wanted to put this into code I just wouldnt know how to do it. But your mention of tasks made me think maybe I should look into using a task to handle actors movement, and so I did and solved my problem. However Im very much interested in this kind of workflow you explained, as I will have to deal with other problems later and there’s no need to reinvent the wheel and I dont want to waste time nor effort dealing with messy code. So if you or anyone else is willing to further explain this and hopefully add code examples specific to Panda3D, Ill be more than happy.

Again, thank you very much.

Regards