Recent Posts

Pages: 1 2 [3] 4 5 ... 10
21
Development / Re: Need Help With Having an NPC Follow the Hero
« Last post by PhoenixII54 on May 09, 2023, 11:40:17 AM »
I don't see any obvious mistake (maybe i would have organized the list in the style 1 entry = an {x=x,y=y} pair but that's just a coding preference) so my guess is that your movement gets overwritten each frame you move and doesn't have time to even start until you stop moving.
So what you should try to do is to detect if the follower NPC already has a movement and update it's target (if possible) instead of recreating a new one each frame, and only create it again if it it reached its actual destination when the hero has stopped moving.
22
Your scripts / Re: (Updated!) Level and Experience system -- V1.6.4
« Last post by helendam on May 09, 2023, 04:27:18 AM »
Here is the new script with some typos corrected, several bugs worked out, and a few things just tidied up.

Thank you D MAS for bringing the corrected issues to my attention. I found a few more issues that bugged me while I was reworking this script so those fixes are in here as well. For instance, once you reach the maximum level, the game will record your experience as being maxed out rather than recording it as 0. It could be improved more but for now I think it will work for most people's purposes.

Code: [Select]
-- LEVEL (LVL) and EXPERIENCE (EXP) counters shown on the game screen.

-- LVL AND EXP  version 1.6
-- from a script (for rupees) by christopho
-- Modified by froGgy for a Zelda-like (ZL) project.
-- v 1.0:  First version posted. It is just a draft.
-- Modified by Kamigousu on 18/07/19.
-- v 1.6:  Updated for use with Solarus 1.6; basic with lots of potential, mostly just froggy77's original draft.
--Modified by D MAS and Kamigousu on 16/01/21.
--v 1.6.4: Updated for clarity and ease of use.

--Additional code and notes are included at the bottom for convenience. Please read them before continuing.

local lvl_and_exp = {}

function lvl_and_exp:new(game)

  local object = {}
  setmetatable(object, self)
  self.__index = self

  object:initialize(game)

  return object
end

function lvl_and_exp:initialize(game)

  self.game = game
  self.surface = sol.surface.create(112, 24)
  self.digits_text_for_lvl = sol.text_surface.create{
    font = "green_digits",
    horizontal_alignment = "left",
  }
  self.digits_text_for_exp = sol.text_surface.create{
    font = "white_digits",
    horizontal_alignment = "left",
  }
  self.digits_text_for_exp_to_levelup = sol.text_surface.create{
    font = "white_digits",
    horizontal_alignment = "left",
  }

  --Set the initial level and experience to 1 and 0 respectively,
  --if they are not all ready set.
  if not self.game:get_level() or self.game:get_level() == 0 then self.game:set_level(1) end
  if not self.game:get_exp() then self.game:set_exp(0) end
 
  self.digits_text_for_lvl:set_text(game:get_level())
  self.digits_text_for_exp:set_text(game:get_exp())
  self.lvl_icon_img = sol.surface.create("hud/lvl_and_exp_icon.png")
  self.exp_icon_img = sol.surface.create("hud/lvl_and_exp_icon.png")
  self.slash_icon_img = sol.surface.create("hud/lvl_and_exp_icon.png")
  self.current_lvl_displayed = self.game:get_level()
  self.current_exp_displayed = self.game:get_exp()
  self.current_exp_displayed_length = string.len(self.current_exp_displayed)

  --Here are two options for setting up the exp_to_levelup table.
  --By default, option 2 is enabled.

  --The first will set up a very basic level up table that requires you
  --to fill in all the fields for each level up. You may stop at whatever
  --level you wish; that level will be the max level. That code is as follows:

  --self.t_exp_to_levelup = {100, 200, 300, 400, 500, 600, 700, 800}
  --self.max_level = #self.t_exp_to_levelup

--============================================

  --The second will set up a basic level up table that will fill in the experience
  --required for each level based on the total number of levels you would like.
  --This requires you to define the max level yourself and input the experience
  --required to level up to level 2 into the exp_to_levelup table.

  self.max_level = 20
  self.t_exp_to_levelup = {150}
  for key, value in ipairs(self.t_exp_to_levelup) do
    local next_key = key + 1
    if next_key <= self.max_level - 1 then
      self.t_exp_to_levelup[next_key] = math.ceil((self.t_exp_to_levelup[1] * next_key) + ((value * next_key) / 100))
      --Uncomment the print lines below to see the level and required experience to levelup in the console.
      --print(#self.t_exp_to_levelup)
      --print(self.t_exp_to_levelup[next_key])
    else
      break
    end
  end

  self.digits_text_for_exp_to_levelup:set_text(self.t_exp_to_levelup[self.current_lvl_displayed])
  self:rebuild_surface()
  self:check()
end

--Whenenever a game over is completed, the timer for this counter
--must be restarted.
function lvl_and_exp:on_started()
  self:rebuild_surface()
  self:check()
end

function lvl_and_exp:check()

  local need_rebuild = false
  local current_level = self.game:get_level()
  local current_exp = self.game:get_exp()
  local exp_to_levelup = self.t_exp_to_levelup[current_level]
  if exp_to_levelup == nil then
self.current_exp_displayed = self.t_exp_to_levelup[self.max_level - 1]
self.current_exp_displayed_length = string.len(self.current_exp_displayed)
   exp_to_levelup = self.t_exp_to_levelup[self.max_level - 1]
  end
  local difference = 0

-- Current LVL.
if current_level <= self.max_level then
  if current_level ~= self.current_lvl_displayed then
  need_rebuild = true
  local increment
  if current_level > self.current_lvl_displayed then
    increment = 1
  else
    increment = -1
  end
  self.current_lvl_displayed = self.current_lvl_displayed + increment
  -- Play a sound if we have just reached the final value.
  if self.current_lvl_displayed == current_level then
    if increment == 1 then
    sol.audio.play_sound("victory")
    sol.audio.play_sound("treasure")
    else
    sol.audio.play_sound("switch")
    sol.audio.play_sound("hero_falls")
    end
  end
  end
end

-- Current XP.
if current_level <= self.max_level - 1 then
  if current_exp ~= self.current_exp_displayed then
need_rebuild = true
local increment
    local difference = math.abs(current_exp - self.current_exp_displayed)
  if current_exp > self.current_exp_displayed then
        if difference >= 1000 then
      increment = 321
        elseif difference>= 100 then
          increment = 32
        else if difference >= 10 then
          increment = 3
        else
          increment = 1
        end
  else
        if difference >= 1000 then
      increment = -321
        elseif difference >= 100 then
          increment = -32
        else if difference >= 10 then
          increment = -3
        else
          increment = -1
        end
  end
  self.current_exp_displayed = self.current_exp_displayed + increment
  self.current_exp_displayed_length = string.len(self.current_exp_displayed)
  end

-- Level up
  if self.current_exp_displayed >= exp_to_levelup then
self.game:add_level(1)
      if self.game:get_level() ~= self.max_level then
    difference = current_exp - exp_to_levelup
    self.game:set_value("current_exp", difference)
    current_exp = self.game:get_value("current_exp")
    self.current_exp_displayed = 0
    self.current_exp_displayed_length = string.len(self.current_exp_displayed)
      end
  end
end

  -- Redraw the surface only if something has changed.
  if need_rebuild then
    self:rebuild_surface()
  end

  -- Schedule the next check.
  local timer = sol.timer.start(self.game, 10, function()
    self:check()
  end)
  timer:set_suspended_with_map()
end

function lvl_and_exp:rebuild_surface()

  self.surface:clear()

  -- LVL (icon).
  self.lvl_icon_img:draw_region(0, 0, 12, 12, self.surface)

  -- XP (icon).
  self.exp_icon_img:draw_region(12, 0, 12, 12, self.surface, 27, 0)
 
  -- SLASH (icon).
  self.slash_icon_img:draw_region(24, 0, 8, 12, self.surface, 40 + (8 * self.current_exp_displayed_length), 4)

    -- Current LVL (counter).
  if self.current_lvl_displayed == self.max_level then
    self.digits_text_for_lvl:set_font("green_digits")
  else
    self.digits_text_for_lvl:set_font("white_digits")
  end
  self.digits_text_for_lvl:set_text(self.current_lvl_displayed)
  self.digits_text_for_lvl:draw(self.surface, 12, 6)
 
  -- Current XP (counter).
  if self.current_lvl_displayed < self.max_level then
    self.digits_text_for_exp:set_font("white_digits")
    self.digits_text_for_exp:set_text(self.current_exp_displayed)
    self.digits_text_for_exp_to_levelup:set_font("white_digits")
  self.digits_text_for_exp_to_levelup:set_text(self.t_exp_to_levelup[self.current_lvl_displayed])
  else
    self.digits_text_for_exp:set_font("green_digits")
    self.digits_text_for_exp:set_text(self.current_exp_displayed)
    self.digits_text_for_exp_to_levelup:set_font("green_digits")
  self.digits_text_for_exp_to_levelup:set_text(self.t_exp_to_levelup[self.max_level - 1])
  end
  self.digits_text_for_exp:draw(self.surface, 40, 6)
  self.digits_text_for_exp_to_levelup:draw(self.surface, 48 + (8 * self.current_exp_displayed_length), 12)
end

function lvl_and_exp:set_dst_position(x, y)
  self.dst_x = x
  self.dst_y = y
end

function lvl_and_exp:on_draw(dst_surface)

  local x, y = self.dst_x, self.dst_y
  local width, height = dst_surface:get_size()
  if x < 0 then
    x = width + x
  end
  if y < 0 then
    y = height + y
  end

  self.surface:draw(dst_surface, x, y)
end

return lvl_and_exp



--[[********************************NOTES and CODE********************************

This script assumes you have the green and white digits fonts from the ALttP resource pack.
It also assumes you have the "victory", "treasure", "switch", and "hero_falls" sounds from that resource pack.
You may change these in the script to customise the sounds and digits for your game.


You must have a file named lvl_and_exp_icon.png in the sprites/hud folder or you must change the file name in this script to correspond with your own custom file.
If you use the file provided in the top comment on the forum page for this script (http://forum.solarus-games.org/index.php/topic,1362.msg8050.html#msg8050)
then you will not need to modify the script. If you use your own custom file, you will, more likely than not, need to modify this script at lines 178, 181, and 184
to draw the new image properly.
You DO NOT need to create sprites for this script to run. You only need to have the png image named correctly and in the proper folder.


The following must be put into your hud_config script, in the table with the rest of your hud elements;
unless you are putting the exp and lvl display in an inventory screen or some other menu, in which case you will have to require it in the proper lua file.

  --Level and Experience Counter
  {
    menu_script = ("scripts/hud/lvl_and_exp"),
    x = 210,    --X and Y can be changed to wherever you would like the exp counter displayed.
    y = 16,
  },


You must also add the functions game:get_level/exp(), set_level/exp(), and add_level/exp() to your game. 
In a seperate file named game.lua (or wherever you have a game metatable available) add the following:

--The line below can be omitted if you are putting the following function in a file with the metatable all ready defined.
local game_meta = sol.main.get_metatable("game")


function game_meta:get_level()
  return self:get_value("current_level")
end

function game_meta:set_level(level)
  return self:set_value("current_level", level)
end

function game_meta:add_level(level)
  local level = level
  local c_level = self:get_level()
  local level_up = c_level + level
  return self:set_value("current_level", level_up)
end

function game_meta:get_exp()
  return self:get_value("current_exp")
end

function game_meta:set_exp(exp)
  return self:set_value("current_exp", exp)
end

function game_meta:add_exp(exp)
  local exp = exp
  local c_exp = self:get_exp()
  local exp_up = c_exp + exp
  return self:set_value("current_exp", exp_up)
end

If you are using the standard features.lua script, it is recommended to require the file that holds the code above in that script.
--]]

I did not change the placement or spacing for the level and experience text but those changes are documented in the script posted by D MAS. Also, I feel that aesthetic choices like that are best left up to the developer using the system. The script here is meant to be easily mutable.

Please feel free to reply with comments or questions or come to the discord to ask/comment. The image file for the icons can still be found in the top comment of this thread or you can use D MAS' file (see comment above) that they were kind enough to share.

Thanks again Froggy77 and D MAS!

EDIT: Added a few more features like pausing with the map and adjusted spacing for the exp and separating slash. It also now counts up exp fasterbackrooms game if there is a large amount of experience to add. Thank you Max for providing a nice example of how to do that; my initial idea was a tad backwards.

EDIT2:  Small fix to the increment portion of the check function.
Thanks for sharing
23
Development / Re: Need Help With Having an NPC Follow the Hero
« Last post by lefthandedhero on May 08, 2023, 07:09:26 PM »
Using the advice above, I created the following code. Note that "Follower" is the name of the NPC:

Code: [Select]
-- Table to store the hero's old postion (List[0] = x, List[1] = y, List[2] = layer):
  List = {}
  -- Follower Movement:
  function hero:on_position_changed(x, y, layer)
    -- If not the hero's first movement:
    if List[0] ~= nil then
      -- Move Follower to the old coordinates
      local movement = sol.movement.create("target")
      -- Set the previous position as the target
      movement:set_target(List[0], List[1])
      -- Make the movement speed match the hero
      movement:set_speed(88)
      -- Move
      movement:start(Follower)
    end
    -- Record the hero's new position
    List[0] = x
    List[1] = y
  end

The current code has two main problems:

1. Follower does not start moving until the moment the hero stops moving, when the idea was that the follower would move while the hero moves and stop when the hero stops.

2. Follower does not stop moving, as if the current target is the hero's current position when it should be the hero's previous position.

Where have I gone wrong in my implementation that is causing these problems?
24
Development / Re: Need Help With Having an NPC Follow the Hero
« Last post by lefthandedhero on May 05, 2023, 04:09:45 PM »
Hello, you can use the hero:on_position_changed() event, which is called each frame Link has moved.

Code: [Select]
-- <initialization stuff where you get the hero and NPC entities>

function hero:on_position_changed(x, y, layer)
--update your list here and move the NPC accordingly

end

Thank you very much. This is a big help.

An alternative way is to make a target movement towards the hero, and stop that movement when the distance between the NPC and the hero gets below some threshold. I think it is done that way in the Zelda A Link to the Dream project.
Your choice, I guess it depends on whether you want the NPC to follow exactly the same path as the hero or not.

Thank you. I do want the NPC to follow the same path as the hero; it's important for another component of the game that I'm trying to make that the NPC follow the same path. But I may fall back on that method if I can't get my current plan to work.
25
Development / Re: Need Help With Having an NPC Follow the Hero
« Last post by Christopho on May 05, 2023, 03:20:57 PM »
An alternative way is to make a target movement towards the hero, and stop that movement when the distance between the NPC and the hero gets below some threshold. I think it is done that way in the Zelda A Link to the Dream project.
Your choice, I guess it depends on whether you want the NPC to follow exactly the same path as the hero or not.
26
Development / Re: Need Help With Having an NPC Follow the Hero
« Last post by PhoenixII54 on May 05, 2023, 11:30:22 AM »
Hello, you can use the hero:on_position_changed() event, which is called each frame Link has moved.

Code: [Select]
-- <initialization stuff where you get the hero and NPC entities>

function hero:on_position_changed(x, y, layer)
--update your list here and move the NPC accordingly

end
27
General discussion / Re: What's Your Favorite Zelda Game?
« Last post by lefthandedhero on May 03, 2023, 08:44:10 PM »
1. Spirit Tracks. I recognize that there are better Zelda games, and I myself have some grievances with it; namely that the spirit flute has to be by far the worst Zelda instrument. But the things work about this game are done amazingly well and easily more than make up for its faults. I really like the train, and I love Spirit Zelda: having Princess Zelda be Link's adventuring companion in this game was nothing short of brilliant, to the point where I almost wonder why it wasn't done sooner and I do wonder why it hasn't been done since. Controlling Link and Zelda together is a ton of fun.

2. Ocarina of Time. It introduced me to the Zelda series, so of course it's going to be in the top 3, and it helps that it's still one of the best Zelda games overall.

Nominations for 3rd place: Link's Awakening, Majora's Mask, Wind Waker and Breath of the Wild.

Winner of the position of 3rd place: Wind Waker. There isn't really much to say; like Sprit Tracks, the game has a ton of charm, the sailing is fun, and I really like the deep narrative under the surface and the theme of the winds of change and the idea that Hyrule waiting for a hero to appear was exactly what doomed Hyrule.
28
Development / Need Help With Having an NPC Follow the Hero
« Last post by lefthandedhero on May 02, 2023, 07:36:06 PM »
Hello.

I am new to using the Solarus engine. I want to create an NPC that follows the hero as a companion by closely following behind the hero and following the same path as the hero; the type of movement that's used in A Link to the Past when Link escorts Zelda out of Hyrule Castle and when Marin accompanies Link for part of Link's Awakening, and is at as old as the classic snake game genre.

Any suggestions for implementing this in Solarus?


UPDATE 1: After watching some videos of the section of A Link to the Past where Link escorts Zelda out of Hryule Castle for reference, I observed some details of Zelda's movement that may help: upon entering any new area or exiting a set of stairs, Zelda always starts one in-game step behind Link, stays still after Link's first in-game step, then starts moving after Link's second in-game step, with Zelda's steps being the step Link took two steps previously. When Link stops moving, Zelda immediately stops moving at the same time, and when Link resumes moving, Zelda immediately resumes moving.

After observing this, the plan I have created is to essentially store the hero's movements in a linked list of maximum length 1: upon entering a new map section, the linked list will be empty. When the hero moves, their "step" is pushed into the list, and once the list is full, the non-playing character does each step that is "popped" out of the linked list. When the hero stops moving, the non-playing character stops moving.

I know how to create a linked list in Lua, so there are two things I still need:
1. The ideal method of storing each in-game step in the linked list.
2. How to implement, "while (the hero is moving) {}".

Any suggestions for solving those two things?
29
General discussion / What's Your Favorite Zelda Game?
« Last post by PoPCaT6800 on April 29, 2023, 04:46:42 PM »
What's Your Top 3 Favorite Zelda Games? tell me in the comments!

My Favorites

3: The Legend Of Zelda: A Link Between Worlds
When I got this game on my 3DS, I was amazed by how it managed to remind you so much of ALTTP while making it's own game. I loved the music remixes and everything was so fluid.

2: The Legend Of Zelda: A Link To The Past
When I was younger, I hated old pixel style games. They freaked me out for some reason. Eventually my Dad made me play the original Zelda 1. I didn't really like it, but eventually I tried ALTTP. Something clicked, and in the blink of an eye I had spent at least 75 hours playing (I still haven't finished).

3: The Legend Of Zelda: Twilight Princess
This was my very first Zelda game. I was digging around in the wii games for something to play and I came across TP. I wasn't sure if it was going to be any good or not. I loved it. I spent so much time trying to figure out the Zora temple and beat Ganon that I probaly spent a good year of my life on it.

What's your top 3?
30
Development / Re: Solarus Quest Resolution Size
« Last post by ZeldaGamer on April 28, 2023, 02:37:23 AM »
Found a solution, for anyone interested:

File => Quest Properties ... and changing the resolution right in the menu
Editing the quest.dat file in the main directory also works
Pages: 1 2 [3] 4 5 ... 10