Class Reference - UbuntuJackson/UFO-Cells GitHub Wiki

UFO-Cells aims to wrap everything in either a class or a namespace according to C++ fashion. Here I'm gonna try to list all the classes and what they are all about.

Menu

#[! Does not exist]

class Menu : public ufo::Fundamental{
    int selected_index;
    int GetWrappedIndex(int _change_in_position){
        if(_change_in_position >= 1){
            selected_index--;
            if(selected_index) selected_index = buttons.size()-1;        
        }
        if(_change_in_position <= -1){
            selected_index++;
            if(selected_index > buttons.size()-1) selected_index = 0;        
        }     
    }
    void Update();
    void EngineUpdate(){
        Wrap(game->GetMouseWheel());
        Update();
    }
}

Container

template<typename T>
class Container{
public:
    Level* level;
    std::vector<T*> container;
    std::function<void(int)> remove_ptr = [&](int _id){
        for(int i = 0; i < container.size(); i++){
            if(container[i]->GetID() == _id){
                container.erase(container.begin() + i);
            }
        }
        std::cout << container.size() << std::endl;
    };
    Container(Level* _level) : level{_level}{}
    T* GetByID(int _id){
        for(auto p : container){
            if(p->GetID() == _id) return p;
        }
        return nullptr;
    }
    template<typename ...Args>
    T* New(Args ...args){
        //std::unique_ptr<T> instance = std::make_unique<T>(args ...);
        //container.push_back(instance.get());
        //level->actors.push_back(std::move(instance));
        T* act = new T(args ...);
        act->remove_pointer_from_container = remove_ptr;
        container.push_back(act);
        level->actors.push_back(act);
    }
};

Basically I added something I call a Container. It is a template class which allows additional accessability to the instances you add with it.

When you just push back a pointer to a new object in the game, it will be contained in actors under a common basetype. This is the vector that is iterated through when the level is updating. However if you intantiate Container like this

Container<Penguin> penguin{this};

you will now be able to add it by doing

penguin.New(position, ...)

And you can access a specific penguin by doing

Penguin specific_penguin = penguin.GetByID(id);

Fundamental

The Fundamental is similar to Node in godot, where you can "attach" it to another node, and it's Update function will run by default. A callback for Draw() will be added ASAP.

Fundamental has a method called Attach(), which takes a variable number of arguments, which can be a one or various types. It generates a pointer of type T and returns said pointer, T*. What it also does is that it adds it to an std::vector called nodes, and said vector is iterated through to run the Update function and UpdateCallbacks on each function.

UpdateCallbacks() is a recursive function and prioritises calling this.Update() first to achieve a structured order.

class Fundamental{
public:
    Fundamental* parent = nullptr;
    std::vector<Fundamental*> nodes;

    int depth = 0;
    std::string name = "";

    Fundamental(){}
    Fundamental(std::string _name) : name{_name}{}

    template<typename T, typename ... Args>
    T* Attach(Args ...args){
        T *node = new T(args ...);
        node->parent = this;
        nodes.push_back(node);
        return node;
    }

    void PrintTree(int _depth = 0){
        std::string indent = "";
        for(int _ = 0; _ < _depth; _++) indent += std::string("    ");
        Console::Out(std::string(indent) + " " + name);
        for(auto node : nodes){
            node->PrintTree(_depth+1);
        }
    }

    virtual void Update(){}
    void UpdateCallbacks(){
        Console::Out(name, "Update");
        Update();
        for(int i = 0; i < nodes.size(); i++){
            nodes[i]->UpdateCallbacks();
        }
    }
    ~Fundamental(){
        for(auto node : nodes){
            delete node;
        }
        Console::Out(name, "Destructor");
    }
};

#[Example]

#include <ufo/game.h>
#include <ufo/fundamental.h>
#include <ufo/console.h>
#include "derived_fundamental.h"
#include <memory>

class PGE_Derived : public Game{
public:

    std::unique_ptr<Fundamental> main = std::make_unique<Fundamental>("main");    

    Fundamental* fun1 = main->Attach<Fundamental>("fun1");
    Fundamental* fun2 = main->Attach<Fundamental>("fun2");
    Fundamental* fun3 = fun1->Attach<Fundamental>("fun3");
    DerivedFundamental* derived = fun1->Attach<DerivedFundamental>();

    PGE_Derived() : Game(){
        fun2->Attach<DerivedFundamental>();
    }

    bool OnUserCreate(){
        main->PrintTree();
        return true;
    }

    bool OnUserUpdate(float fElapsedTime){
        main->UpdateCallbacks();
        return true;
    }
};

int main(){
    PGE_Derived game;
	if (game.Construct(400, 200, 1, 1, false, true, true))
		game.Start();

	return 0;
}

#[Warning! Please don't grab values of this during Attach()]

Here's a quote from Fluff who helped me make this: Quote[ tbh the control flow isn't too complex here. Whenever you call attach, the constructor for the attached class runs.

Now if that attached class calls attach itself, then that will run.

When you were setting depth inside attach, you were setting in on the new node after its constructor runs. This means that the nested attach finishes running first, so it gets the wrong depth "]

Camera

Camera has currently 3 major viewmodes. -Platformer -MouseAndKeyBoard -Static

...

Ray2

Ray2 is a ray class used to do 2d raycasting calculations.

namespace LinearAlgebra

The LinearAlgebra currently mostly holds the underlying utilities for raycasting.

CollisionData RayVsRay2d(Ray& _v, Ray _w);

CollisionData

CollisionData (soon to be renamed RayCastingHitData) is a struct containing the following data:

struct{
    float collision_time;            //Basically a value representing where on the ray is intersecting relative to it's length
    float collision_time_other;      
    bool hit_within_bounds;          //Is true if both collision times are between or equal to 0 and 1.
    olc::vf2d intersection_point;    //Where the rays intersect
}

AssetManager

AssetManager is a singleton class which contains assets. It's contents you can access via the Get() method, which will provide you with a static instance of AssetManager.

class AssetManager{
public:
    AssetManager() = default;
    std::map<std::string, std::unique_ptr<olc::Sprite>> sprites;
    std::map<std::string,std::unique_ptr<olc::Decal>> decals;

    std::map<std::string, std::unique_ptr<olc::Sprite>>& GetSprites();
    void LoadSprite(const std::string& _path, const std::string& _name);
    olc::Sprite* GetSprite(std::string _name);
    std::map<std::string, std::unique_ptr<olc::Decal>>& GetDecals();
    void LoadDecal(const std::string& _path, const std::string& _name); //wouldn't this load both a sprite and a decal? And should the load functions return something?
    olc::Decal* GetDecal(std::string _name);
    void RemoveAsset(std::string _name);

    static AssetManager& Get(){static AssetManager self; return self;} //this practically makes AssetManager global.

};

AssetManager features the following functions to use it:

GetSprites() gives you the std::map containing the sprites currently loaded.

std::map<std::string, std::unique_ptr<olc::Sprite>>& GetSprites();

LoadSprite loads an olc::Sprite from specified path, but does not load a Decal.

void LoadSprite(const std::string& _path, const std::string& _name);

GetSprite returns a pointer to the olc::Sprite which you can pass into a drawing call.

olc::Sprite* GetSprite(std::string _name);

GetDecals() gives you the std::map containing the decals currently loaded.

std::map<std::string, std::unique_ptr<olc::Decal>>& GetDecals();

LoadDecal loads an olc::Decal and an olc::Sprite.

void LoadDecal(const std::string& _path, const std::string& _name);

GetDecal returns a pointer to the olc::Decal which you can pass into a drawing call.

olc::Decal* GetDecal(std::string _name);

RemoveAsset attempts to remove an olc::Decal and an olc::Sprite depending on what you have loaded. If you have an olc::Sprite but not a decal, console will inform you that there was only an olc::Sprite to remove.

void RemoveAsset(std::string _name);

Example:

bool OnUserCreate(){
    AssetManager::Get().LoadSprite("../res/test.png", "test");
    AssetManager::Get().LoadSprite("../res/test.png", "test");
    AssetManager::Get().LoadDecal("../res/test.png", "test2");
    AssetManager::Get().LoadDecal("../res/00.png", "00");
    AssetManager::Get().LoadDecal("../res/00.png", "00");
    AssetManager::Get().RemoveAsset("00");
    AssetManager::Get().RemoveAsset("test");
    AssetManager::Get().RemoveAsset("unicorn");
    AssetManager::Get().RemoveAsset("test2");
    return true;
}
⚠️ **GitHub.com Fallback** ⚠️