I thought I'd finally tackle this, but I guess I should see if anyone else has tried anything similar first...
I don't like letting go of a movement key, and having my character keep going a few steps before stopping. It seems like there is an input buffer if you hold a key down, and the buffer has to empty before you stop. I'd much prefer a screeching halt.
I'm going to see if I can squash this programatically. Has anyone else done anything similar to this before I start?
/mob/skysaw
ID:150313
Nov 7 2001, 9:21 am
|
|
In my games, I handle movement a little differently. pressing the movement keys just sets the mob's action variable. Every action cycle, the program looks at the action variable to see what action to perform. Only the last action entered gets processed, no matter how many keys they mash.
If you want to see a brief demo, let me know. I have one around here somewhere from when I was going to release it as a library. |
In response to Shadowdarke
|
|
Shadowdarke wrote:
In my games, I handle movement a little differently. pressing the movement keys just sets the mob's action variable. Every action cycle, the program looks at the action variable to see what action to perform. Only the last action entered gets processed, no matter how many keys they mash. This is sort of the direction I was thinking in. I was pretty sure I'd have to override the existing movement commands. Sounds pretty easy to code, but if you have time to post a demo that would be nice. |
In response to Skysaw
|
|
Here is the bare bones of the movement scheme I use for Darke Dungeon and Tanks. I use the status cycle to do several things unrelated to movement, so it spawns each tick. If you are only using it for movement, you might want to get rid of the speed system here and just spawn the statuscycle after an appropriate delay.
// Increase or decrease ACTIONRATE to slow down or spead up ALL mobs // lower = faster #define ACTIONRATE 30 mob var speed = 10 // change this to make a mob faster or slower. Higher = faster tmp action = "" // what the player is trying to do speedcounter = 0 // keeps track of when the mob can act proc statuscycle() speedcounter += speed if (speedcounter >= ACTIONRATE) speedcounter -= ACTIONRATE // I only subtract instead of clearing it to 0 so faster // mobs can get a little headstart in the next cycle if // there are a few points left over. switch (action) if ("") // do nothing if ("move") step(src,dir) // define any other actions here else world.log << "Unknown action:[action]\n src:[src]" action = "" // clear the action spawn() statuscycle() New() ..() // kick off the statuscycle() when a mob is created spawn() statuscycle() client // overide all the directional procs North() mob.action = "move" mob.dir = NORTH South() mob.action = "move" mob.dir = SOUTH East() mob.action = "move" mob.dir = EAST West() mob.action = "move" mob.dir = WEST Northeast() mob.action = "move" mob.dir = NORTHEAST Southeast() mob.action = "move" mob.dir = SOUTHEAST Northwest() mob.action = "move" mob.dir = NORTHWEST Southwest() mob.action = "move" mob.dir = SOUTHWEST |
In response to Air Mapster
|
|
Air Mapster wrote:
if anyone can prove me wrong regarding the hardware/OS stuff above, by all means do so! My understanding is not complete, but I believe it describes the situation fairly well. You can trap keypresses with software. I don't remember the addresses, but everytime you press a key it sends a signal. Releasing the key sends a different signal. You can keep track of several keys being held down at once. It's not very well documented and I had to dig through a lot of reference books before I finally found it. Most texts I read take you down to the layer of the keyboard buffer (which is a hardware function, I think) and leave you there without digging any further. I'll look up the C code to do this later when I get home if you want it. I think I got it from an old book called "Secrets of the Game Programming Gurus" or something like that. It walks you through the process of making a Doom style game in C with a little ASM. |
In response to Shadowdarke
|
|
I wonder if this system might still be prone to the movement buffer problem. Won't buffered keystrokes still be setting the action to move?
|
In response to Skysaw
|
|
Skysaw wrote:
I wonder if this system might still be prone to the movement buffer problem. Won't buffered keystrokes still be setting the action to move? The keystrokes keep setting action to "move", but it doesn't matter how many times the action is changed. All that matters is what action is set to when speedcounter goes over ACTIONRATE. Sometimes with this system you might take one step too many, but that's rare. If the network lag is really bad and your packets are arriving late, you might get semisporadic movement, but there is nothing that can be done about that until the internet becomes perfect :P If you want to see that movement system in action, try out Tanks. It's a rotational movement system, but the core is still the same. When you press up, it sets the tank's action to "move". You can see if it prevents the trouble you're having. (Rotation in Tanks doesn't set the player's action, so sometimes you will get problems with rotating too far or wiggling back and forth as you try to get to the right direction on a laggy server.) |
In response to Shadowdarke
|
|
Here you go, Mapster. The raw keyboard code for my old C version of Dungeon Delvers (that never made it much past the input routines :/) To be honest, I'm not even certain it will work with modern computers.
<big><font color=red>C code! Do not try this in DM.</font></big> // Raw Keyboard Interface I stripped out the diagonals to remove some clutter and still leave a usable hunk of code. I'll dig up a list of the raw key codes if you want them. The key release codes are the same as the key down code + 128. |
Furthermore, there is the problem of network delay. When the server is somewhere else on the network, I believe it has no way of distinguishing between actual movement keypress messages and further repeated messages after the key has been released.
Of course, adding a small delay to movement (even one tick might suffice) to ensure that DreamSeeker doesn't lag too far behind the keypress events due to network/graphics/etc overhead may work well enough. This has been done many times and I'm sure you know how to do that.
I'm curious how you intended to tackle the problem? Also if anyone can prove me wrong regarding the hardware/OS stuff above, by all means do so! My understanding is not complete, but I believe it describes the situation fairly well.