Movement route : jump problem

Sinclairetype-0

Warper
I make my NPC character keep jumping to the left (x:-2; y:0). The problem is this character jump to the river or even outside map area. So how do you limiting this jump so if the NPC facing river or wall, they stop jumping ?

Eliaquim

Hakuen Studio
Hi!
I think you can put a condition to check where the player is.
If it is in X position, he cannot jump.
You have to find a way to check this. Maybe with regions, terrain tags etc.
I also dont know why the code is made like that, without "jump colision".

caethyril

^_^
For passability checks, here's a quote from another thread:
Yeah, that's my bad, if I'd dug deeper into the function I'd have realised that the code is checking that you can exit the tile in the direction that you are facing and that you can enter the tile in front. There are alternatives that might be safer.

JavaScript:
``````var space = 2; // tiles to move, change number to increase/decrease distance.
var d = \$gamePlayer.direction();
var x = \$gamePlayer.x + (d === 4 ? -space : (d === 6 ? space : 0)); //adjust x if facing left or right.
var y = \$gamePlayer.y + (d === 8 ? -space : (d === 2 ? space : 0)); //adjust y if facing up or down.
var passable = \$gameMap.isPassable(x, y, d);
\$gameSwitches.setValue(id, passable);  //replace id with switch id to use in conditional branch.``````

So long as the tile being landed on has passability in the direction the player is facing, this won't trigger the else branch. No checks are done on the tile in front of the player's landing position.

If you're going to be having the player land on tiles that themselves have limited passability it might be worth checking to see if there is Any passibility by doing some extra checks.

JavaScript:
``````var space = 2; // tiles to move, change number to increase/decrease distance.
var d = \$gamePlayer.direction();
var x = \$gamePlayer.x + (d === 4 ? -space : (d === 6 ? space : 0)); //adjust x if facing left or right.
var y = \$gamePlayer.y + (d === 8 ? -space : (d === 2 ? space : 0)); //adjust y if facing up or down.
var passable = \$gameMap.isPassable(x, y, 2) || \$gameMap.isPassable(x, y, 4) || \$gameMap.isPassable(x, y, 6) || \$gameMap.isPassable(x, y, 8);
\$gameSwitches.setValue(id, passable);  //replace id with switch id to use in conditional branch.``````

While this is not so nice to look at it checks for passability in all directions and if there's at least one then it's fine to land on the tile. Again, this doesn't check any of the neighbouring tiles.

If you wanted the player to at least have some wiggle room when they jumped you could replace "\$gameMap.isPassable" with "\$gamePlayer.isMapPassable" and it will only execute if the player can enter a space and make a move in at least one direction. I'd argue that this is unnecessary though as the player can always turn around on one tile and reactivate the ability - if they want to jump into tiny holes who are you to stop them?

I also dont know why the code is made like that, without "jump colision".
I think it's because you'd expect to be able to jump over impassable tiles, but if you land on an impassable tile, what should happen? Should the jump just fail to move you at all? Should it backtrack along the jump "line" and land you on the closest passable tile? What about if the passability of the target tile changes mid-jump? Etc.

Eliaquim

Hakuen Studio
I think it's because you'd expect to be able to jump over impassable tiles, but if you land on an impassable tile, what should happen? Should the jump just fail to move you at all? Should it backtrack along with the jump "line" and land you on the closest passable tile? What about if the passability of the target tile changes mid-jump? Etc. :karst:
I think this has to be implemented like any other move route(step forward, backward and other movements). If the dev wants the player to jump across/above unpassable tiles, they can set the through On. At least the dev would have an option.
But the way it is, we don't have a default option for not to land in unpassable tiles.

By the way, a great solution from Silva in the other thread! =O

Sinclairetype-0

Warper
For passability checks, here's a quote from another thread:

I think it's because you'd expect to be able to jump over impassable tiles, but if you land on an impassable tile, what should happen? Should the jump just fail to move you at all? Should it backtrack along the jump "line" and land you on the closest passable tile? What about if the passability of the target tile changes mid-jump? Etc.

Sorry im still green in using RPG Maker MV. Where do i put that javascript ?

caethyril

^_^
Sorry im still green in using RPG Maker MV. Where do i put that javascript ?
It's designed for use in a standalone Script command, with a Conditional Branch command after it to check the switch; the move route would then be applied if the switch is on, and not applied if the switch is off. However, I'm guessing your current set-up only involves a repeating move route, right?

Instead you could try putting this script in a move route for your bouncy NPC:
JavaScript:
``var jx = -2, jy = 0; this._moveRoute.repeat = [2,4,6,8].some(function(d) { return \$gameMap.isPassable(this.x + jx, this.y + jy, d); }, this); if (this._moveRoute.repeat) this.jump(jx, jy);``
This basically says "this move route should repeat if (and only if) this character can pass through the tile two spaces to the left; if the route is repeating, jump two spaces to the left". It's the same idea as Silva posted, just adapted for a repeating move route and constant jump direction~

An alternative would be to have, for instance, a separate Parallel event to make the NPC jump one bounce at a time:
Code:
``````◆Script：var id = 1;    // switch ID
：      ：var s = 2;     // jump distance in tiles
：      ：var d = 4;     // jump direction, 4 = left (see numpad)
：      ：var ev = this.character(0);  // "this event"
：      ：var x = ev.x, y = ev.y;   // current location, now get target...
：      ：for (var n = s; n--;) x = \$gameMap.roundXWithDirection(x, d);
：      ：var passable = [2,4,6,8].some(function(r) {
：      ：  return \$gameMap.isPassable(x, y, r);
：      ：}, this);  // is target tile passable in some direction?
：      ：\$gameSwitches.setValue(id, passable);  // toggle switch
◆If：Switch 1 is ON
◆Set Movement Route：This Event (Wait)
：                  ：◇Jump：-2, +0
◆
：Else
◆Comment：Jump blocked! Disable this event until the map is revisited.
◆Erase Event
◆
：End``````
Easy-copy version of the script call I've used here:
JavaScript:
``````var id = 1;    // switch ID
var s = 2;     // jump distance in tiles
var d = 4;     // jump direction, 4 = left (see numpad)
var ev = this.character(0);  // "this event"
var x = ev.x, y = ev.y;   // current location, now get target...
for (var n = s; n--;) x = \$gameMap.roundXWithDirection(x, d);
var passable = [2,4,6,8].some(function(r) {
return \$gameMap.isPassable(x, y, r);
}, this);  // is target tile passable in some direction?
\$gameSwitches.setValue(id, passable);  // toggle switch``````

Sinclairetype-0

Warper
It's designed for use in a standalone Script command, with a Conditional Branch command after it to check the switch; the move route would then be applied if the switch is on, and not applied if the switch is off. However, I'm guessing your current set-up only involves a repeating move route, right?

Instead you could try putting this script in a move route for your bouncy NPC:
JavaScript:
``var jx = -2, jy = 0; this._moveRoute.repeat = [2,4,6,8].some(function(d) { return \$gameMap.isPassable(this.x + jx, this.y + jy, d); }, this); if (this._moveRoute.repeat) this.jump(jx, jy);``
This basically says "this move route should repeat if (and only if) this character can pass through the tile two spaces to the left; if the route is repeating, jump two spaces to the left". It's the same idea as Silva posted, just adapted for a repeating move route and constant jump direction~

An alternative would be to have, for instance, a separate Parallel event to make the NPC jump one bounce at a time:
Code:
``````◆Script：var id = 1;    // switch ID
：      ：var s = 2;     // jump distance in tiles
：      ：var d = 4;     // jump direction, 4 = left (see numpad)
：      ：var ev = this.character(0);  // "this event"
：      ：var x = ev.x, y = ev.y;   // current location, now get target...
：      ：for (var n = s; n--;) x = \$gameMap.roundXWithDirection(x, d);
：      ：var passable = [2,4,6,8].some(function(r) {
：      ：  return \$gameMap.isPassable(x, y, r);
：      ：}, this);  // is target tile passable in some direction?
：      ：\$gameSwitches.setValue(id, passable);  // toggle switch
◆If：Switch 1 is ON
◆Set Movement Route：This Event (Wait)
：                  ：◇Jump：-2, +0
◆
：Else
◆Comment：Jump blocked! Disable this event until the map is revisited.
◆Erase Event
◆
：End``````
Easy-copy version of the script call I've used here:
JavaScript:
``````var id = 1;    // switch ID
var s = 2;     // jump distance in tiles
var d = 4;     // jump direction, 4 = left (see numpad)
var ev = this.character(0);  // "this event"
var x = ev.x, y = ev.y;   // current location, now get target...
for (var n = s; n--;) x = \$gameMap.roundXWithDirection(x, d);
var passable = [2,4,6,8].some(function(r) {
return \$gameMap.isPassable(x, y, r);
}, this);  // is target tile passable in some direction?
\$gameSwitches.setValue(id, passable);  // toggle switch``````
Sorry for late reply. This script works fine only if the map surrounded by impassable tile but
1. if the map NOT surrounded by impassable tile, the enemy still can jump outside the map.
2. the enemy still can jump to the "non-through" event image like chest or crystal.

Anyways thanks for the script !

Last edited:

caethyril

^_^
Sorry for late reply. This script works fine only if the map surrounded by impassable tile but
1. if the map NOT surrounded by impassable tile, the enemy still can jump outside the map.
2. the enemy still can jump to the "non-through" event image like chest or crystal.

Anyways thanks for the script !
Oh, yep, that's awkward.
1. Unfortunately `isPassable` returns true for tiles outside the map...could add another check in there, though.
2. Checking for "normal priority" events (i.e. Same as Player) can be done with another check.
Here's a chunkier version including those "other checks":
JavaScript:
``var jx = -2, jy = 0, x = this.x + jx, y = this.x + jy; this._moveRoute.repeat = \$gameMap.isValid(x, y) && !this.isCollidedWithEvents(x, y) && [2,4,6,8].some(function(d) { return \$gameMap.isPassable(x, y, d); }, this); if (this._moveRoute.repeat) this.jump(jx, jy);``
(Haven't tested this, hope it works! )

Latest Profile Posts

Celebrating the arrival of autumn in the Northern Hemisphere
When doing a map or whatever, kind of wish you could round out some parts.
Released a plugin mod for MV: SelectMultipleTargets v3.0 (mod of original by Zevia)

port to MZ is following

1,Randomly generate events with planted spawner events(great flexibility for customization and auto-match player's level)
2,Randomly enter roguelike dungeon
3,Player can exit dungeon or back to town or choose to challenge BOSS at the end of each dungeon
4,Dungeon maps can be randomly generated by a third-party tool