ID:2172668
 
(See the best response by Ter13.)
Hello friends and fellow programmers, I have come for help once again. I am at the moment working on a way to go faster as the player run, so that they do not go at full speed as soon as they press the arrow key. Would I tried to do was make it so that the game checks if you are running after about a second thus increasing said speed. I attempted to test this by using spawn(), the message "HEY", and moving as the variable it checks. It does in fact wait the time to do the next code, but it spams the message, even if you stop running. Would I instead need a proc?

        if(src.moving==0)
spawn(20)
if(src.moving==0)
usr<<"HEY"
else
return



Something like this would fit better.
mob
var
startrunning=0
Move()
//After you main movement codes
if(!startrunning)
startrunning=1
spawn(20)
startrunning=0
usr<<"HEY"
Best response
Spawn should be avoided except where absolutely necessary.

client
verb
//set up macro "Any" as key, keyPress "[[*]]" as command
keyPress(key as text)
set hidden = 1
set instant = 1
mob.onKeyPress(key)

//set up macro "Any+UP" as key, keyRelease "[[*]]" as command
keyRelease(key as text)
set hidden = 1
set instant = 1
mob.onKeyRelease(key)

//disable default movement (it's shit.)
North()
Northeast()
East()
Southeast()
South()
Southwest()
West()
Northwest()

mob
var
min_step_size = 1 //how fast we move at min speed
max_step_size = 16 //how fast we move at max speed
acceleration_time = 30 //three seconds to get to full speed
tmp
move_start
move_keys = 0
move_dir = 0

Login()
MoveLoop()
..()

Logout()
move_keys = 0
move_dir = 0
move_start = null

proc
//called from client/keyPress()
onKeyPress(key)
switch(key)
if("W")
onMoveKey(1,1)
if("A")
onMoveKey(8,1)
if("S")
onMoveKey(2,1)
if("D")
onMoveKey(4,1)

//called from client/keyRelease()
onKeyRelease(key)
switch(key)
if("W")
onMoveKey(1,0)
if("A")
onMoveKey(8,0)
if("S")
onMoveKey(2,0)
if("D")
onMoveKey(4,0)

//called when a movement key is pressed or released
onMoveKey(dir,state)
var/opp = turn(dir,180)
if(state) //if the button is being pressed
if(!move_keys) move_start = world.time //keep track of when we started moving

move_keys |= dir //turn on the direction bit
if(move_keys&opp) //turn off the opposite direction bit if applicable
move_dir &= ~opp
move_dir |= dir
else //or released
move_keys &= ~dir //turn off the direction bit
if(move_keys&opp) //turn on the opposite direction bit if applicable
move_dir |= opp
move_dir &= ~dir

if(!move_keys) move_start = null //reset the move_start tracker

//called at client/Login() to keep track of movement keys and apply them to motion
MoveLoop()
set waitfor = 0
var/acceleration
var/client/c = client
while(client&&client==c) //loop as long as we have a client
if(move_dir) //if the player is attempting to move
acceleration = min((world.time-move_start)/acceleration_time,1) //get the acceleration percentage along a linear curve.
step_size = max(min_step_size,max_step_size*acceleration) //reset the step_size
step(src,move_dir) //perform a step in move_dir direction at current step_size
sleep(world.tick_lag) //sleep for one tick


Control loops work MUCH better than BYOND's built-in setup, to be honest.
In response to Ter13
Ter13 wrote:
Spawn should be avoided except where absolutely necessary.

> client
> verb
> //set up macro "Any" as key, keyPress "[[*]]" as command
> keyPress(key as text)
> mob.onKeyPress(key)
>
> //set up macro "Any+UP" as key, keyRelease "[[*]]" as command
> keyRelease(key as text)
> mob.onKeyRelease(key)
>
> //disable default movement (it's shit.)
> North()
> Northeast()
> East()
> Southeast()
> South()
> Southwest()
> West()
> Northwest()
>
> mob
> var
> min_step_size = 1 //how fast we move at min speed
> max_step_size = 16 //how fast we move at max speed
> acceleration_time = 30 //three seconds to get to full speed
> tmp
> move_start
> move_keys = 0
> move_dir = 0
>
> Login()
> MoveLoop()
> ..()
>
> Logout()
> move_keys = 0
> move_dir = 0
> move_start = null
>
> proc
> //called from client/keyPress()
> onKeyPress(key)
> switch(key)
> if("W")
> onMoveKey(1,1)
> if("A")
> onMoveKey(8,1)
> if("S")
> onMoveKey(2,1)
> if("D")
> onMoveKey(4,1)
>
> //called from client/keyRelease()
> onKeyRelease(key)
> switch(key)
> if("W")
> onMoveKey(1,0)
> if("A")
> onMoveKey(8,0)
> if("S")
> onMoveKey(2,0)
> if("D")
> onMoveKey(4,0)
>
> //called when a movement key is pressed or released
> onMoveKey(dir,state)
> var/opp = turn(dir,180)
> if(state) //if the button is being pressed
> if(!move_keys) move_start = world.time //keep track of when we started moving
>
> move_keys |= dir //turn on the direction bit
> if(move_keys&opp) //turn off the opposite direction bit if applicable
> move_dir &= ~opp
> move_dir |= dir
> else //or released
> move_keys &= ~dir //turn off the direction bit
> if(move_keys&opp) //turn on the opposite direction bit if applicable
> move_dir |= opp
> move_dir &= ~dir
>
> if(!move_keys) move_start = null //reset the move_start tracker
>
> //called at client/Login() to keep track of movement keys and apply them to motion
> MoveLoop()
> set waitfor = 0
> var/acceleration
> var/client/c = client
> while(client&&client==c) //loop as long as we have a client
> if(move_dir) //if the player is attempting to move
> acceleration = min((world.time-move_start)/acceleration_time,1) //get the acceleration percentage along a linear curve.
> step_size = max(min_step_size,max_step_size*acceleration) //reset the step_size
> step(src,move_dir) //perform a step in move_dir direction at current step_size
> sleep(world.tick_lag) //sleep for one tick
>

Control loops work MUCH better than BYOND's built-in setup, to be honest.

Hey, I am a bit confused by some of the coding. When ever I press a key that you said use as macro, they show up as text each time.
The "Any" macro is still in beta. It can be used to track the press and release events of any button on the keyboard or gamepad, without needing a separate macro for every individual key, by providing the name of the key as an argument to the verb.
In response to Universe_Steven
Universe_Steven wrote:
Hey, I am a bit confused by some of the coding. When ever I press a key that you said use as macro, they show up as text each time.

Did you set up the macros in the interface editor?

Open your interface file (.dmf file). If you don't have one, create one via File->New.

Double click on the default macro set in the top box.

Now edit the macro set in the skin editor. Delete every macro.

Add a new macro:

Key: Any
Command: keyPress "[[*]]"

Add another new macro:

Key: Any+UP
Command: keyRelease "[[*]]"

Save. Compile. Run.

Is there anything else you are struggling with?
I deleted the default macro set, created macro with the button X and had the command: keyPress then I created one that was X+UP and the command was : keyRelease. When I tested it not only could I not move, but it only created x's in the text input box.
That is because you only defined a macro for x. Key: Any, Any+Up...
I don't mean any key. I mean literally the key value should be "Any".
In response to Ter13
Thank youuu ter13, your movement system is awesome, how can i make this: when the character is walking northwest and then it hits a wall at north, it stops, how can i make it still going west?
In response to STa
STa wrote:
Thank youuu ter13, your movement system is awesome, how can i make this: when the character is walking northwest and then it hits a wall at north, it stops, how can i make it still going west?

I think he means edge sliding.