Skip to main content

News

Topic: Limiting Movement Part II: How do I set movement to a grid? (Read 4784 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
Limiting Movement Part II: How do I set movement to a grid?
I want to set the movement in my game to a grid where the players movement is locked and other keys are also locked untill the player moves to the next grid which yould be

y-16 pixels from the players position when facing north
y+16 pixels from the players position when facing south
x-16 pixels from the players position when facing west
x+16 pixels from the players position when facing east

Here is Radnens movement code
Code: (javascript) [Select]

function game()
{
BindKey(KEY_UP, '', '');
BindKey(KEY_DOWN, '', '');
BindKey(KEY_LEFT, '', '');
BindKey(KEY_RIGHT, '', '');
}



Code: (javascript) [Select]

function Update() {
var moving = false; //I added in this variable to check if the player is moving

if (IsKeyPressed(KEY_UP)) {
         QueuePersonCommand("ghost", COMMAND_FACE_NORTH, true);
     QueuePersonCommand("ghost", COMMAND_MOVE_NORTH, false);
     moving = true;           
}
else if (IsKeyPressed(KEY_DOWN )) { 
     QueuePersonCommand("ghost", COMMAND_FACE_SOUTH, true);
     QueuePersonCommand("ghost", COMMAND_MOVE_SOUTH, false);
     moving = true;          
}
else if (IsKeyPressed(KEY_LEFT)){   
     QueuePersonCommand("ghost", COMMAND_FACE_WEST , true);
     QueuePersonCommand("ghost", COMMAND_MOVE_WEST , false);
     moving = true;     
}
else if (IsKeyPressed(KEY_RIGHT)) {      
     QueuePersonCommand("ghost", COMMAND_FACE_EAST , true);
      QueuePersonCommand("ghost", COMMAND_MOVE_EAST , false);
      moving = true;
}


I would want to modify this so that when I am pressing a button, the movement is locked when I release the button.
The movement will unlock itself only under two conditions
there is a tile obstructing the way or the player has moved 16 pixels ( tilesize ) in that direction

I will need 4 variables, one to check the players position at all times, another to get the position of the next tile,a variable that checks if the players position matches with the intended position they should reach and a final variable that checks if that intended position in obstructed by any tile.

Movement should then be locked only until check is true and there are no obstructions.
------------------------------------------------------------------------------------------------------------------------------------------------------------------

Here is what I tried in the Update script

Code: (javascript) [Select]

var px = GetPersonX("ghost");
var py = GetPersonY("ghost");
var ty = 0, tx = 0; //position of next tile in co-ordinates for x and y

if (moving == false) // if the player is not moving
{
check = false;
switch(GetPersonDirection("ghost")) {
        case "north": ty = py - 16; break;    //north -y
        case "south": ty = py + 16; break; //south +y
        case "west": tx = px - 16; break;  //west -x
        case "east": tx = px + 16;; break; //east x   
    }
}


for now all I could figure out where the variables.
  • Last Edit: July 10, 2013, 09:13:54 am by Xenso

Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #1
For tile movement, a useful statement to use is the for-loop.
Specifically here, where you would want your character to move
16 pixels every time a button is pressed.

To replace what's being doing here:
Code: (javascript) [Select]
 switch(GetPersonDirection("ghost")) {
        case "north": ty = py - 16; break;    //north -y
        case "south": ty = py + 16; break; //south +y
        case "west": tx = px - 16; break;  //west -x
        case "east": tx = px + 16;; break; //east x   
    }


With:

Code: (javascript) [Select]
 for (var i = 0; i < 16; ++i) { QueuePersonCommand(Player, Direction, false); } 


Recognize the "var i = 0; i < 16; ++i" within the parentheses?
This keeps the player moving until the
variable i has reached the number 16.

[Explanation:] For every time that the Player COMMAND_MOVE_NORTH,
the variable i is added an additional 1 to its value.
And until i has reached 16, in other words:
until the player has moved 16 pixels, then the for-loop breaks
and the player stops. He has reached his destination at the new tile.

. . .

What's needed is a variable identifying the person who has the controls,
and another one to identify the direction he is in.

For example:

Code: (javascript) [Select]
 when key_up is pressed, Direction = COMMAND_MOVE_NORTH; 


Another example, for identifying the person with controls:

Code: (javascript) [Select]
 var Player = GetPersonWithInput(); 


(note: function call names might not be correct, cross reference the API)
Drop all of this inside wherever you are defining the keys,
within the Movement function after the if-then cases.
  • Last Edit: July 14, 2013, 01:52:33 pm by Vakinox

Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #2
Maybe I got the wrong idea when implementing this to the movement commands but I thought this would be a bit faster instead of creating another variable just to store COMMAND_MOVE_DIRECTION.

Code: (javascript) [Select]
if (IsKeyPressed(KEY_UP)) {
                     QueuePersonCommand(Player, COMMAND_FACE_NORTH, true);
                     for (var i = 0; i < 32; ++i) { QueuePersonCommand(Player, COMMAND_MOVE_NORTH, false); }
     moving = true;           
}
else if (IsKeyPressed(KEY_DOWN )) { 
     QueuePersonCommand(Player, COMMAND_FACE_SOUTH, true);
     for (var i = 0; i < 32; ++i) { QueuePersonCommand(Player, COMMAND_MOVE_SOUTH, false); }
     moving = true;          
}
else if (IsKeyPressed(KEY_LEFT)){   
     QueuePersonCommand(Player, COMMAND_FACE_WEST , true);
     for (var i = 0; i < 32; ++i) { QueuePersonCommand(Player, COMMAND_MOVE_WEST, false); }
     moving = true;     
}
else if (IsKeyPressed(KEY_RIGHT)) {      
   QueuePersonCommand(Player, COMMAND_FACE_EAST , true);
      for (var i = 0; i < 32; ++i) { QueuePersonCommand(Player, COMMAND_MOVE_EAST, false); }
      moving = true;
}


We have three problems:
It does not move 32 pixels, instead it moves at a much larger distance.

I need it so the player stops in the next grid-zone not necessarily 32 pixels away.
For example if I press up momentarily and then before the player has moved 32 pixels up I press down I would need to make a comparison to check that the player has moved back into the grid and not 32 pixels off.

When you input several movement commands, for example if the player is panicking and presses up, down, left, left, up very quick then the movement processes itself until ALL the commands have been completed, I need it so that even if the player presses a hundred buttons the computer only follows the last button pressed and only checks for if the player sprite is within the grid zone regardless.


EDIT:
I've played Arkistas Ring on NES, limiting the movement to the grid and the speed at which the player can fire a bullet is very essential to neat and smooth gameplay because the risk and challenge is a lot more organized. You have to think fast but over accurate controls would result in "lazy" gameplay and "button smashing", a trend that I think is a little disgusting in the game industry these days ( or maybe I'm getting old ). Lets work on this movement script as I initially planned.
  • Last Edit: July 14, 2013, 09:49:09 am by Xenso

Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #3
Apologies, should've worded my previous advice differently.
But just to identify an issue: Not everything has to be ran through a if-then conditional.

For example, the for-loop which would remain outside of the if-then conditionals,
but still inside the function where you define movement.
Exception: The only time you would put this for-loop in an if-then case is when
checking for obstructions or other things before moving.

Would suggest to read more on what you can do with variables,
but it seems there's an absence of related information in tutorials.
I may make one in the near future seeing as it could be useful.

. . .

Code: (javascript) [Select]
 for (var i = 0; i < 32; ++i) { QueuePersonCommand(Player, Command, false); } 


In my way of doing things, we would leave the "Command" spot as a variable.
We could create this variable locally, within the parameters of the function
where we define movement, presumably before everything else (on top).
First we define it outside of the if-then conditionals, then redefine it inside
them when we're wanting movement during key pressing.

Really, outside the if-thens you could define the local variable "Command" as just about anything,
doesn't matter because that's what we're redefining inside the conditionals.
But for conveniences sake, we should define it as this for now:

Code: (javascript) [Select]
 var Command = null; 


. . .

Code: (javascript) [Select]
 if (IsKeyPressed(KEY_UP)) {
QueuePersonCommand(Player, COMMAND_FACE_NORTH, true);
moving = true;}


Now for the if-then conditional, we relocate the for-loop outside of its parameters.
We can keep the QueuePersonCommand for facing if we want, but what we
want to add is the redefining of the local variable "Command"

Code: (javascript) [Select]
 if (IsKeyPressed(KEY_UP)) {
QueuePersonCommand(Player, COMMAND_FACE_NORTH, true);
moving = true; Command = COMMAND_MOVE_SOUTH}


Being that we're pressing KEY_UP we want our player to go North.
So we define Command = COMMAND_MOVE_NORTH;
This causes Command inside the for-loop to be redefine as COMMAND_MOVE_NORTH
whenever KEY_UP is pressed.

Try it this time, and get back to me with your results.
If it doesn't work, attach your script with the movement function and I'll look through.
  • Last Edit: July 14, 2013, 01:59:02 pm by Vakinox

Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #4
Command is invalid or undefined, I tried to set it to COMMAND_WAIT as its initial value but the player can not move. Note that I have bound all the movement keys in the game Startup I hope this is not the problem and I don't think it should.

Here is the code I am using like you said.

Code: (javascript) [Select]

function Update()
{
direction = GetPersonDirection(Player);
moving = false;
var Command;

  if (IsKeyPressed(KEY_UP))
{
QueuePersonCommand(Player, COMMAND_FACE_NORTH, true);
moving = true;
Command = COMMAND_MOVE_NORTH;
}           
else if (IsKeyPressed(KEY_RIGHT))
{
QueuePersonCommand(Player, COMMAND_FACE_EAST, true);
moving = true;
Command = COMMAND_MOVE_EAST;
}
else if (IsKeyPressed(KEY_DOWN))
{
QueuePersonCommand(Player, COMMAND_FACE_SOUTH, true);
moving = true;
Command = COMMAND_MOVE_SOUTH;
}
else if (IsKeyPressed(KEY_LEFT))
{
QueuePersonCommand(Player, COMMAND_FACE_WEST, true);
moving = true;
Command = COMMAND_MOVE_WEST;
}
}


I have attached my game project. You can check out the script in there. I set up a grid on the map so its easy to see if it worked. press SPACE to shoot. Thanks for your time.


  • Last Edit: July 15, 2013, 03:43:17 pm by Xenso

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #5
There is nothing wrong with the code you supplied. I'll take a look at your game and reply soon.

Edit: You almost had it, attached is the fixed code.
  • Last Edit: July 15, 2013, 04:15:22 pm by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #6
Thanks I learned a lot from you're code, next time I will make a function for this sort of thing and avoid unnecessary variables.

It works perfect on its own but there was a problem while shooting and moving. The players movement would sometimes be slightly altered by one pixel less, when you walk while shooting and then turn to go down for example the collision gets stuck because the player moved 31 pixels and not precisely 32.
I suspected that it was because sphere was busy with updating the shooting and gave that more priority over the players movement that it then updates shortly after the bullet has been created. I moved the code for shooting the bullet when the player presses SPACE ( in the update script ) after the movement function and this solved the problem with collision since now the players movement was given more of a priority but the player cannot shoot while moving.
I am going to attempt to limit the bullet creation to a grid as well. I'm having a bit of trouble wrapping my head around it. I'm thinking it would be similar to the for-loop or the next bullet created will have to first check if there is any person obstructing it in its co-ordinates of creation. Which method would be best to limit the bullet creation so that a bullet is created only when the grid-space it is created on is free of any bullets?

EDIT:
WARNING: Dont analyse code when you're tired. :-X
  • Last Edit: July 18, 2013, 09:30:20 am by Xenso

Re: Limiting Movement Part II: How do I set movement to a grid?
Reply #7
 ;) I got it, it was the collision between the player and the bullet that was messing up the movement. When the player shoots a bullet at speed 1 and walks behind this bullet, the collision mask prevents it from moving the whole 32 pixels. Also I used one variable called bullet_death that is true when the condition is met and the bullet is destroyed and is false when the player creates another bullet that fixed my problem with limiting the bullets to one per shot.

I fixed the problem with the bullet by simply changing start_x and stay_y to 33 instead of 32, this gives it one additional pixel away from the player so the two never collide thus the players movement is not slowed down by one pixel.

Code: (javascript) [Select]

bullets.push(new Bullet("shot"+bullet_num, GetPersonX(player) + x * 33, GetPersonY(player) + y * 33, x, y));


I think all this help has got me thinking more like a programmer, thanks I was able to solve problems by myself, I feel proud ( although they where minor problems ).

O.K, the code is now absolutely perfect, I just need a sound effect to play when the player hits a wall but that's easy I think I can figure that one out for later. ;D
  • Last Edit: July 18, 2013, 09:27:57 am by Xenso