Game Development Community

Do you have a good understanding of the movement component?

by Randy Lutcavich · in Torque X 2D · 08/07/2009 (8:11 pm) · 12 replies

I've attached the default movement component to my player but by default the player is allowed to move up/down and left/right.

I only want my player to be able to move up/down when there is a ladder tile present. I'll figure out the tile part later, I just don't understand how to turn the up/down movement on/off on command. Does anyone have any ideas?

#1
08/07/2009 (11:23 pm)
The default movement component is really just an example to show you how components work and how you can do input. If you edit it, particularly it's ProcessTick Method, you can easily get rid of the movement up/down. If you throw in a flag for it, you can easily turn it off/on with a simple if statement.
#2
08/07/2009 (11:43 pm)
I find it's best to set up a switch statement with a bunch of flags for movement early, as you'll probably use/need it eventually.

Also, for the ladder: as far as I've seen in some recent threads grabbing the tile is fairly hard (never had experience with it myself) so try setting up a T2DTriggerComponent at your ladder. It will at least work for testing and may be a lot faster to prototype than a tile-grabber
#3
08/08/2009 (5:18 pm)
Thank you both for responding. By setting flags do you mean setting up events? Is there anyway you could possibly show me what this would look like in the movement component or point me to a resource on this?
#4
08/08/2009 (9:02 pm)
I'd say the use of flags is meant as in boolean variables, for instance bCanMoveVert. In the ProcessTick() method, you would restrict the part that responds to Y movement on the controller to only happen when that variable is true. The TriggerComp is a good idea; set the bool to true in the OnEnter callback and false in the OnLeave. That should do the trick.
#5
08/08/2009 (9:17 pm)
Ah, see I tried this yesterday. I guess my confusion lies in the default movement component. I'm not sure exactly where to put the if statements with the boolean variables. Here's what I tried and why it didn't work...


Currently the movement component sets up WASD controls like this:
inputMap.BindMove(keyboardId, (int)Keys.D,MoveMapTypes.StickDigitalRight, 0);
inputMap.BindMove(keyboardId, (int)Keys.A,MoveMapTypes.StickDigitalLeft, 0);
inputMap.BindMove(keyboardId, (int)Keys.W, MoveMapTypes.StickDigitalUp, 0);
inputMap.BindMove(keyboardId, (int)Keys.S,MoveMapTypes.StickDigitalDown, 0);

I'm just not familiar with movemaps. I don't know where these button presses lead. If I set up an if statement to block any of these buttons from being mapped, the button will never be mapped because this function that this input map is in is only called once.

The second place I tried adding a flag was in the process tick. Here's what I tried:
if (move != null)
{
     // set our test object's Velocity based on stick/keyboard input
     _sceneObject.Physics.VelocityX = move.Sticks[0].X * 20.0f;

     if (ladderFound)
     {
          _sceneObject.Physics.VelocityY = -move.Sticks[0].Y * 20.0f;
          ladderFound = false;
     }
}
But this doesn't work because this is called on every tick so when I started out with ladderFound being true the code will process and ladderFound will be set to false before the player can even press WASD. I don't think this would be a problem if I could have the key press set ladderFound to true but I can't seem to have a key mapped to two different methods (unless you guys know a way) and it is already mapped to 'MoveMapTypes.StickDigitalUp', whatever that is.
#6
08/09/2009 (12:22 am)
Pretty much it maps your keyboard keys to a virtual stick. If you press a, it makes the X value of the vector negative(-1), while d makes the X value positive. S makes the Y value negative, while W makes makes the Y value positive. Anywho, its set that way for movement as you'll often have those for a stick on your controller.

Anywho, you technically don't need to make ladderFound false in that if statement. The idea is you'll have something externally setting it and I would guess that it would also reset it when you leave the ladder area. A custom collider could do that, or a trigger component that talks to the movement component and messes with your flag.

With a trigger, you'd have the OnEnter Delegate say ladderFound = true, while the OnLeave Delegate would say it is false. You just need to check if theirObject(it's passed through the delegate) has a movement component and then set that flag the way you want to.
#7
08/09/2009 (12:55 am)
Ah, thanks for explaining the input map.

My concern with the trigger is that I plan to have a tilemap with hundreds of tiles that potentially could be changed to a ladder. I'm not sure using hundreds of triggers is a wise move. I need to think on this one. Thanks again!
#8
08/09/2009 (1:03 am)
Well, since you've basically got how to grab if it's a tile based on your older threads. You can always just add that check to the movement component instead of the flag.

Like put a function where it checks if its over a tilemap and if the tiles its colliding are a ladder. So maybe right a function that does that and if it returns true allow movement on the y axis.

The trigger ends up just being a simple collision check, while checking yourself may end up more intensive.
#9
08/09/2009 (1:26 am)
I think how I want to do this is rewrite the movement component starting with the up movement.

I'll make a collision trigger for the base of my building and the row of tiles above that. When the player enters this trigger this means they can now move up. But when the player goes to move up for the first time it replaces that tile with a ladder (as you've seen from my previous posts, I now know how to do this). Then if the player presses up again they will move to the tile above and it will be replaced by a ladder. When the player is in the second row trigger the player cannot move sideways like normal. Instead I want to replace the left/right movement methods to build a sideways ladder (platform). At this point any movements up/down or left/right will start with a check to see if the tile has a ladder, if it doesn't it places one. If it does, the player just moves to the new tile. Once the player reaches the base row again, they are free to move sideways again without a sideways ladder (platform). An attempt to move up on the base row is treated like the very first tile again, meaning if there isn't a ladder one must be placed before moving up. Once the player leaves the base row trigger they can no longer build ladders to move up.

That is my design but I'm not sure exactly how to implement it. I've always used the movement component so I'm not even sure how to move the sprite manually. I'll also have troubles changing button functionality in different rows. But maybe this can simply be done by just changing input maps when entering/exiting the row triggers.
#10
08/17/2009 (1:28 am)
Alright, I am back to this thread. I know now how to create a trigger. Now I just need to create a custom inputMap when the player enters the trigger.

First things first... clearing the old inputMap.

public static void newInputmap(T2DSceneObject ourObject, T2DSceneObject theirObject)
        {
            T2DSceneObject _sceneObject = TorqueObjectDatabase.Instance.FindObject<T2DStaticSprite>("player");
            InputMap inputMap = PlayerManager.Instance.GetPlayer(0).InputMap;
            inputMap.BindMove(0, (int)Keys.B, MoveMapTypes.StickDigitalLeft, 0);
            InputManager.Instance.PopInputMap(inputMap);
            _sceneObject.Physics.VelocityX = 0;
            _sceneObject.Physics.VelocityY = 0;
        }

I tried simply popping the old inputMap but this causes the player to continue moving in the direction that they were moving when they entered the trigger. I then tried setting the player's velocity to 0 but that didn't stop the player.

My first question is, how can I clear the button press?

I really don't understand how physics and/or the movement component is supposed to work in this engine. Any advice would be nice. :)
#11
09/01/2009 (7:59 pm)
I posted this thread about how to undo a particular input binding.

For the third line in your newInputMap function, you forgot the first parameter is needed to specify the device number; plus you would use -1 as the index at the end of that call, not 0:
inputMap.BindMove(InputManager.Instance.FindDevice("keyboard"), (int)Keys.B, MoveMapTypes.StickDigitalLeft, -1);
#12
09/01/2009 (11:09 pm)
Great work Scott! I'll definitely use your resource when this comes up again for me.