Click here to Skip to main content
15,991,072 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm programming a 2D RPG game that uses an array of derived class instance pointers. For clarity I provide a code example in C++. I would like to sort the elements of the entities array based on the worldY value of each element.

main.cpp:

C++
/*
 * result:
 *    player
 *    object
 *    object
 *    npc
 *    npc
 *    2 npc y: 30
 *    1 npc y: 6
 *    1 object y: 20
 *    2 object y: 10
 *    player y: 0
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include "Entity.h"
#include "Npc.h"
#include "Player.h"
#include "Object.h"

int main()
{
    Player* player = new Player();

    std::vector<Entity*> objs;
    std::vector<Entity*> npcs;
    std::vector<Entity*> entities;

    Entity* tmp = new OBJ_o();
    objs.push_back(tmp);
    objs.at(0)->worldY = 20;
    objs.at(0)->ID = "1";

    tmp = new OBJ_o();
    objs.push_back(tmp);
    objs.at(1)->worldY = 10;
    objs.at(1)->ID = "2";

    tmp = new NPC();
    npcs.push_back(tmp);
    npcs.at(0)->worldY = 6;
    npcs.at(0)->ID = "1";

    tmp = new NPC();
    npcs.push_back(tmp);
    npcs.at(1)->worldY = 30;
    npcs.at(1)->ID = "2";

    //--------------- update -------------------
    player->update();

    for (auto iter_objs = objs.begin(); iter_objs != objs.end(); ++iter_objs)
    {
        (*iter_objs)->update();
    }

    for (auto iter_npcs = npcs.begin(); iter_npcs != npcs.end(); ++iter_npcs)
    {
        (*iter_npcs)->update();
    }

    //-------------- entities --------------------
    entities.push_back(player);

    for (int i = 0; i < objs.size(); i++)
    {
        if (!objs.at(i)->name.empty())
        {
            entities.push_back(objs.at(i));
        }
    }

    for (int i = 0; i < npcs.size(); i++)
    {
        if (!npcs.at(i)->name.empty())
        {
            entities.push_back(npcs.at(i));
        }
    }

    // sort entities
    std::sort(entities.begin(), entities.end());

    //---------------- draw entities ------------------
    for (auto iter = entities.begin(); iter != entities.end(); ++iter)
    {
        std::cout << (*iter)->ID << " ";
        (*iter)->draw();
    }

    return 0;
}
----------------------------------------------------------
Entity.h:

#pragma once
#include <iostream>

class Entity
{
public:
    int worldY = 0;
    std::string name;
    std::string ID;

public:
    virtual void update() { std::cout << "base" << std::endl; }
    virtual void draw() { std::cout << "base y: -\n"; }

    // Overloading < operator for std::sort in main: draw
    bool operator<(const Entity& obj) const
    {
        return worldY < obj.worldY;
    }
};
-----------------------------------------------
Npc.h:

#pragma once
#include "Entity.h"

class NPC : public Entity
{
public:
    NPC();
    void update() override;
    void draw() override;
};
-----------------------------------------------
Npc.cpp:

#include "Npc.h"
#include <iostream>

NPC::NPC() { name = "npc"; }
void NPC::update() { std::cout << name << std::endl; }
void NPC::draw() { std::cout << "npc y: " << worldY << std::endl; }
-----------------------------------------
Player.h:

#pragma once
#include "Entity.h"

class Player : public Entity
{
public:
    Player();
    void update() override;
    void draw() override;
};
-------------------------------------------
Player.cpp:

#include "Player.h"
#include <iostream>

Player::Player() { name = "player"; }
void Player::update() { std::cout << name << std::endl; }
void Player::draw() { std::cout << "player y: " << worldY << std::endl; }
-----------------------------------------------
Object.h:

#pragma once

#include "Entity.h"

class OBJ_o : public Entity
{
public:
    OBJ_o();
    void update() override;
    void draw() override;
};
-------------------------------------------------------------------
Object.cpp:

#include "Object.h"
#include <iostream>

OBJ_o::OBJ_o() { name = "object"; }
void OBJ_o::update() { std::cout << name << std::endl; }
void OBJ_o::draw() { std::cout << "object y: " << worldY << std::endl; }

(see result put as comment at the beginning of Main.cpp).
How should I do an increasing order of y (worldY) ?

What I have tried:

Using:
std::sort(entities.begin(), entities.end());

I don't get the desired result:

player
object
object
npc
npc
player y: 0
1 npc y: 6
2 object y: 10
1 object y: 20
2 npc y: 30
Posted

Found the solution:

C++
// sort entities
std::sort(entities.begin(), entities.end(), [](Entity *a, Entity *b)->bool { return a->worldY < b->worldY; });
 
Share this answer
 
Comments
Rick York 5-Jun-24 18:39pm    
You should mark your question as solved so it does not appear on the unsolved list.
how to mark my question as solved ?
 
Share this answer
 
Comments
Dave Kreskowiak 28-Jul-24 18:58pm    
You don't.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900