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.


Topics - noct

Pages: [1]
1
General / [SFML 2.0]Problem with A* algorithm
« on: August 17, 2016, 10:19:31 am »
Hello there. Im working on an implementation of A* algorithm for my SFML game-project. I've recently got some problems with passing 2d arrays to a function (I think).

I got segmentation fault error when receving array[][sizex] (I have an idea why) and many other errors with array[sizey][sizex].
Lets take a look on the code:

aStar.hpp:
//(...)
class Node
{
public:
Node();
sf::Vector2i position;
sf::Vector2i parentPosition;

int gCost;
int hCost;
int fCost;

bool operator == (const Node & nod);


};

class aStar
{
public:

aStar();
int manhattan(sf::Vector2i start, sf::Vector2i end);

Node StartNode;
Node EndNode;

  vector<Node> OpenSet;
  vector<Node> ClosedSet;
  vector<Node> NeighborSet;
  vector<Node> PathSet;

void findPath(sf::Vector2i start, sf::Vector2i end, int tmap[10][10], int collisionMap[10][10]);
void buildPath();
int minfCost(vector<Node> vec);
void findNeighbors(Node CurrentNode, int tmap[10][10], int collisionMap[10][10]);

};
//(...)

aStar.cpp:
//(...)
aStar::aStar()
{
StartNode.parentPosition = sf::Vector2i(0,0);

}

Node::Node()
{
gCost = 0;
hCost = 0;
}


//int Node::fCost() { return gCost+hCost; }

void aStar::findNeighbors(Node CurrentNode, int tmap[10][10], int collisionMap[10][10])
{

   for (int y=-1; y<=1; y++)
{
    for (int x=-1; x<=1; x++)
    {
        int checkX=CurrentNode.position.x+x, checkY=CurrentNode.position.y+y;

        if(x==0 && y==0) {continue; }

        if(checkX < 0 || checkX > 10 || checkY < 0 || checkY > 10) {continue; }
        if(collisionMap[checkY][checkX] == 0)
        {
            Node newNode;
            newNode.position = sf::Vector2i(checkX, checkY);
            newNode.parentPosition = CurrentNode.position;

            if((newNode.position.x==CurrentNode.position.x && newNode.position.y!=CurrentNode.position.y) ||
               (newNode.position.y==CurrentNode.position.y && newNode.position.x!=CurrentNode.position.x))
                    {
                     newNode.gCost = 10 + CurrentNode.gCost;
                    }
            else
                    {
                     newNode.gCost = 14 + CurrentNode.gCost;
                    }

           // OpenSet.push_back(newNode);

           NeighborSet.push_back(newNode);
            tmap[checkY][checkX] = 1;
        }


    }


}
}

bool Node::operator == (const Node & nod)
{ return (this->position == nod.position); }

int aStar::manhattan(sf::Vector2i start, sf::Vector2i end)
{
    int dist;
    dist = abs(start.x - end.x) + abs(start.y - end.y);
    return (dist*10);
}


int aStar::minfCost(vector<Node> vec)
{ int min = vec[0].fCost;
 unsigned int i=0;
    for(; i<vec.size(); i++)
    {
        if(vec[i].fCost < min) {min =vec[i].fCost; }
    }
    return i;
}


void aStar::findPath(sf::Vector2i start, sf::Vector2i end, int tmap[10][10], int collisionMap[10][10])
{

StartNode.position = start;
StartNode.gCost = 0;
StartNode.fCost = StartNode.gCost + manhattan(start, end);
EndNode.position = end;

Node CurrentNode;

OpenSet.push_back(StartNode);

while (OpenSet.size() > 0)
{
    CurrentNode = OpenSet[minfCost(OpenSet)];
    if(CurrentNode == EndNode) { buildPath();   return ; }

OpenSet.erase( remove(OpenSet.begin(), OpenSet.end(), CurrentNode), OpenSet.end() );
ClosedSet.push_back(CurrentNode);

findNeighbors(CurrentNode, tmap, collisionMap);
for ( unsigned int i=0; i<NeighborSet.size(); i++)
{
    if(find(ClosedSet.begin(), ClosedSet.end(), NeighborSet[i]) != ClosedSet.end() )
    {
        continue;
    }
      int tent = CurrentNode.gCost + manhattan(CurrentNode.position, NeighborSet[i].position);

    if(! (find(OpenSet.begin(), OpenSet.end(), NeighborSet[i]) != OpenSet.end() ))
    {// not found
      OpenSet.push_back(NeighborSet[i]);
    }
    else if (tent >= NeighborSet[i].gCost)
    {
        continue;
    }

    NeighborSet[i].fCost = NeighborSet[i].gCost = manhattan(NeighborSet[i].position, EndNode.position);
}

}

}

void aStar::buildPath()
{
    PathSet.push_back(EndNode);
    Node newNode = EndNode;
    while (newNode.parentPosition != sf::Vector2i(-1,-1)) // only possible if newNode == StartNode
    {
        newNode.position = newNode.parentPosition;
        PathSet.push_back(newNode);
    }


}
//(...)
I know it's a big piece of code, sorry for that, however I am not able to specify what's going wrong here.
I know this code Isn't the highest quality, I want to optimise it after I'll have it working ;)
I use std namespace by default.

I got an error wherever I use tmap[10][10] (ctrl+f it)

tmap is a 10x10 int array filled with 0,1,2,3 ("block" numbers)
collisionMap is a 10x10 int array filled with 0 if a "block" is walkable, 1 if isn't and 2 if a "block" is start/end of desired path.

If you think the only option is to rewrite the entire thing, just tell me. I'm looking for at least some tips if fixing this is not possible/worth.



Debugger output: http://pastebin.com/uRFxyrXa

I've been using those pseudocodes/tutorials: (+stack ofc)
http://www.growingwiththeweb.com/2012/06/a-pathfinding-algorithm.html
https://en.wikipedia.org/wiki/A*_search_algorithm
http://www.policyalmanac.org/games/aStarTutorial.htm

2
Graphics / Proper management with class objects
« on: June 05, 2015, 10:41:06 pm »
Hello there,
I've got a little problem with vectors containing class objects.

I want to create two std::vectors containing:
1. objects of class:
class Mobs_normal
{
public:

int id;
string name;
int lvl;
int dmg_min;
int dmg_max;
int hp;
int critChance;
};

Which would be a kind of mob templates.

2. objects of class:
class Entity
{
public:
vector<Mobs_normal> mobsNormal;

void load()
{
// data base
fstream file_mobs_normal;
file_mobs_normal.open("entity/mobs_normal.txt", ios::in );

if (!file_mobs_normal.good() )  {error("mobs_normal.txt"); } // 404

// mobs were an int array, but i want them to be vectors
for (int i=0; i < 11; i++ )
    {
 
       mobsNormal.name.push_back() // ?
       file_mobs_normal >> mobsStack[i].name;
       file_mobs_normal >> mobsStack[i].lvl;
       file_mobs_normal >> mobsStack[i].dmg_min;
       file_mobs_normal >> mobsStack[i].dmg_max;
       file_mobs_normal >> mobsStack[i].hp;
       file_mobs_normal >> mobsStack[i].critChance;
    }
}

void drawMobs(sf::RenderWindow & okno, Textures & cTex)
{
  // temp drawing
  for (int i=0; i < cTex.sprEntity.size(); i++)
  {
   cTex.sprEntity[ i ].setPosition((1+i)*50, 50);
   okno.draw(cTex.sprEntity[ i ] );
  }
}

void enableAiMovement(sf::RenderWindow & okno, Textures & cTex)
{
// moving objects on map and switches for "do something" methods
}

};

Which would be templates handling ai of objects drawn at the time on your screen, containing their movement and other actions on map.

I wonder if it's the best solution for this problem.
How should I create a vector containing all information of objects on map (to interact with Player)?
One for all those stats (id, name, lvl, hp) or one for every single stat? I would connect them with "id" iterator.
I want to achieve a quick access to those stats and sprite drawing methods by their int id;

Attachment: database with stats

3
Graphics / Loading sprites to vector.
« on: May 25, 2015, 10:10:04 pm »
Hello.
Lately I've been experiencing some problems with my code. To the thing:

class Textures
{
public:
fstream txtWeapon1h;
vector<string> namWeapon1h;
vector<sf::Texture> texWeapon1h;
vector<sf::Sprite> sprWeapon1h;

void loadItemTex()
{
txtWeapon1h.open("gfx/weapon/list.txt");
while( !txtWeapon1h.eof() )
{
string new_name;
getline( txtWeapon1h, new_name );
namWeapon1h.push_back(new_name);
}
txtWeapon1h.close();

for (int i=0; i<namWeapon1h.size(); i++)
{
sf::Texture new_tex;
new_tex.loadFromFile(namWeapon1h[i])
texWeapon1h.push_back(new_tex);
}

for (int i=0; i<namWeapon1h.size(); i++)
{
sf::Sprite new_block;
new_block.setTexture(texWeapon1h[i] );
sprWeapon1h.push_back(new_block);
}

}
//(...)
};
That's how i load my tex/spr in a Texture class. Now, in the same class I've got this drawing method:
void drawTile(sf::RenderWindow & okno, int tileType, int tileID, float posX, float posY)
{
    if(tileType == 0 )
     {
         sprCobble_walk[tileID].setPosition(posX, posY);
         okno.draw(sprCobble_walk[tileID]);
     }

else if(tileType == 1 )
     {

        sprWeapon1h[tileID].setPosition(posX, posY);
        okno.draw(sprWeapon1h[tileID] );
     }
else { error("unkown tile used" ); }
}
 
The problem is, that outside of this class,
sprWeapon1h.size()
is returning 0. Also, the app crashes when I try to use these textures (and method). I think the problem lays in scopes. However, maybe you have got any ideas to tell me how to load sprites into a vector and then to use them anywhere else?
By the way, in my main() I can freely draw those sprites, by simple
okno.draw(cTex.sprWeapon1h[1]);
I just can't get, how to make a drawing method using vectors.

4
Window / [SFML 2.0]Problem with repeating buttons and events.
« on: August 29, 2014, 02:48:26 am »
Hello. Well, it's more like a few questions, not only a problem. I think this is all connected with each-other, so I've posted only one topic.

This is in the main loop of application (60 fps limit)
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::LAlt && paused == 0)
{
  cout << "game paused" << endl;
  paused = 1;
}

I'm using bool paused like that:
if (!paused)
{
  okno.display();
}
1. Why Event::KeyPressed and Event::KeyReleased are not working with keys other than similar to Alt, Home, End etc?
I've checked it by using:
if (event.type == sf::Event::KeyPressed)
{
  cout << event.key.code << endl;
}
It returns key codes, but for letters/digits it does not return anything.

2. I'm trying to pause my game, how, correctly, should I do this? By stopping Window.display()?

3. How to resume after pausing?
I was trying to use:
if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::LAlt) && paused == 1)
{
cout << "game started" << endl;
paused = 0;
}
And here comes another problem - game was starting and stopping few times, till I released LAlt. So, how can I disable "key repetition"?
I guess Window.setKeyRepeatEnabled(false) works only with events (which imho aren't working correctly here). Additionally I'd have to lock this only when needed (I can't have this locked ex. while im using W to move up).

I hope you, guys, will understand what do I think about, even with my B2 ;)

Pages: [1]
anything