Author Topic: overlapping key binds.  (Read 3482 times)

test84

  • Key Contributor
  • *****
  • Posts: 1328
  • Karma: +0/-0
  • ت
    • View Profile
    • My personal site.
overlapping key binds.
« on: Sun, Apr 29, 2012 »
Hi,

I use similar keys for some functions in my game, like pressing up let's the play but something, but also used when he can goes through a door and also cycles weapons. Problem is, when he presses up to buy something, other part of the code that is in charge of changing weapon also gets this new key press and changes the weapon.

As I'm at last days of working on this game, I don't want to change the whole code to have a proper "bind" system, as I think that's the best solution, so I would be interested in more quick solutions here.

And since I check for those inputs at different parts, I can't check for example if player is colliding with a door, then don't change weapon.

-test84
blog, twitter, Check out my award winning game, Rot Gut:

Redzeroine

  • Member
  • **
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #1 on: Sun, Apr 29, 2012 »
I'm still new to this but perhaps setting up a boolean system might be quicker? Like, if he overlaps with the door or is within a specific region, you could set up a boolean like overlapPlayerDoor to true and add it as an additional condition for your key binding using an AND operator.

like
if(FlxG.keys.justPressed("Up") && overlapPlayerDoor == true)
{
//add directives
}
else
{
//Add the directives for the weapon change system here
}

That's the quickest way I can think of.

boboshia

  • Member
  • **
  • Posts: 34
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #2 on: Sun, Apr 29, 2012 »
The dirty fix to things like this usually involves using a global variable that you would set to indicate that the player did in fact collide with a door, so the up key press has already been "used", therefore there is no need to change the weapon.

There are much better solutions than this, but a global would be easiest.  I usually handle all of the key press stuff in the the gamestate to avoid having keys trigger things in different places in the code, therefore avoiding problems like this.

test84

  • Key Contributor
  • *****
  • Posts: 1328
  • Karma: +0/-0
  • ت
    • View Profile
    • My personal site.
Re: overlapping key binds.
« Reply #3 on: Sun, Apr 29, 2012 »
There are much better solutions than this, but a global would be easiest.  I usually handle all of the key press stuff in the the gamestate to avoid having keys trigger things in different places in the code, therefore avoiding problems like this.

I really wish to use this approach but I'm afraid it's not that easy, at least in my code. And I tried to code as clear as possible, and it took me a loooong time to do so.

Let me elaborate more on the problem:

All my shops are along with items in a FlxGroup and in Playstate I check collision with this group and in the call back function, I call Shop public function of player and in that I check Up key and if it's true, I do the shopping.

In the player's update, I check for keyboard inputs (as I should do in PlayState's update, I think) and if UP is pressed, I cycle weapons.

So what do you think?

blog, twitter, Check out my award winning game, Rot Gut:

pixelomatic

  • Active Member
  • ***
  • Posts: 131
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #4 on: Sun, Apr 29, 2012 »
I'd make a boolean variable in player class called "shopping" which will be initially false. When shop() function is called, "shopping" flag will be true. In your update code, when "up" key is pressed, check "shopping" flag, if it's true do shop thing and if it's not do weapon cycling. And in last line of your player's update() code, reset your "shopping" flag to false (Because there is not a not-colliding function, so we are assuming we are not colliding with shop until it is changed by shop() function). I don't think it's a very dirty solution. But, if you want to go the design pattern way, you can check out state pattern. Imho, using a pattern for this kind of thing may be overengineering. And I think making the key-checks in only one place (e.g. player's update() function) will be more effective and easier to debug.

To clarify what I'm saying:

Code: [Select]
private _shopping = false;

// The collision callback.
public function shop():void {
    _shopping = true;
}

override public function update() {
    super.update();
    if (upKeyPressed) {
        if (_shopping)
            doShopping();
        else
            doWeaponCycling();
    }
    // ...... rest of the update code
    // And put flag resets here
    _shopping = false;
}
« Last Edit: Sun, Apr 29, 2012 by pixelomatic »

test84

  • Key Contributor
  • *****
  • Posts: 1328
  • Karma: +0/-0
  • ت
    • View Profile
    • My personal site.
Re: overlapping key binds.
« Reply #5 on: Wed, May 2, 2012 »
Thanks but the problem with that approach is it depends on in what order code is called.

I think I should have a class to handle keyboard and ask it if player should jump and in that class I prioritize order of things like some how find out if player can shop then return true for that and something like this but I can't get my head around it properly.

I'm trying to do this because I may assign 3 tasks for up arrow, shopping, cycling weapon and entering doors.
blog, twitter, Check out my award winning game, Rot Gut:

Berzee

  • Member
  • **
  • Posts: 69
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #6 on: Wed, May 2, 2012 »
the problem with that approach is it depends on in what order code is called

But doesn't the check for player/shop collision check happen either reliably before or reliably after the player.update(), each time through?

test84

  • Key Contributor
  • *****
  • Posts: 1328
  • Karma: +0/-0
  • ت
    • View Profile
    • My personal site.
Re: overlapping key binds.
« Reply #7 on: Wed, May 2, 2012 »
Sorry I didn't get you there:
But doesn't the check for player/shop collision check happen either reliably before or reliably after the player.update(), each time through?

I'm not sure what you mean but it can be always one frame late.
blog, twitter, Check out my award winning game, Rot Gut:

Berzee

  • Member
  • **
  • Posts: 69
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #8 on: Wed, May 2, 2012 »
I mean that you probably have something like this going on (basically what pixelomatic posted, much shortened)

Code: [Select]
// in PlayState

override public function update():void
{
     checkForShops(); //if it finds anything, disables weapon cycling for this frame
     super.update(); //player.update(), and hence weapon cycling, happens in here if it isn't disabled
}

So having code that depends on being called in a particular order shouldn't be too bad. Unless you have something very fancy going on where some frames check for shops first and other frames do weapon cycling first -- in which case, I resign. ;)

Edit: I read back over your posts again and you make it sound almost like you are checking for shops and doors asynchronously...but I didn't think that truly asynchronous stuff was possible with Flixel...but maybe I just have a limited understanding of what is possible. ^_^
« Last Edit: Wed, May 2, 2012 by Berzee »

test84

  • Key Contributor
  • *****
  • Posts: 1328
  • Karma: +0/-0
  • ت
    • View Profile
    • My personal site.
Re: overlapping key binds.
« Reply #9 on: Wed, May 2, 2012 »
Thanks but I feel very bad at doing such hack, despite what I asked for at first. What if I want to solve this properly?
blog, twitter, Check out my award winning game, Rot Gut:

Berzee

  • Member
  • **
  • Posts: 69
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #10 on: Wed, May 2, 2012 »
Not sure if this would still be what you consider a hack, but

what if you added a "currentShop" variable to the Player. Each frame, the PlayState can check for overlaps and set the player's current shop (or set it to null if there are no overlaps).

Then the Player class will have an idea of what to do when UP is pressed, just by checking if this.currentShop != null

At the very least, this gets all the keyboard input into one class =)

pixelomatic

  • Active Member
  • ***
  • Posts: 131
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #11 on: Wed, May 2, 2012 »
But doesn't the check for player/shop collision check happen either reliably before or reliably after the player.update(), each time through?

Of course it will happen reliaby. There is no multithreaded code. I'm assuming the state code is like this:
Code: [Select]
override public function update():void
{
      super.update();
      FlxG.overlap(player, shop, overlapShop)
}

private function overlapShop(player:Player, shop:Shop):void
{
      player.shop(); // Which will trigger the _shopping = true
}

You can clearly see what's happening here. super.update() calls update on every added object, including player. After updates are done, the collisions/overlaps get checked. So there is no need to panic.

If you are wondering, "I'm resetting the flag at end of update, how will it get triggered after all?". The overlap code is called after player's update. So, it will get executed at next update.

And for the last post of Berzee, I think it can be done. Instead of setting _shopping = true, you can set _currentShop = theOverlappingShop, if you have business with that Shop object itself.
« Last Edit: Wed, May 2, 2012 by pixelomatic »

test84

  • Key Contributor
  • *****
  • Posts: 1328
  • Karma: +0/-0
  • ت
    • View Profile
    • My personal site.
Re: overlapping key binds.
« Reply #12 on: Sat, May 5, 2012 »
Thanks. I like it and implemented and it works. My only concern is that I'm doing something specifically detail for the player in a very general place, PlayState's update call.
blog, twitter, Check out my award winning game, Rot Gut:

pixelomatic

  • Active Member
  • ***
  • Posts: 131
  • Karma: +0/-0
    • View Profile
Re: overlapping key binds.
« Reply #13 on: Sat, May 5, 2012 »
I'm not sure what you mean by that. But if you are concerned about your abstraction level, I wouldn't think more about it. You may be over-engineering. Making your code extendable and maintainable is a cool thing but if I were you I'd try to keep it in a reasonable level unless I am planning to make it some kind of framework (and we are already using flixel, making it into a sub framework would increase application complexity. Keeping inheritance tree minimal is essential for your mental health :)).