Skip to main content

News

Topic: Question about API and Obstructions (Read 9124 times) previous topic - next topic

0 Members and 2 Guests are viewing this topic.
Question about API and Obstructions
[Question:] Is there an existing function or way to set a person as "obstructed" through the API?

I noticed we have:

Quote

      IsPersonObstructed(name, x, y)
      // returns true if person 'name' would be obstructed at (x, y)

      GetObstructingTile(name, x, y)
      // returns -1 if name isn't obstructed by a tile at x, y,
       - returns the tile index of the tile if name is obstructed at x, y

      GetObstructingPerson(name, x, y)
      // returns "" if name isn't obstructed by person at x, y,
       - returns the name of the person if name is obstructed at x, y

      IgnorePersonObstructions(person, ignore)
       - Sets whether 'person' should ignore other spriteset bases

      IsIgnoringPersonObstructions(person)
       - Returns true if 'person' is ignoring person obstructions, else false
      
      IgnoreTileObstructions(person, ignore)
       - Sets whether 'person' should ignore tile obstructions

      IsIgnoringTileObstructions(person)
       - Returns true if 'person' is ignoring tile obstructions, else false


But don't see anything about setting a person to obstructed.

Should I instead write something like (pseudo-code):

Code: (javascript) [Select]

if (GetTileName(Next_tile) == "obstruct_nw" && direction == "south")
{
QueuePersonCommand(Player, COMMAND_FACE_SOUTH, true);
SetPersonFrame(GetInputPerson(),1);
UpdateMapEngine();
}


Will that work?

. . .

[Edit:] Scratch that, doesn't work.
He skips across the tile like a long jumper. Any ideas?

Tried adding:

Code: [Select]
 QueuePersonCommand(Player, COMMAND_WAIT, true); 


also, but that didn't work either.

Script is attached in case anyone needs to see it.

. . .

[Edit:] Tried a little something else:

Code: (javascript) [Select]

function SetPersonObstructed(name, command)
{
  switch(command) {
  case North: Move(name, 16, South, Face_north); break;
  case South: Move(name, -16, North, Face_south); break;
  case East: Move(name, -16, West, Face_east);  break;
  case West: Move(name, 16, East, Face_west);  break;
  break;
}
}

. . .

if (GetTileName(Ntile) == "obstruct_n" && direction == "south")
{
SetPersonObstructed(GetInputPerson(), South)
SetPersonFrame(GetInputPerson(),0);
UpdateMapEngine();
}

. . .

function Move(Name, Tiles, Direction, Face)
{

if (Direction == North) {QueuePersonCommand(Name, Face_north, false);}  //Makes sprite face its proper direction.
if (Direction == South) {QueuePersonCommand(Name, Face_south, false);}
if (Direction == East)  {QueuePersonCommand(Name, Face_east, false);}
if (Direction == West)  {QueuePersonCommand(Name, Face_west, false);}

if (Direction != Wait) {QueuePersonCommand(Name, Face, false);}   //If Direction commands sprite to Wait. It simply faces



for (var j = 0; j < Tiles; ++j) //For as long as "j" is less than Tiles, +1 is added to variable "j."
{ //The "j" variable will get us to reach our Tile Number. Once Tiles starts to become than "j" we no longer move.

   for (var i = 0; i < 16; ++i) {  QueuePersonCommand(Name, Direction, false);  }
   SetPersonFrame(Name, 0);  //When Tile for-loop is finished, we reset the sprite's frame of currection direction to "0"
}



//Now we set the sprite's facing direction.

if (Face == undefined)   //Checks Face for undefined.
{     //If undefined, sprite faces towards the direction it's commanded to go in.
   if (Direction == North) {Face = North;}
   if (Direction == South) {Face = South;}
   if (Direction == East)  {Face = East;}
   if (Direction == West)  {Face = West;}
}

if (Face == North) {QueuePersonCommand(Name, Face_north, false);}  //Makes sprite face its proper direction.
if (Face == South) {QueuePersonCommand(Name, Face_south, false);}
if (Face == East)  {QueuePersonCommand(Name, Face_east, false);}
if (Face == West)  {QueuePersonCommand(Name, Face_west, false);}


}
   

But that failed also. Still skips across the tile,
but now he stops and turns around and then stays stuck.

Still working on it.

  • Last Edit: July 08, 2013, 12:57:52 am by Vakinox

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: Question about API and Obstructions
Reply #1
Quote
[Question:] Is there an existing function or way to set a person as "obstructed" through the API?

A person is *always* obstructed. Rules:

- A person isn't obstructed with people it's ignoring.
- A person isn't obstructed with people on another layer.
- Make sure your obstruction base in the rss file looks like it should.

Re: Question about API and Obstructions
Reply #2
Apologies, I'm approaching and wording it all wrong.
Lack of sleep, delirium, last night kept me from making the right decisions.

Turns out, what I'm really wanting to do:
Is make a tile obstruct a character, but in different ways.
For example, if the character enters the tile in one certain direction, it'll be obstructed by the tile on the other side of it.
If the character attempts to enter the tile from the other side, then it's obstructed by the original tile.

[Visual Translation:]
Quote

--> []
Trying to enter the tile from the West causes obstruction

Quote

[][<--
Entering the tile from the East causes obstruction against the tile next to it (from the west).

Quote

[][^
. . |
You would also be free to move North, or South, inside the tile, alongside the tile next to it.
As long as you don't move West, which will cause obstruction.


What I should be doing is editing the TileMovement() script to check the Tiles that come next.
And then switch between Command_Wait or Command_Direction depending on the direction of travel and the specified tile.

To do this, I'll need to use functions: IgnoreTileObstructions(person, ignore); GetTileName(Next_Tile); and such.
Does this make sense? And is correct for what I want to achieve?

. . .

Problem, for some reason when sphere starts up, the Sprite is given the placement value of (0, 0).
I'm having to collect the placement values for the player to predict the Next Tile in front of their chosen direction.
So if something collides with the player during TileMovement, from the point of startup, one of the values will register -1.
Thus, throwing/returning an error. (Because there is no existence of a tile in (-1, 0) or (0, -1)).

How do I change the values from point of start?

I tried this:

Quote

QueuePersonScript("Player", 'Txy("Player", 19, 12)', true);


But it doesn't work. It places "Player" at values (19, 12) but it registers as (0, 0) still.
Is this a problem with sphere?

  • Last Edit: July 08, 2013, 06:43:03 pm by Vakinox

Re: Question about API and Obstructions
Reply #3
There's another problem,
this function:

Code: (javascript) [Select]

// To get the tile in front of the player.
function GetTileInFront()
{
  var direction = GetPersonDirection(GetInputPerson());
  if (direction == "north") return GetTile(NowTileX/16,NowTileY/16-1,0);
  if (direction == "south") return GetTile(NowTileX/16,NowTileY/16+1,0);
  if (direction == "west") return GetTile(NowTileX/16-1,NowTileY/16,0);
  if (direction == "east") return GetTile(NowTileX/16+1,NowTileY/16,0);
}


is returning some crazy numbers.
For example, it returns a Y-value of 44, when it should be 14.
As seen here:




For reference: The NowTile variables only collect the pixel coordinates of the tiles.
Code: (javascript) [Select]

if (IsKeyPressed(KEY_DOWN))
{
  if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)+16) == false) Counter++;
  Direction = COMMAND_MOVE_SOUTH;

  QueuePersonCommand(Player, COMMAND_FACE_SOUTH, true);
  if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)+16) == false) LastTileY = GetPersonY(Player);
  if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)+16) == false) NowTileY = GetPersonY(Player) + 16;
}


Anybody have any ideas?

. . . .

[Edit:] Alright, I figured this part out!

The function GetTile() doesn't return coordinate values,
it returns the Tile's numeral identity count within the tileset used for the map.
In otherwords, the tile in the front is the 44th tile in the tileset of the map.
So it is returning the correct number, not an arbitrary one like I thought it was.

Still have more from the previous comment to solve.
Feel free to add in whenever possible.
  • Last Edit: July 08, 2013, 09:36:22 pm by Vakinox

Re: Question about API and Obstructions
Reply #4
Solved it! Well, sort of.
Everything begins to work, the sprite pauses in the correct location, however he keeps moving afterwards.
I need him to stop completely. Shouldn't the for-loop keep him waiting as long as KEY_UP is pressed?

Code: (javascript) [Select]

if (IsKeyPressed(KEY_UP))
{
  //Adds count to total number of steps
  if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)-16) == false) Counter++;  

  //Gets the next tile, if it's "obstruct_n" it ignores it for the time being
  if (GetTileName(Next_Tile) == "obstruct_n") IgnoreTileObstructions(Player, true);   

  if (GetTileName(GetTile(NowTileX/16, NowTileY/16, 0)) == "obstruct_nw") Direction = COMMAND_WAIT;
  if (GetTileName(GetTile(NowTileX/16, NowTileY/16, 0)) == "obstruct_ne") Direction = COMMAND_WAIT;

  //Until here, where the sprite is suppose to Wait as long as KEY_UP is pressed
  if (GetTileName(GetTile(NowTileX/16, NowTileY/16, 0)) == "obstruct_n")  Direction = COMMAND_WAIT;
 
  //Anywhere else or any other tile on the map, it can move North, except "obstruct_n"
  else { Direction = COMMAND_MOVE_NORTH; }                                                                                     


  QueuePersonCommand(Player, COMMAND_FACE_NORTH, true);
  if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)-16) == false) LastTileY = GetPersonY(Player);          //Gets previous Tile location in pixel-value
  if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)-16) == false) NowTileY = GetPersonY(Player) - 16;  //Gets present Tile location in pixel-value
  }



The GetTileInFront() function is the same, only thing that's changed is the definition for the Key commands.

[Question:] How do I keep him from moving, other than using only COMMAND_WAIT?

. . .

[Edit:] Tried running it through a for-loop:

Code: [Select]
 for (var j = 1; j > 0; ++j){Direction = COMMAND_WAIT;} 


But that didn't work either. He did stop completely, however he remained there and was stuck without hope of getting out.

. . .

[Edit:] He's still getting stuck, but should this work?

Code: (javascript) [Select]

//Reads: If Next Tile is "obstruct_n" AND Player is going North, then ignore tile obstruction.

if (GetTileName(Next_Tile) == "obstruct_n" && GetPersonDirection(Player) == "north") IgnoreTileObstructions(Player, true);

//Reads: UNLESS If the current tile is "obstruct_n", do not Obstruct (because that would get us stuck inside the tile)

else if (GetTileName(GetTile(NowTileX/16,NowTileY/16,0)) !== "obstruct_n") IgnoreTileObstructions(Player, false);

  • Last Edit: July 08, 2013, 11:07:40 pm by Vakinox

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about API and Obstructions
Reply #5
To make him stop try using ClearCommandQueue(name);

Also this line of code:
for (var j = 1; j > 0; ++j){Direction = COMMAND_WAIT;}

Just sets Direction to COMMAND_WAIT forever without pause. This is an infinite loop!
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: Question about API and Obstructions
Reply #6
Sphere throws a "ClearCommandQueue(Player); is not defined"

Did you mean: ClearPersonCommands(name);

That doesn't work either, it does the same as the problem before.
Where he pauses for a quick bit, then keeps on walking.

. . .

To break the loop with a key, could I do this?

Code: [Select]

for (var j = 1; j > 0; ++j){
Direction = COMMAND_WAIT;
if ( IsKeyPressed(KEY_UP) == false) j = -1;}


Would that be if anything other than KEY_UP is pressed, then j registers a value as -1, thus breaking the loop?

. . .

Also, working getting the third part of the previous comment working.
If I get this working, I'll just need to keep the character from continuing walking North after the tile obstruction is ignored.

This is what I'm referring to:
Quote from: javascript

if (GetTileName(Next_Tile) == "obstruct_n" && GetPersonDirection(Player) == "north") IgnoreTileObstructions(Player, true);

else if (GetTileName(GetTile(NowTileX/16,NowTileY/16,0)) !== "obstruct_n") IgnoreTileObstructions(Player, false);


The problem is the character keeps getting stuck inside of the tile, for some reason the second part (else if) isn't working correctly.
Doesn't "!==" mean comparing to see if they're NOT equal?

  • Last Edit: July 09, 2013, 01:00:24 am by Vakinox

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about API and Obstructions
Reply #7
!== is a strict not equals which checks type and value. You were using it correctly there. :) You usually only use != tho.

Try:
Code: (javascript) [Select]

if (GetTileName(Next_Tile) == "obstruct_n")) IgnoreTileObstructions(Player, GetPersonDirection(Player) == "north");


What that will do is disable tile obstructions going north only if the next tiles name is 'obstruct_n'.
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: Question about API and Obstructions
Reply #8
Mind blown, as it's very creative. Just realized what was done.
The true or false part of IgnoreTileObstructions() is chosen according to what the GetPersonDirection() registers as in the comparison.
Which is also a true or false statement.

However, doesn't work.
For some reason the character is freely able to move South across the tile, when it should be obstructed.
Being that the direction isn't north.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about API and Obstructions
Reply #9
So, the idea is: when you move north you can't move through obstruct_n tiles, and when you move any other direction you can move through them, right?
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: Question about API and Obstructions
Reply #10
Sorta, but not quite.

1.) When you move north, you can enter the tile, but you can't pass through it.
2.) You can totally pass through it if you're moving east or west.
3.) However, when you're moving south, you're entirely obstructed by the tile, except when already inside of it.

. . .

[Edit:] Just realized during explanation, I should probably be putting this through a
Code: [Select]
 switch(Direction){ 
case north: //rules
case east:  //exception
case west:  //exception
case south: //rules
}

Right?
  • Last Edit: July 09, 2013, 02:18:44 pm by Vakinox

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about API and Obstructions
Reply #11
Yeah, a switch is a good start. When programming you look at the rules and exceptions, ask yourself what needs to be true or false for those to work and then implement them.

You will also need to figure out two things: what is the tile in front of you., and what is the tile you are currently on. Then I'm sure you can do the rest.
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: Question about API and Obstructions
Reply #12
[Update:]

Alright, just attempted to run it through the for-loop which deals with the player's tile movements.
However, that doesn't work. Meaning I'll have to code into each individual Key's input,
rather than handling it within the for-loop with a switch(Direction); operator.

Code: (javascript) [Select]
 
if (Direction != null && !IsObstructed(Player, Direction)) {
for (var i = 0; i < 16; ++i) {
QueuePersonCommand(Player, Direction, false);
switch (Direction){

  case COMMAND_MOVE_NORTH:
  if (GetTileName(Next_Tile) == "obstruct_n") IgnoreTileObstructions(Player, true);
  //if (GetTileName(GetTile(NowTileX/16,NowTileY/16,0)) != "obstruct_n") IgnoreTileObstructions(Player, false);
break;
  case East:
break;
  case West:
break;
  case South:
break;}
}
}


Instead of working, it doesn't ignore the tile's obstruction, and instantly blocks the player upon contact.
So now I'm back to handling it inside of the input key's defining.

. . .

FINALLY! Got it working correctly though.
This is the code:

Code: (javascript) [Select]
 
if (IsKeyPressed(KEY_UP))
{
if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)-7) == false) Counter++;

if (GetTileName(Next_Tile) == "obstruct_n" && GetPersonDirection(Player) == "north") IgnoreTileObstructions(Player, true), Direction = COMMAND_MOVE_NORTH;
if (GetTileName(GetTile(NowTileX/16,NowTileY/16,0)) == "obstruct_n") IgnoreTileObstructions(Player, false), Direction = COMMAND_WAIT;
else Direction = COMMAND_MOVE_NORTH;

QueuePersonCommand(Player, COMMAND_FACE_NORTH, true);
if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)-16) == false) LastTileY = GetPersonY(Player);
if (IsPersonObstructed(Player, GetPersonX(Player), GetPersonY(Player)-16) == false) NowTileY = GetPersonY(Player) - 16;
}


And then added a:

Code: [Select]
 if (GetTileName(GetTile(NowTileX/16-7,NowTileY/16-7,0)) == "obstruct_n") IgnoreTileObstructions(Player, true), Direction = COMMAND_MOVE_SOUTH; 


to the KEY_DOWN's definitions.
Took the whole day to figure it out, but finally got it.

Turns out that there was a similar problem with my step counter, in which the correct tiles weren't registering.
So had to correct the math a bit, add a (-7) and done. Works.
  • Last Edit: July 09, 2013, 09:34:14 pm by Vakinox

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about API and Obstructions
Reply #13
Yeah, I noticed the -7 helps, you can also do a bit shift: GetTileWidth() >> 1;

It'll divide it in half and round. The reason for the 7 is that the width is 0..15 and 15/2 = 7.5, rounded down it's 7. Just stuff to look out for.
  • Last Edit: July 10, 2013, 12:30:37 am 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: Question about API and Obstructions
Reply #14
Thanks for the advice man, will take it.

Though while you're here, one last problem that was posted I forgot to fix. It's now messing with my corrections.

For reference, it's this one:
Quote

For some reason when sphere starts up, the Sprite is given the placement value of (0, 0).
I'm having to collect the placement values for the player to predict the Next Tile in front of their chosen direction.
So if something collides with the player during TileMovement, from the point of startup, one of the values will register -1.
Thus, throwing/returning an error. (Because there is no existence of a tile in (-1, 0) or (0, -1)).

How do I change the values from point of start?

I tried this:
Code: (javascript) [Select]
 QueuePersonScript("Player", 'Txy("Player", 19, 12)', true); 


But it doesn't work. It places "Player" at values (19, 12) but it registers as (0, 0) still.
Is this a problem with sphere?


Still can't figure it out. Can you help?
  • Last Edit: July 09, 2013, 10:08:15 pm by Vakinox