How can I change the Hero's Layer?(Solved)

Started by Satoh, July 11, 2016, 12:54:00 AM

Previous topic - Next topic
July 11, 2016, 12:54:00 AM Last Edit: July 11, 2016, 04:18:33 AM by Satoh
I need to manually switch the hero's layer, without altering their position, instantly. (For reasons dealing with how collision happens, which are too complicated to explain for the purposes of this question)

What I've tried is:
local entity = ...
entity:set_size(16,16)
entity:set_origin(8,12)
entity:add_collision_test("origin", function(me, other) 
  debug.message = "layerchange"
  local posx,posy,posl = other:get_position()
  other:set_position(posx,posy,math.min(posl+1,2))
end)


Now... this all works as it seems like it should, except that it does not change the layer.
I also tried this in the debug console by simply accessing sol.main.game:get_hero():set_position(hero x,hero y, new layer)
and the hero does move to whatever hero x and hero y are, but new layer is ignored.

In short, hero:set_position() is ignoring the layer no matter what I do... is there another way to handle layer switching?
(Stairs force the player to move, which is not what I want to happen, I just want the hero to be on a different layer, at the same location)

EDIT:
Other entities that move across this layerswitch entity DO get their layer's changed... Only the hero is ignored.
Patience is difficult and rarely thanked, but always appreciated, and sorely missed when absent.


July 11, 2016, 03:11:02 AM #2 Last Edit: July 11, 2016, 03:23:57 AM by Diarandor
I think you are changing the position of your custom entity instead of the position of the hero, i.e., the collision test is probably detecting the custom entity as colliding with itself, so the layer of the custom entity is changed and then there is no collision with the hero since they are in different layers. I might be wrong with this, so you have to check if this is what is happening. In that case, you will need to add a condition in the collision test to check that the other entity is the hero, something like: "if other:get_type() == "hero" then ....blablabla".

Anyway, as Starlock says, the simplest way is probably to use a sensor instead of a custom entity with a collision test, unless you need to make more things that cannot be done with a sensor entity.

There is a nice tutorial made by ffomega which shows how to make bridges, which use sensors to change the layer of the hero. If you are having problems, then you should take a look (it is exactly the same link that Starlock has given above):
http://solarus_resource.site88.net/tutorial/bridges.htm
http://forum.solarus-games.org/index.php/topic,654.msg3361.html#msg3361

EDIT: Another possible cause of your problem could be if the ground on the second layer is of type "empty". That would make the hero fall automatically to the low layer again, because that is the behavior coded in the engine. However, other entities do not fall to lower layers if they are over an "empty" ground, so this would explain your problem too.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Quote from: Diarandor on July 11, 2016, 03:11:02 AM
I think you are changing the position of your custom entity instead of the position of the hero, i.e., the collision test is probably detecting the custom entity as colliding with itself, so the layer of the custom entity is changed and then there is no collision with the hero since they are in different layers. I might be wrong with this, so you have to check if this is what is happening. In that case, you will need to add a condition in the collision test to check that the other entity is the hero, something like: "if other:get_type() == "hero" then ....blablabla".

Anyway, as Starlock says, the simplest way is probably to use a sensor instead of a custom entity with a collision test, unless you need to make more things that cannot be done with a sensor entity.

There is a nice tutorial made by ffomega which shows how to make bridges, which use sensors to change the layer of the hero. If you are having problems, then you should take a look (it is exactly the same link that Starlock has given above):
http://solarus_resource.site88.net/tutorial/bridges.htm
http://forum.solarus-games.org/index.php/topic,654.msg3361.html#msg3361

EDIT: Another possible cause of your problem could be if the ground on the second layer is of type "empty". That would make the hero fall automatically to the low layer again, because that is the behavior coded in the engine. However, other entities do not fall to lower layers if they are over an "empty" ground, so this would explain your problem too.

I had not considered that empty tiles would automatically cause the player to fall. That seems to be the most likely case here, as the second layer is empty.
As for the entity colliding with itself, it is not. I've tested that already, 'other' is appropriately the Hero, and also works on other entities like blocks and destructibles.
Now that I've tested it with appropriate flooring installed, the hero does in fact move up to the second layer.

...now to really use this how I intended I have to figure out how to make an entity be solid on layer 0, and traversable on layer 1....

I'm attempting to create a stackable entities...I have my reasons.
Patience is difficult and rarely thanked, but always appreciated, and sorely missed when absent.

Ok, I guess I was wrong about a custom entity detecting itself during collisions (or maybe you have some extra code).

To change the custom entity from traversable to solid and viceversa you can use the event: "entity:on_position_changed(x, y, layer)".
But be careful when you change your entities to solid, because other entities (like the hero) may overlap them and be stuck. (What you are doing may be more complicated than it seems.)
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."