Recent Posts

Pages: 1 [2] 3 4 ... 10
11
Bugs & Feature requests / Re: Improve gamepad support
« Last post by alexgleason on October 14, 2018, 10:03:14 pm »
SDL_gamecontroller sounds like magic. Did this pull request ever happen?
12
Development / Re: Adding gamepad support to the title screen
« Last post by Diarandor on October 14, 2018, 08:29:31 pm »
13
Development / Re: Adding gamepad support to the title screen
« Last post by alexgleason on October 14, 2018, 06:56:08 pm »
This is a FAR simpler solution. If you're willing to just accept that your game has only one save file, you can start it up first thing, then you'll be free to use on_command_pressed in your menus. Nothing else but this is needed in your main.lua:

Code: Lua
  1. function sol.main:on_started()
  2.   local game = sol.game.load("save1.dat")
  3.   game:start() -- This is where the magic happens
  4.  
  5.   sol.menu.start(game, solarus_logo) -- We're setting the menus to use the "game" we started above
  6.  
  7.   function solarus_logo:on_finished()
  8.     sol.menu.start(game, title_screen) -- The title screen uses internal logic to reload the game once it's ready
  9.   end
  10.  
  11. end
  12.  
14
Development / Adding gamepad support to the title screen
« Last post by alexgleason on October 14, 2018, 04:24:20 pm »
Hey all, just wanted to share my progress with this. I ended up writing a script that gives default configs to any menu object:

scripts/enable_commands.lua
Code: Lua
  1. -- ♡ Copying is an act of love. Please copy and share.
  2. --
  3. -- Use this script to pass in a game or menu object and have it set up
  4. -- default keyboard and joystick controls so you can use `on_command_pressed`
  5. -- as expected.
  6. --
  7. -- Usage:
  8. --    local enable_commands = require("scripts/enable_commands")
  9. --    enable_commands.enable(my_menu)
  10. --
  11. -- Then simply define `function my_menu:on_command_pressed(command)`
  12.  
  13. local enable_commands = {}
  14.  
  15.  
  16. local function on_key_pressed(self, key)
  17.   if self.on_command_pressed == nil then return true end
  18.   if key == "space" then self:on_command_pressed("action")
  19.   elseif key == "c" then self:on_command_pressed("attack")
  20.   elseif key == "d" then self:on_command_pressed("pause")
  21.   elseif key == "up" then self:on_command_pressed("up")
  22.   elseif key == "down" then self:on_command_pressed("down")
  23.   elseif key == "left" then self:on_command_pressed("left")
  24.   elseif key == "right" then self:on_command_pressed("right")
  25.   elseif key == "x" then self:on_command_pressed("item_1")
  26.   elseif key == "v" then self:on_command_pressed("item_2") end
  27.   return true
  28. end
  29.  
  30. local function on_key_released(self, key)
  31.   if self.on_command_released == nil then return true end
  32.   if key == "space" then self:on_command_released("action")
  33.   elseif key == "c" then self:on_command_released("attack")
  34.   elseif key == "d" then self:on_command_released("pause")
  35.   elseif key == "up" then self:on_command_released("up")
  36.   elseif key == "down" then self:on_command_released("down")
  37.   elseif key == "left" then self:on_command_released("left")
  38.   elseif key == "right" then self:on_command_released("right")
  39.   elseif key == "x" then self:on_command_released("item_1")
  40.   elseif key == "v" then self:on_command_released("item_2") end
  41.   return true
  42. end
  43.  
  44. local function on_joypad_button_pressed(self, button)
  45.   if self.on_command_pressed == nil then return true end
  46.   if button == 0 then self:on_command_pressed("action")
  47.   elseif button == 1 then self:on_command_pressed("attack")
  48.   elseif button == 4 then self:on_command_pressed("pause")
  49.   elseif button == 2 then self:on_command_pressed("item_1")
  50.   elseif button == 3 then self:on_command_pressed("item_2") end
  51.   return true
  52. end
  53.  
  54. local function on_joypad_button_released(self, button)
  55.   if self.on_command_released == nil then return true end
  56.   if button == 0 then self:on_command_released("action")
  57.   elseif button == 1 then self:on_command_released("attack")
  58.   elseif button == 4 then self:on_command_released("pause")
  59.   elseif button == 2 then self:on_command_released("item_1")
  60.   elseif button == 3 then self:on_command_released("item_2") end
  61.   return true
  62. end
  63.  
  64. local function on_joypad_axis_moved(self, axis, state)
  65.   if axis == 0 then
  66.     if state == 1 and self.on_command_pressed then self:on_command_pressed("right")
  67.     elseif state == -1 and self.on_command_pressed then self:on_command_pressed("left")
  68.     elseif state == 0 and self.on_command_released then
  69.       -- FIXME: Only release the last command?
  70.       self:on_command_released("right")
  71.       self:on_command_released("left")
  72.     end
  73.   end
  74.   if axis == 1 then
  75.     if state == 1 and self.on_command_pressed then self:on_command_pressed("down")
  76.     elseif state == -1 and self.on_command_pressed then self:on_command_pressed("up")
  77.     elseif state == 0 and self.on_command_released then
  78.       -- FIXME: Only release the last command?
  79.       self:on_command_released("down")
  80.       self:on_command_released("up")
  81.     end
  82.   end
  83.   return true
  84. end
  85.  
  86. -- Enable on an item
  87. function enable_commands.enable(item)
  88.   item.on_key_pressed = on_key_pressed
  89.   item.on_key_released = on_key_released
  90.   item.on_joypad_button_pressed = on_joypad_button_pressed
  91.   item.on_joypad_button_released = on_joypad_button_released
  92.   item.on_joypad_axis_moved = on_joypad_axis_moved
  93. end
  94.  
  95. return enable_commands
  96.  

Then just run your menu through this, either in main.lua or in your menu script itself, like so:

Code: Lua
  1. local enable_commands = require("scripts/enable_commands")
  2.  
  3. -- Ability to use game commands on these menus
  4. enable_commands.enable(title_screen)
  5.  
  6. function title_screen:on_command_pressed(command)
  7.   -- Handle commands here! No need to handle keys or joypad inputs.
  8. end
  9.  

It's a horribly verbose script! But it works. Normally the save file stores the controller config, so it creates a chicken and egg problem where you must create a save file before you can configure a gamepad, but need to go through the file select menu first. This partially works around that by assigning the Solarus default keyboard and joystick inputs to normal gamepad actions like "attack" and "action" etc. for a particular menu (the title screen).

What I think I'll actually end up doing is load the game before the title screen, and maybe let the player configure their input device here. My goal is to make the game playable on a platform like RetroPie where no keyboard exists. But this works for now.

As a side note, I think having 3 separate save files is overkill for most Solarus games. Unlike the days of Super Nintendo, most people have their own personal devices that can run Solarus, whether that's a laptop, desktop, Android phone/tablet, or Nintendo Switch. The exception might be a RetroPie device, but even then these often have hundreds of games and different people will probably be playing a different game during a different time. So, I'm going to focus on handling 1 save file at a time which will make things much easier.
15
Your scripts / Auto-assign an item to slot 1 if it's empty.
« Last post by alexgleason on October 13, 2018, 03:40:57 am »
This script is useful for when your character receives the first item of the game. Rather than making them equip the item, you can make it automatically assigned to slot 1. Adding slot 2 support probably wouldn't be too difficult. Here's the script.

Code: Lua
  1. -- ♡ Copying is an act of love. Please copy and share.
  2.  
  3. require("scripts/multi_events.lua")
  4.  
  5. -- When the player obtains their first item, assign it to slot 1 automatically
  6.  
  7. local function item_obtained_cb(self, variant, savegame_variable)
  8.   local slot_1 = sol.main.game:get_item_assigned(1)
  9.   if slot_1 == nil and self:is_assignable() then
  10.     sol.main.game:set_item_assigned(1, self)
  11.   end
  12. end
  13.  
  14. local item_metatable = sol.main.get_metatable("item")
  15. item_metatable:register_event("on_obtained", item_obtained_cb)

Install it by creating the file scripts/item_auto_assign.lua in your project and pasting the above code.

Then, open scripts/features.lua and add this to the list:

Code: Lua
  1. require("scripts/item_auto_assign")

I am assuming you're using the Solarus engine boilerplate code, which already includes the multi_events script.
16
Your projects / Re: Vegan on a Desert Island
« Last post by alexgleason on October 12, 2018, 06:39:45 pm »
I played Survival Kids for a few hours last night. It really is super similar to what I'm going for! I was surprised.

The way you can collect, use, and combine items was really illuminating. I think this will help me make some decisions about that. Thanks again. :D

I agree that it's too hard, though. I prefer to enjoy the game I'm playing instead of feeling like I'm constantly fighting for my life, haha.
17
Development / Re: Cutscene troubles (as menu)
« Last post by Christopho on October 12, 2018, 12:40:14 pm »
You stored the game on the cutscene table (cutscene.game), but you are trying to access it just with "game".
18
Development / Re: Cutscene troubles (as menu)
« Last post by Eyth on October 12, 2018, 11:16:01 am »
Tried it, I'm still doing something wrong...

When I have:
Code: Lua
  1. local cutscene = {}
  2.  
  3. function cutscene:intialize(game)
  4. cutscene.game = game
  5. end
  6.  
  7. function cutscene:on_started()
  8. --sprites, sol.audio.stop_music(), timers--
  9. end
  10.  
  11. function cutscene:on_finished()
  12. --timers:stop, hero:unfreeze()
  13. game:set_paused_allowed(true)
  14. end
  15.  
  16. function cutscene:on_draw(battle_surface)
  17. --sprites and images--
  18. end
  19.  
  20. function cutscene:on_command_pressed(command)
  21.   if command == "action" then
  22.     sol.menu.stop(self)
  23.   end
  24. end
  25.  
  26. return cutscene
  27.  

...the engine says:"Error: In on_finished: scripts/cutscene.lua:13: attempt to index global 'game' (a nil value)"
I have to add, I made an "on_command_pressed()" event to test the scene, because it doesnt end itself for now.

So I still cant use game-events, what am I doing wrong?  ???
19
Not sure if this is a bug or user error, but I wanted to share.

My goal is to disable the "attack" command completely and use the sword as a standard item (with hero:start_attack()). In main.lua:

Code: Lua
  1. function game:on_command_pressed(command)
  2.   -- Disable attacking; the stick is a regular item
  3.   if command == "attack" then
  4.     return true
  5.   end
  6.   ...
  7. end

However, when I swing the sword, I can actually still press and hold the attack button while the sword is mid-animation. This causes sword-loading to trigger. I'm baffled by the fact I can do this when I've overridden the attack command to "return true" whenever it's pressed. ???

I ended up adding this to scripts/meta/hero.lua to solve my issue:

Code: Lua
  1. -- The hero can only swing the sword, nothing else
  2. function hero:on_state_changed(state)
  3.   if state == "sword loading"
  4.   or state == "sword tapping"
  5.   or state == "sword spin attack" then
  6.     hero:freeze()
  7.     hero:unfreeze()
  8.   end
  9. end

Freezing and unfreezing the hero when going into the sword loading state effectively disables that state, which is what I want. (In my game the sword is limited)
20
so your downside is my upside, haha.

Aaaannndd this is how a bug becomes a feature. ;D
Pages: 1 [2] 3 4 ... 10