Solarus Forum

Solarus => Development => Topic started by: dpro_games on April 04, 2017, 09:05:39 pm

Title: Small Key HUD ?
Post by: dpro_games on April 04, 2017, 09:05:39 pm
Hello, I followed Christopho's tuto and I don't understand how to display a small key counter...

The small_key item:

Code: [Select]
local item = ...
local game = item:get_game()

--small_key option
function item:on_created()
  self:set_shadow("small")
  self:set_can_disappear(false)
  self:set_brandish_when_picked(true)
  self:set_sound_when_picked("picked_small_key")
  item:set_amount_savegame_variable("small_keys_save")
end

--small_key save
function item:on_obtaining()
  item:add_amount(1)
end

Thank you for helping me !
Title: Re: Small Key HUD ?
Post by: Christopho on April 04, 2017, 09:22:18 pm
There are several ways to do that. The easiest is to make a small key item that increments a saved value.

And then you need a HUD element that draws this saved value on the screen.
Title: Re: Small Key HUD ?
Post by: MetalZelda on April 04, 2017, 09:23:50 pm
You need to create a menu, and attach it to the HUD script (if you use any).
You can use the savegame variable to display the correct number of small keys
You can look how it is done in MoSDX
Title: Re: Small Key HUD ?
Post by: Christopho on April 04, 2017, 09:28:08 pm
Mystery of Solarus DX is quite old, I have more modular examples now.

For example: https://github.com/solarus-games/zelda-xd2-mercuris-chess/blob/dev/data/items/small_key.lua
Which calls code of this script: https://github.com/solarus-games/zelda-xd2-mercuris-chess/blob/dev/data/scripts/equipment.lua
With detection of the current map to know which small key counter to update (basically, which dungeon).

Another way is to make several small key items, one for each dungeon. Same thing for the map, the compass and the big key. A bit easier but very repetitive.
Title: Re: Small Key HUD ?
Post by: dpro_games on April 04, 2017, 09:31:48 pm
Thank for your answers but I'm really begining in the world of programmation... For now, I'm trying to modifiying the christopho's script for the HUD called rupee but I don't know how it work... I have already check those scripts but it's to complicate (I'm talking about mercuris chess)...

The ruppee code in the tutorial:

Code: [Select]
-- The money counter shown in the game screen.

local rupees_builder = {}

local rupee_icon_img = sol.surface.create("hud/small_key_icon.png")

function rupees_builder:new(game, config)

  local rupees = {}

  local digits_text = sol.text_surface.create({
    font = "white_digits",
    horizontal_alignment = "left",
    vertical_alignment = "top",
  })
  local money_displayed = game:get_money()

  local dst_x, dst_y = config.x, config.y

  function rupees:on_draw(dst_surface)

    local x, y = dst_x, 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

    rupee_icon_img:draw(dst_surface, x + 8, y)
    digits_text:draw(dst_surface, x, y + 10)
  end

  -- Checks whether the view displays correct information
  -- and updates it if necessary.
  local function check()

    local need_rebuild = false
    local money = game:get_money()
    local max_money = game:get_max_money()

    -- Current money.
    if money ~= money_displayed then

      need_rebuild = true
      if money_displayed < money then
        money_displayed = money_displayed + 1
      else
        money_displayed = money_displayed - 1
      end

      if money_displayed == money  -- The final value was just reached.
          or money_displayed % 3 == 0 then  -- Otherwise, play sound "rupee_counter_end" every 3 values.
        sol.audio.play_sound("rupee_counter_end")
      end
    end

    if digits_text:get_text() == "" then
      need_rebuild = true
    end

    -- Update the text if something has changed.
    if need_rebuild then
      digits_text:set_text(string.format("%03d", money_displayed))

      -- Show in green if the maximum is reached.
      if money_displayed == max_money then
        digits_text:set_font("green_digits")
      else
        digits_text:set_font("white_digits")
      end
    end

    return true  -- Repeat the timer.
  end

  -- Periodically check.
  check()
  sol.timer.start(game, 40, check)

  return rupees
end

return rupees_builder
Title: Re: Small Key HUD ?
Post by: Christopho on April 04, 2017, 10:19:55 pm
Ok then yes, start with rupees, it is simpler than small keys. What are you trying to modify exactly and what went wrong?
Title: Re: Small Key HUD ?
Post by: MetalZelda on April 05, 2017, 01:18:58 am
Hmmmm, I do wonder if there is any difference between MoS and MC alteration of these scripts ? because MOS looks simpler ...
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 06:51:25 am
I don't really know what I modify... I'm trying with chance. For now I got two counter, one for rupee with rupee's icon and an other rupee's counter with key's icon but I would like it display the number of keys... I have a big problem with variable and the save in solarus... (Where is the variable "money"..., how to use a variable from an item...)
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 02:13:38 pm
I have used the code you gived to me ("small_key" and "equipment") but now, when I take a key I got an error:

Error: In on_obtaining: [string "items/small_key.lua"]:12: attempt to call method 'add_small_key' (a nil value)

Why ?... What sort of things I need to do to make it work well ?!  :-\
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 02:23:53 pm
It is explained in the comments of equipment.lua. You need to require("scripts/equipment.lua") at least once. I usually do it from scripts/features.lua
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 02:25:31 pm
(Where is the variable "money"..., how to use a variable from an item...)
game:get_money()

(how to use a variable from an item...)
item:get_amount()
But small keys are more compilcated since we want different small key counters in each dungeon. Start with something easier like rupees or the bow and arrows.
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 02:36:04 pm
It's not possible to have a simple script for the keys ? I don't want to have different key counters in each dungeon... I can't just have a really simple key counter like rupee but for the key ?
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 02:39:20 pm
Well that's exacty the purpose of my equipment.lua script. It provides a function game:get_num_small_keys() so that it is very easy for the HUD.
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 02:40:32 pm
Je peux parler fr ce sera plus simple ?
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 02:45:08 pm
Oui pas de souci :)
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 02:49:19 pm
En fait, je commence vraiment la programmation et là, çà fait déjà plusieurs semaine que je bloque sur le système de clé avec le HUD... Donc en gros je ne comprend rien au script "equipment" (je doit supprimer quoi pour faire le truc le plus simple possible) et où je doit placer le require de ce script ? Vraiment merci d'accorder du temps au nouveau développeur !
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 02:52:36 pm
Donc si je comprends bien tu veux faire un item dont le seul effet est d'augmenter un compteur sauvegardé.
C'est en effet beaucoup plus simple si tu n'as pas de compteurs différents dans chaque donjon. Dans ce cas oublie mon script equipment.lua.

C'est comme l'item rubis, sauf qu'au lieu de game:add_money() tu incrémentes un compteur à toi.

Code: (lua) [Select]
local item = ...

function item:on_obtaining(variant, savegame_variable)

  local count = game:get_value("num_small_keys") or 0
  game:set_value("num_small_keys", count + 1)
end
Est-ce que le code cet item est clair ?

Et ton HUD n'a plus qu'à afficher la valeur de game:get_value("num_small_keys").
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 02:56:12 pm
Il y a encore un problème quand je prend une clé, j'ai une erreur différente maintenant :

Error: In on_obtaining: [string "items/small_key.lua"]:12: attempt to index global 'game' (a nil value)
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 03:00:29 pm
Ah oui, j'ai oublié de mettre une ligne local game = item:get_game().
Mais ça il faudrait savoir le corriger à l'aide du message d'erreur.
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 03:08:02 pm
Ca marche !! Merci beaucoup !!  :)
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 04:36:12 pm
J'ai de nouveau un problème au niveau du HUD cette fois, mais il me semble que j'ai presque réussis...

Le code du HUD pour la small_key :

Code: [Select]
-- The small_key counter shown in the game screen.

local small_key_builder = {}

local small_key_icon_img = sol.surface.create("hud/small_key_icon.png")

function small_key_builder:new(game, config)

  local small_key = {}

  local digits_text = sol.text_surface.create({
    font = "white_digits",
    horizontal_alignment = "left",
    vertical_alignment = "top",
  })
  local small_key_displayed = game:get_value("small_keys_save")

  local dst_x, dst_y = config.x, config.y

  function small_key:on_draw(dst_surface)

    local x, y = dst_x, 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

    small_key_icon_img:draw(dst_surface, x + 8, y)
    digits_text:draw(dst_surface, x, y + 10)
  end

end

return small_key_builder

Mais j'ai une erreur :

Error: In on_started: [string "scripts/hud/hud.lua"]:21: attempt to index local 'element' (a nil value)

Voici le script de la clé :

Code: [Select]
local item = ...
local game = item:get_game()

function item:on_created()

  self:set_shadow("small")
  self:set_brandish_when_picked(false)
  self:set_sound_when_picked("picked_small_key")
end

function item:on_obtaining(variant, savegame_variable)
 
  local count = game:get_value("small_keys_save") or 0
  game:set_value("small_keys_save", count + 1)
end
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 05:00:30 pm
Tu nous montres deux fichiers mais pas celui pointé dans le message d'erreur…
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 05:22:20 pm
Ah oui pardon, je suis débile...  ;D

Code: [Select]
-- Script that creates a head-up display for a game.

-- Usage:
-- require("scripts/hud/hud")

require("scripts/multi_events")
local hud_config = require("scripts/hud/hud_config")

-- Creates and runs a HUD for the specified game.
local function initialize_hud_features(game)

  -- Set up the HUD.
  local hud = {
    enabled = false,
    elements = {},
  }

  for _, element_config in ipairs(hud_config) do
    local element_builder = require(element_config.menu_script)
    local element = element_builder:new(game, element_config)
    if element.set_dst_position ~= nil then
      -- Compatibility with old HUD element scripts
      -- whose new() method don't take a config parameter.
      element:set_dst_position(element_config.x, element_config.y)
    end
    hud.elements[#hud.elements + 1] = element
  end

  -- Destroys the HUD.
  function hud:quit()

    if hud:is_enabled() then
      -- Stop all HUD elements.
      hud:set_enabled(false)
    end
  end

  -- Returns whether the HUD is currently enabled.
  function hud:is_enabled()
    return hud.enabled
  end

  -- Enables or disables the HUD.
  function hud:set_enabled(enabled)

    if enabled ~= hud.enabled then
      hud.enabled = enabled

      for _, menu in ipairs(hud.elements) do
        if enabled then
          -- Start each HUD element.
          sol.menu.start(game, menu)
        else
          -- Stop each HUD element.
          sol.menu.stop(menu)
        end
      end
    end
  end

  -- Returns whether the HUD is currently shown.
  function game:is_hud_enabled()
    return hud:is_enabled()
  end

  -- Enables or disables the HUD.
  function game:set_hud_enabled(enable)
    return hud:set_enabled(enable)
  end

  -- Call this function to notify the HUD that the current map has changed.
  local function hud_on_map_changed(game, map)

    if hud:is_enabled() then
      for _, menu in ipairs(hud.elements) do
        if menu.on_map_changed ~= nil then
          menu:on_map_changed(map)
        end
      end
    end
  end

  -- Call this function to notify the HUD that the game was just paused.
  local function hud_on_paused(game)

    if hud:is_enabled() then
      for _, menu in ipairs(hud.elements) do
        if menu.on_paused ~= nil then
          menu:on_paused()
        end
      end
    end
  end

  -- Call this function to notify the HUD that the game was just unpaused.
  local function hud_on_unpaused(game)

    if hud:is_enabled() then
      for _, menu in ipairs(hud.elements) do
        if menu.on_unpaused ~= nil then
          menu:on_unpaused()
        end
      end
    end
  end

  game:register_event("on_map_changed", hud_on_map_changed)
  game:register_event("on_paused", hud_on_paused)
  game:register_event("on_unpaused", hud_on_unpaused)

  -- Start the HUD.
  hud:set_enabled(true)
end

-- Set up the HUD features on any game that starts.
local game_meta = sol.main.get_metatable("game")
game_meta:register_event("on_started", initialize_hud_features)
return true
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 05:36:16 pm
Dans la fonction small_key_builder:new() tu as oublié de retourner le menu que tu viens de créer. Donc element est nil.
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 05:56:24 pm
Juste, comment faire pour que ma variable qui compte les clés soit égale a zéro aux début du jeu et pas a "nil" ?
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 06:01:25 pm
Une astuce est de faire comme mon code plus beau :
Code: (lua) [Select]
local count = game:get_value("small_keys_save") or 0
Rajouter "or 0" au bout pour initialiser à 0 si c'est nil.

Autre solution, initialiser au début du jeu (dans initial_game.lua) mais je me vois mal initialiser toutes les futures variables du jeu dès le départ.
Title: Re: Small Key HUD ?
Post by: dpro_games on April 05, 2017, 06:26:28 pm
Ça marche enfin !!  ;D
Vraiment merci de m'avoir accordé du temps pour m'aider ! J'ai compris plein de chose sur le fonctionnement de Solarus !

Et un gros GG pour avoir conçu le moteur de mes rêve: Solarus !   :)
Title: Re: Small Key HUD ?
Post by: Christopho on April 05, 2017, 09:34:59 pm
Content que tu aies compris et pas juste reproduit du coup ^^
Tu vas pouvoir continuer à progresser :)