Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Elias Daler

Pages: [1] 2 3 ... 40
1
Feature requests / Re: XInput support
« on: October 14, 2019, 05:15:38 pm »
Of course, it's possible to switch DInput/XInput at runtime, and by default DInput should be used.

2
Feature requests / XInput support
« on: October 10, 2019, 02:45:15 pm »
Supporting XInput on Windows will allow use to have the following:
* Have triggers be independent axes instead of one
* Support vibration (not sure if SFML needs to have API for that or it users would be able to get some state out of SFML to handle that using XInput directly)

Xbox 360 and Xbox One amount to ~64% of gamepads used on Steam, so I think that this feature is necessary to have to be able to handle Xbox 360/Xbox One gamepads correctly.

Also, some gamepads (e.g. Logitech ones) also have a switch from DInput to XInput, so Xbox gamepads are not the ones who rely on XInput to work.

3
SFML projects / Re: [Release][GUI] ImGui-SFML
« on: October 02, 2019, 03:39:52 pm »
What IDE/build system are you using? You're not linking to ImGui and ImGui-SFML, which means that you haven't included imgui.cpp, imgui_widgets.cpp and imgui-SFMLcpp to your build

4
Working on quests - tried to simplify stuff as much as possible, and put it in one script per quest. And it works well! Here's an example of quest state:

InHouseState.entityStates = {
    luna = function(e, quest)
        setActionListOnInteraction(e, beforeKill, quest)
    end
}

InHouseState.sceneEnter = {
    luna_house_basement = function(quest)
        saveManager:setQuestData(QUEST_TAG, "went_to_basement", true)
        spawnByTag("basement_slime") -- spawn a boss
    end
}

InHouseState.sceneExit = {
    luna_house_basement = function(quest)
        despawnByTag("basement_slime") -- despawn a boss
    end
}
 

entityStates is used to describe what function should be called on an entity when it appears on scene. In this case, when "luna" appears on the scene, she gets a new interaction function which will launch a specific cutscene.

sceneEnter/sceneExit are used to describe what happens when you enter/exit the scene in the specific quest state. In this case, it's used to spawn a boss in "luna_house_basement" until you kill it (and then the quest state changes and different script plays each time you enter the basement)

Here's what's good about this mechanism - entities and scenes don't know anything about quests - quest itself does the things when it's in corresponding state, so I can easily add more and more logic to them without touching scene/NPC script - it's all encapsulated into quest script!



Another thing I've added in an event logger. It allows me to subscribe to events of needed type and then inspect the data in each event. Very useful for debugging!



Here it is in action:
https://gfycat.com/sardonicmenacinggrackle

5
Doing more level editor/dev tools stuff... It's amazing how everything comes together now!


Here it is in action:
https://gfycat.com/presentleanbangeltiger

You can see how everything is dynamic and makes it easy for me to debug the game in action.

Also, I've finally solved the problem of entity lifetime that was bugging me for quite a long. Now there are three types of entities:
* AlwaysSpawn - spawned when level loads
* SpawnOnRoomEnter - spawned when you enter the room, despawned when you exit it. Used for enemies (it's easier to create an entity from scratch than to try to restore its state)
* DoNotSpawn - used for NPCs mainly - these are spawned by manager whichi takes a save and then looks where NPC is currently in this save. If the room is current one - the NPC is spawned. This allows me to have NPCs "travelling" between rooms and levels.

Also, now when I enter level editor, the level state is completely restored thanks to a clear separation. Every temporary object is removed, every SpawnOnRoomEnter/DoNotSpawn object is spawned, so that I can edit it, and then killed, when resuming the game. It works amazingly well. :)

6
If I add a break, other prefabs in the list won't be displayed.

7
Added filtering for prefab names. Now I can find prefabs and create them faster:


ImGui is so awesome - I only had to write this code to have this work:
    static ImGuiTextFilter filter;
    filter.Draw("Filter");
    if (ImGui::ListBoxHeader("Prefab")) {
        for (const auto& prefabName : prefabNames) {
            if (filter.PassFilter(prefabName.c_str())) {
                if (ImGui::Selectable(prefabName.c_str(), selectedPrefabName == prefabName)) {
                    selectedPrefabName = prefabName;
                    selected = true;
                }
            }
        }
        ImGui::ListBoxFooter();
    }

8

Spikes! I'm starting to work on some dungeon puzzles, yay :)

Here's their script. Pretty cool how easy they were to make with all the systems my engine has.

local EntityState = require("EntityState")

local coroutineManager = require 'Managers'.coroutineManager

local actions = require 'actions.wrappers'
local delay = actions.delay
local waitForAnimationEnd = actions.waitForAnimationEnd

local SPIKES_DELAY_TIME = 2.0

-- SpikesHiddenState
local SpikesHiddenState = EntityState:subclass("SpikesHiddenState")

function SpikesHiddenState:enter(e, args)
    e:setAnimation("hidden")
    e:setComponentEnabled("damage", false)

    coroutineManager:launch(
        function()
            delay(SPIKES_DELAY_TIME)
            e:changeState("SpikesRisingState")
        end
    )
end

-- SpikesRisingState
local SpikesRisingState = EntityState:subclass("SpikesRisingState")

function SpikesRisingState:enter(e)
    e:setComponentEnabled("damage", true)

    coroutineManager:launch(
        function()
            e:setAnimation("rising")
            waitForAnimationEnd(e)
            e:changeState("SpikesRisedState")
        end
    )
end

-- SpikesRisedState
local SpikesRisedState = EntityState:subclass("SpikesRisedState")

function SpikesRisedState:enter(e)
    e:setAnimation("rised")

    coroutineManager:launch(
        function()
            delay(SPIKES_DELAY_TIME)
            e:changeState("SpikesDescendingState")
        end
    )
end

-- SpikesDescendingState
local SpikesDescendingState = EntityState:subclass("SpikesDescendingState")

function SpikesDescendingState:enter(e)
    coroutineManager:launch(
        function()
            e:setAnimation("descending")
            waitForAnimationEnd(e)
            e:changeState("SpikesHiddenState")
        end
    )
end


return {
    SpikesHiddenState,
    SpikesRisingState,
    SpikesRisedState,
    SpikesDescendingState,
}
 

But with coroutine system I can also write something like this:

    coroutineManager:launch(
        function()
            while true do
                  e:setAnimation("hidden")
                  e:setComponentEnabled("damage", false)
                  delay(SPIKES_DELAY_TIME)

                  e:setComponentEnabled("damage", true)
                  e:setAnimation("rising")
                  waitForAnimation(e)

                  e:setAnimation("rised")
                  delay(SPIKES_DELAY_TIME)

                  e:setAnimation("descending")
                  waitForAnimation(e)
            end
        end
    )

... but for now I think I'll go with good old state based approach, which I think it more readable.

9
Graphics / Re: Using SFML with ImGui and the NewFrame issue
« on: September 16, 2019, 08:35:45 pm »
You're welcome. :)
Please add "[SOLVED]" to threads title.

10
Graphics / Re: Using SFML with ImGui and the NewFrame issue
« on: September 16, 2019, 05:55:01 pm »
void updateWindow(_GAME *pGame)
{
   
    while (window.isOpen()) {
        sf::Event event;
       
        while (window.pollEvent(event)) {
            // Process ImGui along with the SFML event
           
            ImGui::SFML::ProcessEvent(event);
           
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            // ImGui::EndFrame(); ????? <- shouldn't be called!
        }

        ImGui::SFML::Update(window, dt);

        ...
        // call LogonWindow here
 
        window.clear(sf::Color::Black);
 
        //window.clear(sf::Color::Black);
       
        ImGui::SFML::Render(window);
        window.display();
       
    }
 
    ImGui::SFML::Shutdown();
}
 

11
Graphics / Re: Using SFML with ImGui and the NewFrame issue
« on: September 16, 2019, 05:53:00 pm »
Where is LogonWindow called?
You need to call ImGui::SFML::Update before calling it.

12
Graphics / Re: Using SFML with ImGui and the NewFrame issue
« on: September 16, 2019, 11:23:02 am »
Here are my two guesses:
1) You use ImGui older than v1.68 (and recent ImGui-SFML require it)
2) Your game loop differs from what ImGui-SFML expect (some things changed in recent versions, as far as I remember). It's especially important to call ImGui::SFML::Update update function before calling any ImGui functions in the frame.

13
Thanks a lot, everyone. :)

Working on animated tiles recently, also did a lot about level editor and I'll publish a new dev log soon. :)
As you can see, both synced (waves) and unsynced (flowers) animations are supported.
TileAnimation system tracks all tiles which need to be animated, and when it's time to change a frame, it updates needed vertices in vertex array.


Level editor looks like this now:

* Added a toolbar. Previously tile editor had "three modes" - tile creation, entity selection, entity creation. Now I can easily add new tools!
* Empty tiles can't be selected for tile brush, also non-first animation frames for animated tiles can't be selected too
* Added tile layers.
* "Tile stamp tool" lets me combine tiles into "tile entities", e.g. house is a big stamp which can be applied to create new houses easily:

* Finally started to work on the second level - it was not easy to make sure that new level loads correctly and everything works well (there's a very elaborate scheme to find out which prefabs/entities are needed for the next level):


14
General discussions / Re: Review of simple Input Manager.
« on: September 11, 2019, 06:02:14 pm »
Some ideas:
  • If you use an enum class instead of strings for actions, your actions are type-safe (no mistypes possible)
Agreed, but this only works if the actions are defined statically. In my game I load them and input mapping from JSON, so it's not always a viable option.

  • Service locator is an option, but it's often misused as a lazy design pattern. Input is not something you need to access from anywhere in the application, and you should strive to decouple it from game logic. If you design class relations carefully, you can instantiate the Input class once, and delegate its actions (or results thereof) to other components, like the one which steers your player.
Agreed. I struggled with that, but managed to put all input logic into handleInput functions which take InputManager by reference. At times it's still useful to access InputManager globally, but one should generally avoid doing so. That being said, I think that Service Locator is less harmful than Singleton. :)[/list]

15
General discussions / Re: Review of simple Input Manager.
« on: September 11, 2019, 11:13:58 am »
The scheme looks okay. You can also report an error if action name that's passed to one of the functions is not correct, so that misspelled actions are easy to spot in code, e.g.

if(ActionManager::isActionPressed("someAction")) doSomeStuff(); // ok
if(ActionManager::isActionPressed("someActoin")) doSomeStuff(); // throws/logs error

Also, I'd strongly advice against using "static" classes which are really Singletons. I prefer Service Locator pattern a lot more.

Pages: [1] 2 3 ... 40
anything