Author Topic: Jump movement direction4 error?  (Read 213 times)

Zefk

  • Sr. Member
  • ****
  • Posts: 482
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Jump movement direction4 error?
« on: May 10, 2017, 05:55:26 am »
I made the following two functions. The bug happens with my entity:jump function. It seems not to want to change the facing direction.

Code: Lua
  1. entity:jump_create() -- default jump sprite Eldran is created for this one.

and

Code: Lua
  1. entity:jump() -- no sprite set to be created

The direction does not change even though I set:

Code: Lua
  1.   function self:on_movement_changed()
  2.      self:set_direction(quick_movement:get_direction4())  
  3.   end

The problem only occurs if I do not manually create the sprite with script. (If I do not pick the sprite from the custom entity.)

Code: Lua
  1.    
  2.   function self:on_created()
  3.      sprite = self:create_sprite(sprite_directory) -- sprite_directory
  4.   end
  5.  
  6.   function self:on_movement_changed()
  7.      sprite:set_direction(quick_movement:get_direction4())  
  8.   end
  9.  

What makes no sense is I have other functions with identical code. For example, entity:wander() and entity:follow(). Both those functions use a sprite I picked from the custom entity and work perfectly.

I used "self:set_direction(quick_movement:get_direction4())" on both of those functions and they change direction correctly.

Code: Lua
  1.   function self:on_movement_changed()
  2.      self:set_direction(quick_movement:get_direction4())  
  3.   end

My only solution was to manually check.
Code: Lua
  1.  if direction8 == 0 or direction8 == 1 then
  2.     if self:get_direction() == 1 then -- up
  3.       self:set_direction(0)
  4.     end
  5.  
  6.     if self:get_direction() == 2 then -- left
  7.       self:set_direction(0)
  8.     end
  9.  
  10.     if self:get_direction() == 3 then -- down
  11.       self:set_direction(0)    
  12.     end
  13.  
  14.     if self:get_direction() == 0 then-- right
  15.       self:set_direction(0)
  16.     end
  17.   end
  18.  
  19.   if direction8 == 2 or direction8 == 3  then
  20.     if self:get_direction() == 1 then -- up
  21.       self:set_direction(1)
  22.     end
  23.  
  24.     if self:get_direction() == 2 then -- left
  25.       self:set_direction(1)
  26.     end
  27.  
  28.     if self:get_direction() == 3 then -- down
  29.       self:set_direction(1)    
  30.     end
  31.  
  32.     if self:get_direction() == 0 then-- right
  33.       self:set_direction(1)
  34.     end
  35.   end
  36.  
  37.   if direction8 == 4 or direction8 == 6 then
  38.     if self:get_direction() == 1 then -- up
  39.       self:set_direction(2)
  40.     end
  41.  
  42.     if self:get_direction() == 2 then -- left
  43.       self:set_direction(2)
  44.     end
  45.  
  46.     if self:get_direction() == 3 then -- down
  47.       self:set_direction(2)    
  48.     end
  49.  
  50.     if self:get_direction() == 0 then-- right
  51.       self:set_direction(2)
  52.     end
  53.   end
  54.  
  55.   if direction8 == 6 or direction8 == 7 then
  56.     if self:get_direction() == 1 then -- up
  57.       self:set_direction(3)
  58.     end
  59.  
  60.     if self:get_direction() == 2 then -- left
  61.       self:set_direction(3)
  62.     end
  63.  
  64.     if self:get_direction() == 3 then -- down
  65.       self:set_direction(3)    
  66.     end
  67.  
  68.     if self:get_direction() == 0 then-- right
  69.       self:set_direction(3)
  70.     end
  71.   end
« Last Edit: May 14, 2017, 04:44:08 am by Zefk »

MetalZelda

  • Sr. Member
  • ****
  • Posts: 480
    • View Profile
Re: Jump movement direction4 error?
« Reply #1 on: May 10, 2017, 10:19:33 pm »
This is a bit unclear to me, can you upload the whole code ?

Zefk

  • Sr. Member
  • ****
  • Posts: 482
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: Jump movement direction4 error?
« Reply #2 on: May 11, 2017, 05:44:00 am »
entity:jump_create() works, but entity:jump() does not. The only main different is entity:jump_create() makes the sprite with script and entity:jump() needs a sprite and on_created():

Code: Lua
  1. -- Event called when the custom entity is initialized.
  2. function entity:on_created()
  3.   entity:jump()
  4. end

Code: Lua
  1. -------------------------------------------
  2. --Entity Create Jump Method
  3. -------------------------------------------
  4. function metatable_entity:jump_create(sprite_directory, speed, traversable, set_can_traverse_hero, set_traversable_by_hero, ignore_obstacles, direction8, jump_distance, animation, finish_animation, finish_time, finish_jump_sound, jump_sound, sound_timer, dialog, dialog_activation_distance)
  5.  
  6.   local map = self:get_map()
  7.   local hero = map:get_hero()
  8.   local game = map:get_game()
  9.   local sprite
  10.   local quick_movement
  11.  
  12.   --speed default value
  13.   if speed == nil then
  14.     speed = 40
  15.   end
  16.  
  17.   if traversable == nil then
  18.     traversable = false
  19.   end
  20.  
  21.   --By default the entity cannot traverse the hero
  22.   if set_can_traverse_hero == nil then
  23.     set_can_traverse_hero = false
  24.   end
  25.  
  26.   --By default the hero cannot traverse the entity.
  27.   if set_traversable_by_hero == nil then
  28.     set_traversable_by_hero = false
  29.   end
  30.  
  31.   --By default the entity does not ignore obstacles
  32.   if ignore_obstacles == nil then
  33.     ignore_obstacles = false
  34.   end
  35.  
  36.   if direction8 == nil then
  37.     direction8 = 0
  38.   end
  39.  
  40.   if jump_distance == nil then
  41.     jump_distance = 100
  42.   end
  43.  
  44.   --By default the sprite directory is the hero tunic1
  45.   if sprite_directory == nil then
  46.     sprite_directory = "main_heroes/Eldran"
  47.   end
  48.  
  49.   if animation == nil then
  50.     animation = "jumping"
  51.   end
  52.  
  53.   if finish_animation == nil then
  54.    finish_animation = "stopped"
  55.   end
  56.  
  57.   if finish_time == nil then
  58.     finish_time = 3000
  59.   end
  60.  
  61.   if jump_sound == nil then
  62.     jump_sound = "jump"
  63.   end
  64.  
  65.   if finish_jump_sound == nil then
  66.     finish_jump_sound = "jump"
  67.   end
  68.  
  69.   if sound_timer == nil then
  70.     sound_timer = 500
  71.   end
  72.  
  73.   --By default the welcome sign dialog is used.
  74.   if dialog == nil then
  75.     dialog = "welcome_sign"
  76.   end
  77.  
  78.   --dialog_activation_distance default value
  79.   if dialog_activation_distance == nil then
  80.     dialog_activation_distance = 20
  81.   end
  82.  
  83.   function self:on_created()
  84.     sprite = self:create_sprite(sprite_directory) -- sprite_directory
  85.     self:set_can_traverse("hero", set_can_traverse_hero) -- set_can_traverse_hero
  86.     self:set_traversable_by("hero", set_traversable_by_hero) -- set_traversable_by_hero
  87.     self:set_drawn_in_y_order(true)
  88.     self:set_traversable_by(traversable)
  89.  
  90.     quick_movement = sol.movement.create("jump")
  91.     self:get_sprite():set_animation(animation) -- animation
  92.     quick_movement:set_ignore_obstacles(ignore_obstacles) -- ignore obstacles
  93.     quick_movement:set_direction8(direction8) --direction8
  94.     quick_movement:set_distance(jump_distance) -- distance
  95.     quick_movement:set_speed(speed) -- speed
  96.     quick_movement:start(self)
  97.  
  98.     sol.timer.start(sound_timer, function() --finish_time
  99.                  sol.audio.play_sound(jump_sound) --finish_animation
  100.           end)
  101.    
  102.   end
  103.  
  104.          sol.timer.start(finish_time, function() --finish_time
  105.      sol.audio.play_sound(finish_jump_sound)
  106.                  self:get_sprite():set_animation(finish_animation) --finish_animation
  107.          end)
  108.  
  109.   function self:on_interaction()
  110.     local distance_check = hero:get_distance(self)
  111.  
  112.     if distance_check <= dialog_activation_distance then -- dialog_activation_distance
  113.       if hero:get_direction() == 0 then
  114.         self:set_direction(2)
  115.         map:get_game():start_dialog(dialog) -- dialog
  116.       end
  117.       if hero:get_direction() == 1 then
  118.         self:set_direction(3)
  119.         map:get_game():start_dialog(dialog) -- dialog
  120.       end
  121.       if hero:get_direction() == 2 then
  122.         self:set_direction(0)
  123.         map:get_game():start_dialog(dialog) -- dialog
  124.       end
  125.       if hero:get_direction() == 3 then
  126.         self:set_direction(1)
  127.         map:get_game():start_dialog(dialog) -- dialog
  128.       end
  129.     end
  130.   end
  131.  
  132.   function self:on_movement_changed()
  133.      sprite:set_direction(quick_movement:get_direction4())  
  134.   end
  135. end

Code: Lua
  1. -------------------------------------------
  2. --Entity Jump Method
  3. -------------------------------------------
  4. function metatable_entity:jump(speed, traversable, ignore_obstacles, direction8, jump_distance, animation, finish_animation, finish_time, finish_jump_sound, jump_sound, sound_timer, dialog, dialog_activation_distance)
  5.  
  6.   local map = self:get_map()
  7.   local hero = map:get_hero()
  8.   local game = map:get_game()
  9.   local quick_movement
  10.  
  11.   --speed default value
  12.   if speed == nil then
  13.     speed = 40
  14.   end
  15.  
  16.   if traversable == nil then
  17.     traversable = false
  18.   end
  19.  
  20.   --By default the entity does not ignore obstacles
  21.   if ignore_obstacles == nil then
  22.     ignore_obstacles = false
  23.   end
  24.  
  25.   if direction8 == nil then
  26.     direction8 = 0
  27.   end
  28.  
  29.   if jump_distance == nil then
  30.     jump_distance = 100
  31.   end
  32.  
  33.   if animation == nil then
  34.     animation = "jumping"
  35.   end
  36.  
  37.   if finish_animation == nil then
  38.    finish_animation = "stopped"
  39.   end
  40.  
  41.   if finish_time == nil then
  42.     finish_time = 3000
  43.   end
  44.  
  45.   if jump_sound == nil then
  46.     jump_sound = "jump"
  47.   end
  48.  
  49.   if finish_jump_sound == nil then
  50.     finish_jump_sound = "jump"
  51.   end
  52.  
  53.   if sound_timer == nil then
  54.     sound_timer = 500
  55.   end
  56.  
  57.   --By default the welcome sign dialog is used.
  58.   if dialog == nil then
  59.     dialog = "welcome_sign"
  60.   end
  61.  
  62.   --dialog_activation_distance default value
  63.   if dialog_activation_distance == nil then
  64.     dialog_activation_distance = 20
  65.   end
  66.  
  67.     self:set_drawn_in_y_order(true)
  68.     self:set_traversable_by(traversable)
  69.  
  70.     quick_movement = sol.movement.create("jump")
  71.     self:get_sprite():set_animation(animation) -- animation
  72.     quick_movement:set_ignore_obstacles(ignore_obstacles) -- ignore obstacles
  73.     quick_movement:set_direction8(direction8) --direction8
  74.     quick_movement:set_distance(jump_distance) -- distance
  75.     quick_movement:set_speed(speed) -- speed
  76.     quick_movement:start(self)
  77.  
  78.     sol.timer.start(sound_timer, function() --finish_time
  79.                  sol.audio.play_sound(jump_sound) --finish_animation
  80.           end)
  81.  
  82.          sol.timer.start(finish_time, function() --finish_time
  83.      sol.audio.play_sound(finish_jump_sound)
  84.                  self:get_sprite():set_animation(finish_animation) --finish_animation
  85.          end)
  86.  
  87.   function self:on_interaction()
  88.     local distance_check = hero:get_distance(self)
  89.  
  90.     if distance_check <= dialog_activation_distance then -- dialog_activation_distance
  91.       if hero:get_direction() == 0 then
  92.         self:set_direction(2)
  93.         map:get_game():start_dialog(dialog) -- dialog
  94.       end
  95.       if hero:get_direction() == 1 then
  96.         self:set_direction(3)
  97.         map:get_game():start_dialog(dialog) -- dialog
  98.       end
  99.       if hero:get_direction() == 2 then
  100.         self:set_direction(0)
  101.         map:get_game():start_dialog(dialog) -- dialog
  102.       end
  103.       if hero:get_direction() == 3 then
  104.         self:set_direction(1)
  105.         map:get_game():start_dialog(dialog) -- dialog
  106.       end
  107.     end
  108.   end
  109.  
  110.   function self:on_movement_changed()
  111.      self:set_direction(quick_movement:get_direction4())  
  112.   end
  113. end

The Fix:
Code: Lua
  1. --Manual jump direction check
  2.   if direction8 == 0 or direction8 == 1 then
  3.     if self:get_direction() == 1 then -- up
  4.       self:set_direction(0)
  5.     end
  6.  
  7.     if self:get_direction() == 2 then -- left
  8.       self:set_direction(0)
  9.     end
  10.  
  11.     if self:get_direction() == 3 then -- down
  12.       self:set_direction(0)    
  13.     end
  14.  
  15.     if self:get_direction() == 0 then-- right
  16.       self:set_direction(0)
  17.     end
  18.   end
  19.  
  20.   if direction8 == 2 or direction8 == 3  then
  21.     if self:get_direction() == 1 then -- up
  22.       self:set_direction(1)
  23.     end
  24.  
  25.     if self:get_direction() == 2 then -- left
  26.       self:set_direction(1)
  27.     end
  28.  
  29.     if self:get_direction() == 3 then -- down
  30.       self:set_direction(1)    
  31.     end
  32.  
  33.     if self:get_direction() == 0 then-- right
  34.       self:set_direction(1)
  35.     end
  36.   end
  37.  
  38.   if direction8 == 4 or direction8 == 6 then
  39.     if self:get_direction() == 1 then -- up
  40.       self:set_direction(2)
  41.     end
  42.  
  43.     if self:get_direction() == 2 then -- left
  44.       self:set_direction(2)
  45.     end
  46.  
  47.     if self:get_direction() == 3 then -- down
  48.       self:set_direction(2)    
  49.     end
  50.  
  51.     if self:get_direction() == 0 then-- right
  52.       self:set_direction(2)
  53.     end
  54.   end
  55.  
  56.   if direction8 == 6 or direction8 == 7 then
  57.     if self:get_direction() == 1 then -- up
  58.       self:set_direction(3)
  59.     end
  60.  
  61.     if self:get_direction() == 2 then -- left
  62.       self:set_direction(3)
  63.     end
  64.  
  65.     if self:get_direction() == 3 then -- down
  66.       self:set_direction(3)    
  67.     end
  68.  
  69.     if self:get_direction() == 0 then-- right
  70.       self:set_direction(3)
  71.     end
  72.   end

MetalZelda

  • Sr. Member
  • ****
  • Posts: 480
    • View Profile
Re: Jump movement direction4 error?
« Reply #3 on: May 12, 2017, 05:53:55 pm »
http://www.solarus-games.org/doc/latest/lua_api_entity.html#lua_api_entity_on_movement_changed
Your approach is good but try with

Code: Lua
  1. function self:on_movement_changed(movement)
  2.   self:set_direction(movement:get_direction4())
  3. end

If it doesn't work, try
http://www.solarus-games.org/doc/latest/lua_api_movement.html#lua_api_movement_on_changed

Also, you are overwriting the on_interaction function, all custom entities with undefined on_interaction will have this "default" code. This might be related to http://forum.solarus-games.org/index.php/topic,974.0.html
« Last Edit: May 12, 2017, 06:02:28 pm by MetalZelda »

Zefk

  • Sr. Member
  • ****
  • Posts: 482
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: Jump movement direction4 error?
« Reply #4 on: May 13, 2017, 03:18:28 am »
Quote
If it doesn't work, try
http://www.solarus-games.org/doc/latest/lua_api_movement.html#lua_api_movement_on_changed 

Does not work.

Quote
Also, you are overwriting the on_interaction function, all custom entities with undefined on_interaction will have this "default" code. This might be related to http://forum.solarus-games.org/index.php/topic,974.0.html

No matter how I test it. If the custom entity is able to wander off after an on_interaction, then I can activate it as long as the hero does not move. If the hero moves 1 step, then it cancels.  The fact that it cancels when the hero moves it super strange because my code has nothing to do with the hero movement.
« Last Edit: May 13, 2017, 03:23:12 am by Zefk »

MetalZelda

  • Sr. Member
  • ****
  • Posts: 480
    • View Profile
Re: Jump movement direction4 error?
« Reply #5 on: May 13, 2017, 10:28:21 pm »
Can you send your project here ? I'll investigate this, weird issues there

Zefk

  • Sr. Member
  • ****
  • Posts: 482
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: Jump movement direction4 error?
« Reply #6 on: May 14, 2017, 01:19:00 am »
I attached the jump_lib.lua. Put it in the script directory.

From your main.lua put the following at the top.

Code: Lua
  1. require("scripts/jump_lib.lua")

Pick a sprite from the custom entity and paste the following into a custom entity script. The sprite will need a "jumping" and "stopped" animation. Also, a sound called "jump". Using the sample_quest and Eldran will work. Remember to change the direction of the custom entity. It jumps "right" by default.

Code: Lua
  1. -- Event called when the custom entity is initialized.
  2. function entity:on_created()
  3.   entity:jump()
  4. end

I have tested this outside of my project. I am pretty sure you will get the same result. That is why I reported it as a bug. This only happens with the jump movement.

https://github.com/solarus-games/solarus/issues/1057

For entity:jump_create() all you gotta do is paste it into a custom entity. This is the function that works. It uses Eldran as the default sprite. main_heroes/eldran

Code: Lua
  1. entity:jump_create()

You can change the directory.

Code: Lua
  1. entity:jump_create("main_heroes/eldran")

The jump_create function creates the sprite with script instead.

Code: Lua
  1. sprite = self:create_sprite(sprite_directory)
« Last Edit: May 14, 2017, 01:57:12 am by Zefk »

MetalZelda

  • Sr. Member
  • ****
  • Posts: 480
    • View Profile
Re: Jump movement direction4 error?
« Reply #7 on: May 14, 2017, 02:36:25 am »
What I see is, you try to get the direction4, which doesn't exist in the jump movement

You can only get direction8 from a jump movement, which is understandable

http://www.solarus-games.org/doc/latest/lua_api_jump_movement.html#lua_api_jump_movement_get_direction8

So then, to get a 4 direction way, simply divide by 2

Also in on_interaction, you can save a lot of space by doing

Code: Lua
  1. self:set_direction((2 + hero:get_direction()) % 4) -- Make the entity face the hero
  2. map:get_game():start_dialog(dialog) -- dialog

And i maintain, i don't get the on_interaction issue you're facing, so it comes from your code

If this doesn't solve the issue then it have something to do with your code, i'll investigate it tomorrow.
« Last Edit: May 14, 2017, 02:41:06 am by MetalZelda »

Zefk

  • Sr. Member
  • ****
  • Posts: 482
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: Jump movement direction4 error?
« Reply #8 on: May 14, 2017, 03:01:56 am »
What I see is, you try to get the direction4, which doesn't exist in the jump movement

You can only get direction8 from a jump movement, which is understandable

http://www.solarus-games.org/doc/latest/lua_api_jump_movement.html#lua_api_jump_movement_get_direction8

So then, to get a 4 direction way, simply divide by 2

I do not understand what you mean. Doesn't the following script make the hero turn depending on the direction the movement is moving? The hero should still face the jumping direction.

Code: Lua
  1.   function self:on_movement_changed()
  2.      self:set_direction(quick_movement:get_direction4())  
  3.   end

Jump movements are particular movement objects. Therefore, they inherit all methods from the type movement.
http://www.solarus-games.org/doc/latest/lua_api_movement.html#lua_api_movement_get_direction4

0 will make the hero jump to the right with the direction8 movement. If I face the hero up from the custom entity and jump, then the hero jumps to the right while facing up. It does this for everything else. I understand that the direction8 is different from the direction4.

Quote
Also in on_interaction, you can save a lot of space by doing

Code: Lua
  1. self:set_direction((2 + hero:get_direction()) % 4) -- Make the entity face the hero
  2. map:get_game():start_dialog(dialog) -- dialog

Thanks for the tip. I will try it out sometime.

Quote
And i maintain, i don't get the on_interaction issue you're facing, so it comes from your code

If this doesn't solve the issue then it have something to do with your code, i'll investigate it tomorrow.

Did you try letting the custom entity move away from the hero after interacting with it? If you move the hero one step, then the bug cancels. If the custom entity is standing still, then you will never get the bug because you will move the hero. Also, this does not happen with an NPC entity. This is kinda off topic.
« Last Edit: May 14, 2017, 03:27:36 am by Zefk »

Zefk

  • Sr. Member
  • ****
  • Posts: 482
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: Jump movement direction4 error?
« Reply #9 on: May 14, 2017, 03:51:18 am »
For example, If I set the direction8 to 2 for sprite to jump up and I face him down from the custom entity, then the following script should make him face up.

Maybe a visual explanation will help.


I use this script to change his direction, but it does not work.
Code: Lua
  1.   function self:on_movement_changed()
  2.      self:set_direction(quick_movement:get_direction4())  
  3.   end


1.I set direction8 to 0 for the hero to jump to the right. From the entity I face the entity up. He will jump right while facing up.

Code: Lua
  1.   entity:jump(speed, traversable, ignore_obstacles, 0, jump_distance, start_animation, finish_animation, finish_jump_sound, start_jump_sound, sound_timer, dialog, dialog_activation_distance)

2.I set the direction8 to 2 for the hero to jump up. From the entity I face the entity right. He will jump up while facing right.

Code: Lua
  1.   entity:jump(speed, traversable, ignore_obstacles, 2, jump_distance, start_animation, finish_animation, finish_jump_sound, start_jump_sound, sound_timer, dialog, dialog_activation_distance)

My entity:jump_create() function works. It is 95% identical to entity:jump(). The major difference with entity:jump_create() is that it creates the sprite by script.  I believe that using a sprite from the custom entity with the jump movement causes a facing direction bug.
« Last Edit: May 16, 2017, 03:17:38 pm by Zefk »