Side scrolling functionality

Started by wizard_wizzle (aka ZeldaHistorian), June 25, 2015, 04:24:13 AM

Previous topic - Next topic
August 08, 2018, 02:40:59 AM #30 Last Edit: May 13, 2020, 06:02:23 PM by Zefk
I found a bug when holding down keys.  The hero glides around if I continue to hold the up and right keys at the same time and the hero retains the jump animation if I were to jump while holding the keys.

August 08, 2018, 08:14:53 AM #31 Last Edit: May 13, 2020, 06:02:45 PM by Zefk
Here is a little patch until wrightmat fixes the problem. The hero will not float and get stuck on the jumping animation. Although, it will not prevent the hero from standing still and moving when the right/down or left/down is being pressed at the same time.

Wrightmat's sidescroller script: here
Wrightmat's monster script: here

I think I heard a key on_pressing function was being made. Maybe that could fix the problem.

Patch for game:on_started():
Code ( lua) Select
  function game:on_started()
   local hero = game:get_hero()
    hero:set_tunic_sprite_id("main_heroes/eldran")
    sol.timer.start(gravity, function()
      if self:get_map() ~= nil then
        -- Gravity: move entities down one pixel on every update if there's no collision.
        --   (like with the ground or a platform) and hero not jumping or on a ladder.
        local hero = self:get_hero()
        local x, y, l = hero:get_position()
        if state ~= "jumping" and self:get_map():get_ground(hero:get_position()) ~= "ladder" then
          if not hero:test_obstacles(0, 1) then hero:set_position(x, (y + 1), l) end
        elseif state == "jumping" then
          for i = 1, jump_height do
            if not hero:test_obstacles(0, -1) then hero:set_position(x, (y - 1), l) end
          end
          sol.timer.start(gravity * jump_height, function()
            if self:is_command_pressed("right") or self:is_command_pressed("left") then
              state = "walking"
            else
              state = "stopped"
            end
            --right
            if self:is_command_pressed("right") and self:is_command_pressed("left") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("right") and self:is_command_pressed("up") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            --left
            if self:is_command_pressed("left") and self:is_command_pressed("right") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("left") and self:is_command_pressed("up") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            --up
            if self:is_command_pressed("up") and self:is_command_pressed("right") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("up") and self:is_command_pressed("left") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("up") and self:is_command_pressed("down") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
          end)
          hero:set_animation(state)
        end

  function game:on_key_pressed(key)
    local hero = game:get_hero()

    if key == "up" and key == "down" and key == "left" and key == "right"  then
      hero:set_animation("walking")
    else
      hero:set_animation("walking")
    end
  end


Explanation:

I added some checks function game:on_started() to prevent the hero from floating around.

Code ( lua) Select
            --right
            if self:is_command_pressed("right") and self:is_command_pressed("left") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("right") and self:is_command_pressed("up") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            --left
            if self:is_command_pressed("left") and self:is_command_pressed("right") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("left") and self:is_command_pressed("up") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            --up
            if self:is_command_pressed("up") and self:is_command_pressed("right") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("up") and self:is_command_pressed("left") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end
            if self:is_command_pressed("up") and self:is_command_pressed("down") then
              hero:set_animation("walking")
              state = "walking"
            else
              state = "stopped"
            end


I added this function to prevent the hero from being stuck on the jumping animation.

Code ( lua) Select
  function game:on_key_pressed(key)
    local hero = game:get_hero()

    if key == "up" and key == "down" and key == "left" and key == "right"  then
      hero:set_animation("walking")
    else
      hero:set_animation("walking")
    end
  end

This is a known issue. The side-scrolling script does not support jumping correctly yet.

August 09, 2018, 01:14:13 AM #33 Last Edit: May 13, 2020, 06:00:37 PM by Zefk
@Christopho
Ah, I had no idea.

Updated:

  • Added facing direction option when jumping
  • Added a fix for when the hero gets stuck on a ladder when using the bow
  • Added fixes for sword
  • Added fixes for tapping
  • Added fixes for running
  • Added fixes for lifting
  • Added fixes for water - needs to be converted to dynamic and named water
  • Added fixes for block
  • Added fixes for carrying destructible entities
  • Added fixes for boomerang
  • Added fixes for hookshot
  • Added fixes for opening chest
  • Added fixes for hole or falling
  • Added fake death
  • Added script and comment clean up
  • Added fixes for holding multiple keys when carrying

Download Quest: here

The thing I cannot figure out. The hero jumps faster and faster after every death. The only thing I can think of is to use a fake game:start().

Code ( lua) Select
        local map = game:get_map()
        --Fake death
        --map1
        if game:get_value("map1") == true and map:get_id() == "first_map" then
          if game:get_life() == 1 then
            hero:teleport("first_map", "map1", "fade")
            game:set_life(game:get_max_life())
          end
         --map2
         elseif game:get_value("map2") == true and map:get_id() == "map_leave_test" then
          if game:get_life() == 1 then
            hero:teleport("map_leave_test", "map2", "fade")
            game:set_life(game:get_max_life())
          end
        end


August 11, 2018, 02:13:31 AM #34 Last Edit: August 11, 2018, 03:35:54 AM by Zefk
I updated my post and made the side-scroling script somewhat stable: here

It is not perfect, but I could make a side-scroller game with it. I hope it helps someone out there.

Remember to credit Wrightmat because it is his script. I just patched it up.

P.S. I will just silently update the post above if I find bugs.

I can't figure out how to make this run. I put it in my Solarus folder, and it seems have roughly the same contents as the other quests there, but for some reason, the app won't detect it.

A custom feather allowing to jump in sideview maps was done recently, as an improved version of Wrightmat's script. But it will be slightly rewritten again, and using custom states, when Solarus 1.6 (with its custom states) is released.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

January 18, 2021, 10:14:30 AM #37 Last Edit: January 18, 2021, 11:10:05 AM by PhoenixII54
[Sorry for the necropost but since this thread has been mentioned on the Discord, i wanted to make an update before it goes forgotten under tons of Discord messages]

Some of you may already know but i actually tackled on rewriting the sidecrolller system for a Zelda: Links Awakening remake (ALTTD - A Link to the Dream).
As of today (2021, january 18th), the script is stable enough to be used in another project (in fact, someone did test to do it with success). You can find it here: https://gitlab.com/zeldaforce/zelda-alttd/-/blob/dev/data/scripts/maps/sideview_manager.lua.

This is still in development, though, since the internals are quite a hack, especially the sprite and hero movement  management, so i am in the process of using custom states instead. (it is already written in a separate branch, but it broke the ladder-top detection).
Also, the system works badly when you try to walk down slopes, (unfortunately, i don't have any idea how to handle this, maybe you can help me somehow ?), but this is a low-priority for now since the main project it is used on has none.

Prerequisites:
- Since it overwrites some of the metas, you will have to use a script that does allow multiples occurences of the same event (the multi_events.lua, which is required by the script, see header for more information), and never use the direct call to hero:on_position_changed, game:on_map_changed and hero:on_state_changed, since they are the triggers to launch the multiple timers used to update the Y-positions of the affected entities and the movement/commands handling for the hero.
- You will also need scripts/states/sideview_swim.lua, found in the same repository, and the following additional animations for the hero:
swimming_scroll
stopped_swimming_scroll
lifting_heavy
swimming_scroll_loading (+sword_loading_swimming_scroll for the sword sprite)
climbing_walking
climbing_stopped


Remarks:
- To make entities jump, just set your_entity.vspeed to a negative value.
- Being a fan project, the remake may be taken down at any point, so if the links get broken, then i will attach the script here instead.

thanks for the help, i'll see if i can do anything about the slopes

may as well download LttD as well, might have more things i wanna steal draw inspiration from and i might give feedback
i remember the old days of not knowing wtf to put in this box