4

So I'm making a clone of Super Mario Bros in pygame. As of now I am in the middle of making my keypoll function, to check all the keys that are currently being pressed. I am wondering which would be better:

  1. Have the keypoll function modify marios attributes (ex. horizontal direction), then based on those, have mario decide which action he should be doing (ie. walk, run, jump, etc.) and call the function cooresponding to that action (ex. mario.moveHorz())

    OR

  2. Have the keypoll function call the function of the action he should be doing, and then the mario instance would decide what state he is currently in.

Here is some semi-pseudo code for the first one:

def doAction():
    if mario.horzDir == 'r' or 'l':
        mario.moveHorz()
    elif mario.action == 'jump':
        mario.jump()

 def keyPoll(keys):
    if keys[K_RIGHT]:
        mario.horzDir = 'r'
    elif keys[K_LEFT]:
        mario.horzDir = 'l'
    if keys[K_z]:
        mario.action = 'jump'

Here is some more semi-pseudo code for the second one:

def keyPoll(keys):
    if keys[K_RIGHT]:
        mario.moveHorz('r')
    elif keys[K_LEFT]:
        mario.moveHorz('l')
    if keys[K_z]:
        mario.jump()

def setProperties():
    if mario.x_vel > 0:
        mario.horzDir = 'r'
    elif mario.x_vel < 0:
        mario.horzDir = 'l'
    elif mario.y > ground:
        mario.action  = 'jump'

Both essentially accomplish the same thing, I just don't know which one is more correct.

Thanks!

2
  • 2
    The key polling should only set variables in your game model. Your animation loop should act on (get) the variables in your game model. This ensures that the key polling happens quickly (within one game cycle). Commented Jul 23, 2015 at 20:14
  • What do you mean? Could you put it in terms of my mario example?
    – Robbie
    Commented Jul 23, 2015 at 20:49

1 Answer 1

3

Because key polling usually happens at the very top of the game loop, the specific question you're asking is hard to separate completely from all the other extremely important issues one needs to be aware of when designing a game loop (Gilbert's comment appears to be referring to some of them). To get those out of the way, I'll simply suggest you read this: http://gameprogrammingpatterns.com/game-loop.html Now to answer your specific question.

It is better for your keypoll function to call mario methods than to set mario properties, mainly because all of these commands are going to have at least one or two extra steps beyond setting a field on the object. mario may have an internal state machine that keeps track of whether jumping or changing direction is even allowed in its current state. It may be keeping track of how many times it's been told to move right or left in the past several frames so it can speed up or slow down gradually. It may have yet more state to help it work out when you've done the inputs for various special combo moves. keyPoll() shouldn't have to know about any of that.

By setting a field and then calling a method to do all of this work, you're essentially doing in two steps what you could be doing with one step. That's usually not a good thing. Yes, it's likely that mario will have an update() or render() method to get called later on, but those should be completely separate from the methods for handling input.

Now, whether this is the best option depends on how complex your game is, but for most games, it's better to go even farther, and not have your keyPoll() function directly refer to mario at all. In principle, the only thing keyPoll() needs to do is check the state of the keyboard, and output zero or more objects that represent commands. If you ever want to support key rebinding or multiple control schemes, that logic would go in keyPoll(). Then the main loop gives these commands to whatever entity the player is currently controlling, presumably mario. By decoupling the input handling from the specific game entity, you make it easy to add new abilities to mario or support key rebinding or allow switching between multiple characters or add AI/demo characters and other cool stuff without having to worry about both the internals of keyPoll() and the internals of mario at the same time.

8
  • This is a great answer! I agree with what you say about decoupling mario and the state machine. If I were to do this, what would I do exactly? Would the main loop contain some variables about which keys are being pressed and then mario gets these variables and decides what to do? Also, I knew about the stuff posted in the first link, I just didn't think it was necessary. @lxrec
    – Robbie
    Commented Jul 24, 2015 at 18:08
  • 1
    @Robbie Yes, the main loop would have to store something returned by keyPoll() and then pass that into some method on mario. That's why I snuck in a link about the Command Pattern in my last paragraph; command objects are exactly the sort of thing keyPoll() ought to be returning.
    – Ixrec
    Commented Jul 24, 2015 at 18:15
  • Ok. So, pygame (the python extension i am using) has a built in function called key.get_pressed() that creates a list representing all the keys that are currently being pressed. Using this, would I even need to create a keypoll function in the main loop since I could just store the key.get_pressed() function as variable? @lxrec
    – Robbie
    Commented Jul 24, 2015 at 18:43
  • 1
    @Robbie If that really is all the input handling logic you want, then yes you wouldn't need your own function. But what about mouse/controller/joystick input? Holding down and releasing keys? Multiple or custom keybindings? And how does it handle international keyboards? I'd be willing to bet there's still some extra piece of logic you want that justifies giving it at least its own function.
    – Ixrec
    Commented Jul 24, 2015 at 18:48
  • @lxrec I see what you mean. I do want to eventually add other stuff, so for now I will just give it it's own function. Thanks!! This helped a lot
    – Robbie
    Commented Jul 24, 2015 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.