Controlling movement with keyboard

Started by Jam Torkberg, Wed 03/09/2003 23:25:20

Previous topic - Next topic

Jam Torkberg

Edit by strazer: Superseded by the KeyboardMovement script module.

--

Telling the character to move about with simple keystrokes is easy enough.  Tapping left, for example, can be used to make the character walk as far to the left as possible, until he hits the edge of a walkable area.

But what if one wants to use the keyboard in a more digital sense, moving the character if the button is held down and having the character stop if the button is released.

I've tried several methods to accomplish this, but to no avail.  In all cases, holding down the button causes the character to stay in place and jerk about.  I can see why this would happen, I just can't see how to fix it.

Thoughts?
"Now it's over I'm dead and I haven't
done anything that I want
or, I'm still alive
and there's nothing I want to do."

Ishmael

I noticed this too... Every time a nwe MoveCharacter is ran, the characteris stopped. I see MoveCharacterPath does the same.... I see it logical that MoveCharacterPath should work, since you can us it to add waypoints to the characters path. If you use it in cutscene or so, does it stop the character and start it moving to the new point, without finishing the current set path?
I used to make games but then I took an IRC in the knee.

<Calin> Ishmael looks awesome all the time
\( Ö)/ ¬(Ö ) | Ja minähän en keskellä kirkasta päivää lähden minnekään juoksentelemaan ilman housuja.

Scorpiorus

#2
Yes, every MoveCharacter() call first stops the previous movement. You may find it useful to use a-v-o's movement script: (EDIT: See Hollister Man's reply lower down for the complete script)

-Cheers

Jam Torkberg

#3
Well, I've added a-v-o's code and it works perfectly.  But I'm a picky bastard, and have to take things one step further.

My thought is to have things such that if you the player presses two arrow keys at the same time the character will move diagonally.  For example, is one presses the up and right arrow keys at the same time the charater move up and to the right (fuh).

Here is an expert from a-v-o's code
Quoteif ((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0)) Direction = DIR_UP_LEFT;    // 7 Home (numeric pad)
   else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP;         // 8 Up arrow
   else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0)) Direction = DIR_UP_RIGHT;   // 9 PgUp (numeric pad)
   else if ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT;       // 4 Left arrow
   else if ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP;       // 5 Stop (numeric pad)
   else if ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT;      // 6 Right arrow
   else if ((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0)) Direction = DIR_DOWN_LEFT;  // 1 End (numeric pad)
   else if ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN;       // 2 Down arrow
   else if ((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0)) Direction = DIR_DOWN_RIGHT; // 3 PgDn (numeric pad)
   else Direction = DIR_STOP;


And here is the same, with my additions:
Quoteif ((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_UP_LEFT;
   else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP;        
   else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (377) > 0))) Direction = DIR_UP_RIGHT;  
   else if ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT;      
   else if ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP;      
   else if ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT;      
   else if ((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_DOWN_LEFT;
   else if ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN;      
   else if ((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (377) > 0))) Direction =DIR_DOWN_RIGHT;
else Direction = DIR_STOP;

So here's the problem.  The above works, but only for up and left.  AND!!! If I were to switch, say, the code for up-left with that of up-right, than up right would be the only combination that works.  In other words, it is only the first bit of code.  I don't know if all the ||s and &&s are fouling things up, or the “else if”s, but something is going on.

It is not the end of the world if these never works, but I am mostly just curious as to why it only half works, for reference in later coding escapades.  Any thoughts?
"Now it's over I'm dead and I haven't
done anything that I want
or, I'm still alive
and there's nothing I want to do."

Scorpiorus

Quoteif ((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_UP_LEFT;
else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP;
else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (377) > 0))) Direction = DIR_UP_RIGHT;
else if ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT;
else if ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP;
else if ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT;
else if ((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_DOWN_LEFT;
else if ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN;
else if ((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (377) > 0))) Direction =DIR_DOWN_RIGHT;
else Direction = DIR_STOP;
When you press UP+RIGHT AGS first checks else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP; line and since the UP key (372) is pressed it goes UP. The else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (377) > 0))) Direction = DIR_UP_RIGHT; code is not even get checked.

So you need another IFs order:

First diagonals:
Quote
if ((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_UP_LEFT;
else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (377) > 0))) Direction = DIR_UP_RIGHT;
else if ((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_DOWN_LEFT;
else if ((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (377) > 0))) Direction =DIR_DOWN_RIGHT;

The rest:
Quote
else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP;
else if ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT;
else if ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP;
else if ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT;
else if ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN;
else Direction = DIR_STOP;

How does it go?

-Cheers

Jam Torkberg

#5
Ah, I see what you are saying, and it had not even occurred to me.  It is all so clear now.  You see, the trouble is that, having learned to use this stuff in bits and pieces, some in the manual, some on the web, I have no solid beginning to ending understanding of the language.

Anyway, none of that is really important.  What is important is that you fellows are coding fiends and the whole system works now.  Many thousands of thanks to everyone, and let us hope the subject is closed.
"Now it's over I'm dead and I haven't
done anything that I want
or, I'm still alive
and there's nothing I want to do."

Teh Crabe

I played with the script for a bit, but I'm unsure of its usefulness without being paired with a collision detection system.
"You are too pessimistic, you always see the empty side of the glass. Try to see the half-sized side." -Gord10

Jam Torkberg

Hmm, that may be a good point.  I certainly hope I don't build a game around it have have it implode due to the character flying abou thte screen.

But, for the moment, a simple walkable area seems enough to keep the sprite based persona from falling off the edhe of the screen.
"Now it's over I'm dead and I haven't
done anything that I want
or, I'm still alive
and there's nothing I want to do."

Teh Crabe

Well, what I mean is you need some kind of collision detection for interacting with things.  If you still need to point and click with a mouse to interact, using the keyboard to walk is a waste.  I'm assuming you would have an action key or keys which you would press.  If the character were standing over a hotspot when the key was pressed, your interaction would occur.  Right now, hotspots detect the mouse cursor, not the character.

I'm new to this too, and could be wrong, but that's the impression I get.  You need a way to track when the character is within a hotspot.
"You are too pessimistic, you always see the empty side of the glass. Try to see the half-sized side." -Gord10

Jam Torkberg

Regions, my friend!  Regions make the world a fine and dandy place.

At least, I imagine so in my mind.  I have been using them without incident thus far.  But that does not mean things will not go fubar at the drop of a hat.
"Now it's over I'm dead and I haven't
done anything that I want
or, I'm still alive
and there's nothing I want to do."

Hollister Man

#10
Thanks to AVO, I got the script.  Here it is for all to enjoy:

The player can use keys 1-9 on the numeric keypad or the corresponding arrow keys to control the movement of the player character (pc). The pc moves as long as the key is pressed and stops moving when the key is released.

At the top of the Main global script:
Code: ags

// ------ keyboard control ------
#define DIR_DISTANCE 10000
#define DIR_DOWN_LEFT 1
#define DIR_DOWN 2
#define DIR_DOWN_RIGHT 3
#define DIR_LEFT 4
#define DIR_STOP 5
#define DIR_RIGHT 6
#define DIR_UP_LEFT 7
#define DIR_UP 8
#define DIR_UP_RIGHT 9
int PrevDirection;


Within the game_start() function:
Code: ags

// ------ keyboard control ------
PrevDirection = DIR_STOP;


Within the repeatedly_execute() function:
Code: ags

// --- keyboard control ---
int CharId, Direction, dx, dy;
// neue Richtung ermitteln
if ((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0)) Direction = DIR_UP_LEFT; // 7 Home (numeric pad)
else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP; // 8 Up arrow
else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0)) Direction = DIR_UP_RIGHT; // 9 PgUp (numeric pad)
else if ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT; // 4 Left arrow
else if ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP; // 5 Stop (numeric pad)
else if ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT; // 6 Right arrow
else if ((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0)) Direction = DIR_DOWN_LEFT; // 1 End (numeric pad)
else if ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN; // 2 Down arrow
else if ((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0)) Direction = DIR_DOWN_RIGHT; // 3 PgDn (numeric pad)
else Direction = DIR_STOP;
// Vergleich mit aktueller Richtung
if (PrevDirection != Direction)
{
PrevDirection = Direction;
CharId = GetPlayerCharacter ();
if (Direction == DIR_STOP) { StopMoving (CharId); } // 5 Stop (numeric pad)
else
{
if (Direction == DIR_UP_LEFT) { dx = -DIR_DISTANCE; dy = -DIR_DISTANCE; } // 7 Home (numeric pad)
else if (Direction == DIR_UP) { dx = 0; dy = -DIR_DISTANCE; } // 8 Up arrow
else if (Direction == DIR_UP_RIGHT) { dx = DIR_DISTANCE; dy = -DIR_DISTANCE; } // 9 PgUp (numeric pad)
else if (Direction == DIR_LEFT) { dx = -DIR_DISTANCE; dy = 0; } // 4 Left arrow
else if (Direction == DIR_RIGHT) { dx = DIR_DISTANCE; dy = 0; } // 6 Right arrow
else if (Direction == DIR_DOWN_LEFT) { dx = -DIR_DISTANCE; dy = DIR_DISTANCE; } // 1 End (numeric pad)
else if (Direction == DIR_DOWN) { dx = 0; dy = DIR_DISTANCE; } // 2 Down arrow
else if (Direction == DIR_DOWN_RIGHT) { dx = DIR_DISTANCE; dy = DIR_DISTANCE; } // 3 PgDn (numeric pad)
MoveCharacterStraight (CharId, character [CharId].x + dx, character [CharId].y + dy);
}
}


I think there could  be some optimization, but this is what AVO posted in the forums earlier.   Whatch out for non-english comments.
That's like looking through a microscope at a bacterial culture and seeing a THOUSAND DANCING HAMSTERS!

Your whole planet is gonna blow up!  Your whole DAMN planet...

Barcik

#11
Duzz has released the source of his AGS FIFA game, and it may prove to be very helpful to you.

Download here.
Currently Working On: Monkey Island 1.5

magintz

Or as another option to you young mites, you can try the classic adventure style walking, where if you push the button once they move, and if you push it again they stop. All the scripting needed for this is within my Text Parser Template.
When I was a little kid we had a sand box. It was a quicksand box. I was an only child... eventually.

rtf

I fail at art.

SilverWizard_OTF

#14
Here is a script code that Barbarian gave to me, when i had the same question.

Code: ags

if (keycode==372) { // up arrow
    MoveCharacterStraight(EGO, player.x, player.y-200);
    while ((IsKeyPressed(372)>0) && (character[EGO].walking)) Wait(1);
    StopMoving(EGO);
}

if (keycode==375) { // left arrow
    MoveCharacterStraight(EGO, player.x-200, player.y);
    while ((IsKeyPressed(375)>0) && (character[EGO].walking)) Wait(1);
    StopMoving(EGO);
}

if (keycode==377) { // right arrow
    MoveCharacterStraight(EGO, player.x+200, player.y);
    while ((IsKeyPressed(377)>0) && (character[EGO].walking)) Wait(1);
    StopMoving(EGO);
}

if (keycode==380) { // down arrow
    MoveCharacterStraight(EGO, player.x, player.y+200);
    while ((IsKeyPressed(380)>0) && (character[EGO].walking)) Wait(1);
    StopMoving(EGO);
} 


Hope it helps.  Anyway, it helped me!
"All we have to decide is what to do, with the time that is given to us"

Hollister Man

#15
I made a minor change to AVO's script, so that a combination of 4-way arrows will allow you to go diagonal.


This should all go in the Repeatedly_execute function.
Code: ags


int CharId, Direction, dx, dy;
     if (((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0)) || (IsKeyPressed(372)&&IsKeyPressed(375))) Direction = DIR_UP_LEFT; // 7 Home (numeric pad)
else if (((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0)) || (IsKeyPressed(372)&&IsKeyPressed(377))) Direction = DIR_UP_RIGHT; // 9 PgUp (numeric pad)
else if (((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0)) || (IsKeyPressed(380)&&IsKeyPressed(375))) Direction = DIR_DOWN_LEFT; // 1 End (numeric pad)
else if (((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0)) || (IsKeyPressed(380)&&IsKeyPressed(377))) Direction = DIR_DOWN_RIGHT; // 3 PgDn (numeric pad)
else if  ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP; // 8 Up arrow
else if  ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT; // 4 Left arrow
else if  ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP; // 5 Stop (numeric pad)
else if  ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT; // 6 Right arrow
else if  ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN; // 2 Down arrow
else Direction = DIR_STOP;

if (PrevDirection != Direction)
{
PrevDirection = Direction;
CharId = GetPlayerCharacter ();
if (Direction == DIR_STOP) { StopMoving (CharId); } // 5 Stop (numeric pad)
else
{
if (Direction == DIR_UP_LEFT) { dx = -DIR_DISTANCE; dy = -DIR_DISTANCE; } // 7 Home (numeric pad)
else if (Direction == DIR_UP) { dx = 0; dy = -DIR_DISTANCE; } // 8 Up arrow
else if (Direction == DIR_UP_RIGHT) { dx = DIR_DISTANCE; dy = -DIR_DISTANCE; } // 9 PgUp (numeric pad)
else if (Direction == DIR_LEFT) { dx = -DIR_DISTANCE; dy = 0; } // 4 Left arrow
else if (Direction == DIR_RIGHT) { dx = DIR_DISTANCE; dy = 0; } // 6 Right arrow
else if (Direction == DIR_DOWN_LEFT) { dx = -DIR_DISTANCE; dy = DIR_DISTANCE; } // 1 End (numeric pad)
else if (Direction == DIR_DOWN) { dx = 0; dy = DIR_DISTANCE; } // 2 Down arrow
else if (Direction == DIR_DOWN_RIGHT) { dx = DIR_DISTANCE; dy = DIR_DISTANCE; } // 3 PgDn (numeric pad)
MoveCharacterStraight (CharId, character [CharId].x + dx, character [CharId].y + dy);
}
}

That's like looking through a microscope at a bacterial culture and seeing a THOUSAND DANCING HAMSTERS!

Your whole planet is gonna blow up!  Your whole DAMN planet...

jetxl

My version:
http://www.2dadventure.com/ags/ArrowWalk.zip

Code: ags

int cleft;Ã,  //flags to see if button is still pressed
int cright;
int cup;
int cdown;



Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  //the arrowkey code . copy this in global script repeatedly execute
Ã,  if (IsKeyPressed(375)==1 && cleft==0) {
Ã,  Ã,  cleft=1;
Ã,  Ã,  MoveCharacterStraight(GetPlayerCharacter(),-1000,character[GetPlayerCharacter()].y);
Ã,  }
Ã,  if (IsKeyPressed(375)==0 && cleft==1){
Ã,  Ã,  StopMoving(GetPlayerCharacter());
Ã,  Ã,  cleft=0;
Ã,  }

Ã,  if (IsKeyPressed(377)==1 && cright==0) {
Ã,  Ã,  cright=1;
Ã,  Ã,  MoveCharacterStraight(GetPlayerCharacter(),1000,character[GetPlayerCharacter()].y);
Ã,  }
Ã,  if (IsKeyPressed(377)==0 && cright==1){
Ã,  Ã,  StopMoving(GetPlayerCharacter());
Ã,  Ã,  cright=0;
Ã,  }

Ã,  if (IsKeyPressed(372)==1 && cup==0) {
Ã,  Ã,  cup=1;
Ã,  Ã,  MoveCharacterStraight(GetPlayerCharacter(),character[GetPlayerCharacter()].x,-1000);
Ã,  }
Ã,  if (IsKeyPressed(372)==0 && cup==1){
Ã,  Ã,  StopMoving(GetPlayerCharacter());
Ã,  Ã,  cup=0;
Ã,  }

Ã,  if (IsKeyPressed(380)==1 && cdown==0) {
Ã,  Ã,  cdown=1;
Ã,  Ã,  MoveCharacterStraight(GetPlayerCharacter(),character[GetPlayerCharacter()].x,1000);
Ã,  }
Ã,  if (IsKeyPressed(380)==0 && cdown==1){
Ã,  Ã,  StopMoving(GetPlayerCharacter());
Ã,  Ã,  cdown=0;
Ã,  }

TerranRich

Shouldn't pressing one arrow also stop the other movements as well? For example, if the charactrer is walking up and the player presses right, this code will cause him/her to walk up-right. Or am I wrong?
Status: Trying to come up with some ideas...

jetxl

#18
Nope. If the player presses up and then right, the character will go right. (because I didn't use "else")

This is a small and simple piece of code for 3 reasons.
1: I thought that AGS could only handle one key press. So I never tried doing diagnal. (I don't use those walking loops anyway)
2: I never look in the tech arcive and didn't knew there was  a "movement with keyboard" topic. I made this before there was a tech archive.
3: People that can't program very well (like me) won't use complexed code since they don't understand how it works. And when they do (like me) they can make their own code anyway.

SMF spam blocked by CleanTalk