[solved]Jump movement direction4 error?

Started by Zefk, May 10, 2017, 05:55:26 AM

Previous topic - Next topic
I confirm the bug. I got the same problem when I checked this with a custom entity.
Solarus Works on ReactOS Opensource Windows OS

https://www.reactos.org/forum/viewtopic.php?f=2&t=14759&p=120616#p120616

Sorry for my arrogance before, but I am under too much stress these days.
I have now tried the script directly (I didn't before, I had only read the code).

After "cleaning" the code a bit, it works, so I confirm that there is no bug (unless someone can prove that I am wrong  :P).
The problem is just that the script is not well coded, in the following parts:

I tested it with a custom_entity script. There is a line of code missing since "metatable_entity" is not defined, but I guess that it is
Code (Lua) Select
metatable_entity = ...
and in that case "metatable_entity" is not really a metatable in the formal sense (I think).

1) Your events on_interaction() and on_movement_changed() are not called the first time you create a jump, because they are defined inside your function "metatable_entity:jump". These events should be defined outside that function. Although the variable quick_movement is not defined outside the function "jump", you can still access the movement with entity:get_movement().

2) This part is really confusing and gives problems:
Code (Lua) Select

  sol.timer.start(450, function()

    function quick_movement:on_finished()
      set_stop_aniamtion = true
    end

    if set_stop_aniamtion == true then
     sol.audio.play_sound(finish_jump_sound)
                 self:get_sprite():set_animation(finish_animation) --finish_animation
   return false
    end

   return true
  end)

If your jump ends in less than 450 ms, the event quick_movement:on_finished() would never be called since it would be defined after the movement has ended. Actually you do not need a timer, and should probably write something like this instead of the above code:
Code (Lua) Select

    function quick_movement:on_finished()
      sol.audio.play_sound(finish_jump_sound)
      entity:get_sprite():set_animation(finish_animation)
    end


I can paste a copy of the modified script if you want. It works and the sprite of the custom entity is always facing the direction of the jump, which I believe is what you wanted (otherwise I did not understand your final purpose).

And I insist that having a clean code is more important that it may appear, not only for finding bugs, but also to make the code understandable to others who want to help you.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Quote2) This part is really confusing and gives problems:

Ah, I think you are correct about the timer. I will do some tests later. That would not prevent a facing direction change though.

Quote1) Your events on_interaction() and on_movement_changed() are not called the first time you create a jump, because they are defined inside your function "metatable_entity:jump". These events should be defined outside that function. Although the variable quick_movement is not defined outside the function "jump", you can still access the movement with entity:get_movement().

Everything is defined in my "Entity Create Jump Method" and it works, so I am not sure that is the problem. The only difference is that function self:on_created() is inside the script and the sprite is created by the function instead of being picked from the custom entity.

Code ( lua) Select
-------------------------------------------
--Entity Create Jump Method
-------------------------------------------
function metatable_entity:jump_create(sprite_directory, speed, traversable, set_can_traverse_hero, set_traversable_by_hero, ignore_obstacles, direction8, jump_distance, start_animation, finish_animation, finish_jump_sound, start_jump_sound, sound_timer, dialog, dialog_activation_distance)

  local map = self:get_map()
  local hero = map:get_hero()
  local game = map:get_game()
  local sprite
  local quick_movement

  --speed default value
  if speed == nil then
    speed = 40
  end

  if traversable == nil then
    traversable = false
  end

  --By default the entity cannot traverse the hero
  if set_can_traverse_hero == nil then
    set_can_traverse_hero = false
  end

  --By default the hero cannot traverse the entity.
  if set_traversable_by_hero == nil then
    set_traversable_by_hero = false
  end

  --By default the entity does not ignore obstacles
  if ignore_obstacles == nil then
    ignore_obstacles = false
  end

  if direction8 == nil then
    direction8 = 0
  end

  if jump_distance == nil then
    jump_distance = 100
  end

  --By default the sprite directory is the hero tunic1
  if sprite_directory == nil then
    sprite_directory = "main_heroes/Eldran"
  end

  if start_animation == nil then
    start_animation = "jumping"
  end

  if finish_animation == nil then
   finish_animation = "stopped"
  end

  if start_jump_sound == nil then
    start_jump_sound = "jump"
  end

  if finish_jump_sound == nil then
    finish_jump_sound = "jump"
  end

  if sound_timer == nil then
    sound_timer = 500
  end

  --By default the welcome sign dialog is used.
  if dialog == nil then
    dialog = "welcome_sign"
  end

  --dialog_activation_distance default value
  if dialog_activation_distance == nil then
    dialog_activation_distance = 20
  end

  function self:on_created()
    sprite = self:create_sprite(sprite_directory) -- sprite_directory
    self:set_can_traverse("hero", set_can_traverse_hero) -- set_can_traverse_hero
    self:set_traversable_by("hero", set_traversable_by_hero) -- set_traversable_by_hero
    self:set_drawn_in_y_order(true)
    self:set_traversable_by(traversable)

    quick_movement = sol.movement.create("jump")
    self:get_sprite():set_animation(start_animation) -- animation
    quick_movement:set_ignore_obstacles(ignore_obstacles) -- ignore obstacles
    quick_movement:set_direction8(direction8) --direction8
    quick_movement:set_distance(jump_distance) -- distance
    quick_movement:set_speed(speed) -- speed
    quick_movement:start(self)

    sol.timer.start(sound_timer, function() --finish_time
                 sol.audio.play_sound(start_jump_sound) --finish_animation
          end)
   
  end

  local set_stop_aniamtion = false

  sol.timer.start(450, function()

    function quick_movement:on_finished()
      set_stop_aniamtion = true
    end

    if set_stop_aniamtion == true then
     sol.audio.play_sound(finish_jump_sound)
                 self:get_sprite():set_animation(finish_animation) --finish_animation
   return false
    end

   return true
  end)

  function self:on_interaction()
    local distance_check = hero:get_distance(self)

    if distance_check <= dialog_activation_distance then -- dialog_activation_distance
      if hero:get_direction() == 0 then
        self:set_direction(2)
        map:get_game():start_dialog(dialog) -- dialog
      end
      if hero:get_direction() == 1 then
        self:set_direction(3)
        map:get_game():start_dialog(dialog) -- dialog
      end
      if hero:get_direction() == 2 then
        self:set_direction(0)
        map:get_game():start_dialog(dialog) -- dialog
      end
      if hero:get_direction() == 3 then
        self:set_direction(1)
        map:get_game():start_dialog(dialog) -- dialog
      end
    end
  end

  function self:on_movement_changed()
     sprite:set_direction(quick_movement:get_direction4())   
  end
end


QuoteI can paste a copy of the modified script if you want. It works and the sprite of the custom entity is always facing the direction of the jump, which I believe is what you wanted (otherwise I did not understand your final purpose).

I found the problem. The problem is that the facing direction will not change because function entity:on_movement_changed() is inside the function entity:on_created(). Taking it out results in correct direction change. That means it is not a bug I think. That is the only reason my script does not work for facing direction change.

I declared my function like this and that is why will not work.

function entity:on_created()
   entity:jump()
end

Try it out if you do not believe me.

Code ( lua) Select
local entity = ...
local game = entity:get_game()
local map = entity:get_map()

function entity:on_created()

    entity:set_drawn_in_y_order(true)
    entity:set_traversable_by(true)

    quick_movement = sol.movement.create("jump")
    entity:get_sprite():set_animation("jumping") -- animation
    quick_movement:set_ignore_obstacles(true) -- ignore obstacles
    quick_movement:set_direction8(2) --direction8
    quick_movement:set_distance(100) -- distance
    quick_movement:set_speed(100) -- speed
    quick_movement:start(entity)

  function entity:on_movement_changed()
     entity:set_direction(quick_movement:get_direction4())   
  end
end


I will go ahead and close the issue I reported.

Quote from: Zefk on June 24, 2017, 07:32:36 AM
I found the problem. The problem is that the facing direction will not change because function entity:on_movement_changed() is inside the function entity:on_created().
It is good to see that there is no engine bug this time and all is fixed. (The less bugs it has, the sooner we will have new features added by Chris.  ;D) Yes, we should close the github issue.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."