SFML community forums

Help => Graphics => Topic started by: Pikmeir on July 09, 2012, 03:14:04 am

Title: Help with RPG inventory system (solved) Thanks!
Post by: Pikmeir on July 09, 2012, 03:14:04 am
I'm new to SFML (2.0), C++, and new to programming, so please be nice on my code.. I apologize it's so long, but this is the bare minimum I think I can post to explain my problem since I'm stumped. (If you want the whole code, I have no problem giving it out to anyone). With that said...

I'm trying to make an RPG game (here are some screenshots: http://imgur.com/a/vxd9B (http://imgur.com/a/vxd9B) - pardon the Paint graphics, but I suck at drawing and I'm fine with that), and up until now everything's been going fine. I stressed for about a week about how to make an inventory system, and came up with a solution that semi-works, but is giving me issues.

I declared some global variables:
sf::Texture textureArray[95];  // textures for sprites for slots 1-96
sf::Sprite spriteArray[95];      // sprites for spots 1-96
sf::FloatRect invRect[95];      // floatRect for interacting with spots 1-96

In main(), before the game's while loop, I create/load all my textures, and then I do this from 0-95:
spriteArray[0].setPosition(INV_1_X, INV_1_Y); // INV_1_X and Y are pre-defined coords for where to draw the sprites
invRect[0] = sf::FloatRect(INV_1_X, INV_1_Y, INV_SIZE_X, INV_SIZE_Y); // INV_SIZE_X and Y are pre-defined sizes for the boxes

I then set all of the textureArray[] assets from 0-95 to empty by doing this:
for (int i = 0; i < 95; i++) { textureArray[i] = invEmpty; }

Then I give the player some test items:
addItem(invHPot); // I added this line several times with various items

In the game's while loop, if the inventory window is open I do this:
for (int i = 0; i < 96; i++)
{
        if (cursor_box.intersects(invRect[i])) // cursor_box is the floatRect for the cursor
        {
                selectInv = i;
                std::cout << "SELECTED INV SLOT # " << i + 1 << "." << std::endl; // for testing
        }
}

if (cursor_box.intersects(buttonDispose_box)) // if they click DISPOSE after selecting an item
{
        delItem(selectInv);
        std::cout<<"DISPOSE THIS ITEM"<<std::endl; // for testing
        selectInv = -1; // reset selectInv
}
 

And temporarily, if the player clicks the MOVE button below DISPOSE, I made it run addItem(invHPot) just to test if the system's working. (this function is below)

Here are the two functions for adding and deleting items from the inventory:
void delItem(int selectInv) // selectInv is a number 0-95 and is decided from the functions above (when the player clicks in a space)
{
        sf::Texture invEmpty;
        invEmpty.loadFromFile("res/images/inv/invEmpty.png");
        textureArray[selectInv] = invEmpty; // a blank 5x5 png texture
}

void addItem(sf::Texture textureName) // Inv spot 0-95
{
        int i;
        for (i = 0; i < 95; i++)
        {
                if (textureArray[i].getSize().x == 5) // invEmpty is 5x5 pixels, others are 43x43
                {
                        textureArray[i] = textureName;
                        break;
                }
        }
}

Then toward the end of main(), before showing the screen I do the following:
// Link/Set sprites to appropriate textures
for (int i = 0; i < 95; i++)
{ spriteArray[i].setTexture(textureArray[i]); // now the spriteArray and textureArray elements should be linked}

// Display inventory items
for (int i = 0; i < 95; i++)
{ Screen.draw(spriteArray[i]); // draw all of the sprites }

------------------------------------

Phew, that was long. So what the problem is, is sometimes the program crashes randomly when I open the inventory screen. When it doesn't crash, this is what happens:

The items display fine (I usually try addItem with at least 5-30 items, and they display fine). The selecting and deleting items works fine. If I delete an item, it goes away properly. But when I try to add an item while playing, it will only replace one of the empty spots. It won't let me just add items, unless I've "deleted" one already using delItem (the DISPOSE button). I'm not sure how to fix this. I've tried re-arranging things, but each time I get the same problem (when I was testing it with only 12 elements, before changing it to the full 96, it didn't crash, but I had the same problem).

Please tell me I'm stupid "because there's such an easy solution." I hope someone here can help me out.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Tresky on July 09, 2012, 06:00:03 am
Hmmmm.... I don't know what the problem is that you are having, but I do know that you need to put a catcher in your delItem function. The selectInv variable gets set to -1 at some point in there and if no item is selected, but the user hits 'DISPOSE' the program will crash from what I see. -1 is an invalid position in the array.
if (cursor_box.intersects(buttonDispose_box)) // if they click DISPOSE after selecting an item
{
        delItem(selectInv);
        std::cout<<"DISPOSE THIS ITEM"<<std::endl; // for testing
        selectInv = -1; // reset selectInv
}

Perhaps like so...
void delItem(int selectInv) // selectInv is a number 0-95 and is decided from the functions above (when the player clicks in a space)
{
    if (selectInv >= 0) {
        sf::Texture invEmpty;
        invEmpty.loadFromFile("res/images/inv/invEmpty.png");
        textureArray[selectInv] = invEmpty; // a blank 5x5 png texture
    }
}

On another note.
Could you send me the full code? I'll see if I can figure out what could be causing that.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 09, 2012, 06:53:14 am
Thanks for letting me know about adding a catcher to delItem().
As for the -1, I put it there (mistakenly) because I didn't want the player to accidentally delete an item without clicking on it, just by clicking the DISPOSE button, unless he/she had just clicked on a space. Maybe it's unnecessary though.

Here's the entire project so far, including the assets:
http://www.mediafire.com/?5y5zid9wbg6k9d3 (http://www.mediafire.com/?5y5zid9wbg6k9d3) 4.2 MB

And here's just main.cpp by itself (I also attached it to this post too if that's easier):
http://www.mediafire.com/?359uq1ianr8adbw (http://www.mediafire.com/?359uq1ianr8adbw) 44 KB

I tried to make the code easy to read by combining repetitive lines into one, but it's still around 800 lines so far. Thanks so much for your help.

[attachment deleted by admin]
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Tresky on July 09, 2012, 06:51:52 pm
Oh Lord, I don't know, man. Have you considered organizing your code better? i.e. classes, multiple files, etc.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: game_maker on July 09, 2012, 09:49:16 pm
Are the images/sprites the same? If they are, then use one image and one sprite only, because its a memory waste.
Move the sprite and draw it in the positions that you want.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Nexus on July 09, 2012, 10:13:51 pm
Pikmeir, please read this thread (http://en.sfml-dev.org/forums/index.php?topic=5559.0). No one will download your whole project and search for errors, so please come up with a reduced example. And if you have just begun to learn C++, I'd suggest to wait some time before you jump directly into game programming, because SFML requires basic C++ knowledge. Or read at least a good C++ book in parallel.

game_maker, multiple sprites are not a problem, sf::Sprite is a lightweight entity. But multiple identical textures should be avoided.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: game_maker on July 09, 2012, 10:31:23 pm
But it's best to use only one, right?  :D
It does not matter on a small project...

Goodbye!
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 09, 2012, 10:32:39 pm
I'll go through my project and try to create a simple, runnable short version just with the problem that I'm having and post it here.

As for my project, I don't expect anyone to read through the entire thing and try to debug it, it's just there if you're curious. Since most people are overly protective of their source code, I decided I'd just throw mine out there since I'm new anyway :)
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 09, 2012, 11:39:28 pm
I made a minimal version of my program and attached all the necessary files as well here.
I also noticed that this program doesn't run at all unless I made the arrays [3] instead of just [2]. I'm not sure why this is, since nothing is held in the last spot. However this program still has the same problem I got before.

Here's just main.cpp by itself:
#include <SFML/Graphics.hpp>

sf::Texture textureArray[3]; // textures for sprites for slots 1-3
sf::Sprite spriteArray[3]; // sprites for spots 1-3
sf::FloatRect invRect[3]; // floatRect for selecting spots 1-3
int selectInv = -1; // current item spot selected (1-3), default is -1
sf::Texture invEmpty;   // EMPTY
sf::Texture invHPot;    // Health potion

void setAllEmpty() // Set all inventory slots to empty
{
        sf::Texture invEmpty;
        invEmpty.loadFromFile("invEmpty.png");
        for (int i = 0; i <= 2; i++)
        {
                textureArray[i] = invEmpty;
        }
}

void delItem(int selectInv)
{
        sf::Texture invEmpty;
        invEmpty.loadFromFile("invEmpty.png");
        if (selectInv >= 0)
        {
                textureArray[selectInv] = invEmpty;
        }
}

void addItem(sf::Texture textureName)
{
        for (int i = 0; i <= 2; i++)
        {
                if (textureArray[i].getSize().x == 5)
                {
                        textureArray[i] = textureName;
                        break;
                }
        }
}

int main ()
{
        sf::RenderWindow Screen (sf::VideoMode (800, 600, 32), "Game", sf::Style::Close);

        sf::Texture invEmpty; // a 5 by 5 blank png
                if (!invEmpty.loadFromFile("invEmpty.png")) return EXIT_FAILURE;
        sf::Texture invHPot; // a 43 by 43 png
                if (!invHPot.loadFromFile("invHPot.png")) return EXIT_FAILURE;

        sf::Texture buttonDispose; // DISPOSE button
                if (!buttonDispose.loadFromFile("buttonDispose.png")) return EXIT_FAILURE;
        sf::Sprite buttonDisposeSpr;
                buttonDisposeSpr.setTexture(buttonDispose);
                buttonDisposeSpr.setPosition(400, 400);
        sf::FloatRect buttonDispose_box = sf::FloatRect(400, 400, 50, 50);

        sf::Texture buttonAddItem; // ADD ITEM button
                if (!buttonAddItem.loadFromFile("buttonAddItem.png")) return EXIT_FAILURE;
        sf::Sprite buttonAddItemSpr;
                buttonAddItemSpr.setTexture(buttonAddItem);
                buttonAddItemSpr.setPosition(500, 400);
        sf::FloatRect buttonAddItem_box = sf::FloatRect(500, 400, 50, 50);
       
        // Set position of each sprite
        spriteArray[0].setPosition(100, 100);
        spriteArray[1].setPosition(200, 100);
        spriteArray[2].setPosition(300, 100);

        // Create FloatRect boxes for each inventory space
        invRect[0] = sf::FloatRect(100, 100, 43, 43);
        invRect[1] = sf::FloatRect(200, 100, 43, 43);
        invRect[2] = sf::FloatRect(300, 100, 43, 43);
       
        setAllEmpty(); // clear inventory

        addItem(invHPot); // give test item

        while (Screen.isOpen())
        {
                Screen.clear();

                // Get mouse cursor info
                float mouseX = sf::Mouse::getPosition(Screen).x;
                float mouseY = sf::Mouse::getPosition(Screen).y;
                sf::FloatRect cursor_box = sf::FloatRect(mouseX, mouseY, 1, 1);

                sf::Event Event;
                while (Screen.pollEvent (Event))
                {
                        if (Event.type == sf::Event::Closed || Event.key.code == sf::Keyboard::Escape)
                                Screen.close();

                        if (Event.type == sf::Event::MouseButtonPressed)
                        {
                                for (int i = 0; i <= 2; i++)
                                {
                                        if (cursor_box.intersects(invRect[i]))
                                                { selectInv = i; }
                                }
       
                                if (cursor_box.intersects(buttonDispose_box))
                                {
                                        delItem(selectInv);
                                        selectInv = -1;
                                }
                                if (cursor_box.intersects(buttonAddItem_box))
                                { addItem(invHPot); }
                        }

                }

                for (int i = 0; i <= 2; i++) // Set spriteArray to textureArray
                { spriteArray[i].setTexture(textureArray[i]); }

                Screen.draw(buttonAddItemSpr);
                Screen.draw(buttonDisposeSpr);

                for (int i = 0; i <= 2; i++)
                { Screen.draw(spriteArray[i]); }

                Screen.display();

        } // (END) GAME WHILE LOOP

        return 0;
}
 

[attachment deleted by admin]
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: eXpl0it3r on July 10, 2012, 12:37:25 am
As Nexus stated try to read more on C++... ;)

Use std::vector instead of arrays, since they are dynamic and way safer to use than a plain array.

I also noticed that this program doesn't run at all unless I made the arrays [3] instead of just [2]. I'm not sure why this is, since nothing is held in the last spot.
This is because all your loops go from 0 to 2, which are three indiezes, but if your array only holds 2 elements you'd run out of bound and since it's an array it's quite dangerous.

Your initial problem lies with the selection. You're converting for some reason your mouse position to a rectangle and then you're trying to test if the inventory rectangle intersects with the 1x1 mouse rectangle. There's an easy function Rect<T>::contains(point) (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Rect.php#a24163acdb9b2987c0ea55c201e270d41) that checks wether a point is within a rectangle, which is exactly what you need, because the mouse is just a point and not a rectangle.
Also what you're doing with selectInv can crash your program, because whenever you delete an item, you set it to -1 and later it can happen that you don't select an item and thus your variable will still be -1. Trying to access an array at position -1 is not a good idea!  :-\

So conclusion: Read some more about C++ and think of a better structure and code design. :)
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 10, 2012, 01:36:31 am
I'll look up std::vector and try to do it using those instead, and if I have any problems I'll post here again.
I also went ahead and fixed the other issues you'd pointed out, but for the time being I left the intersect function for the mouse as is, since it works fine in the rest of the game; I'll change it after I fix the inventory system.
Thanks~
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 10, 2012, 03:12:30 am
I took your advice and fixed the following:

1) Switched all of the arrays to vectors.
2) Changed the mouse to use contains() instead, only checking if the mouse pixel is inside the box.
3) Decided to use 1-96 for everything, instead of 0-95.
4) Made selectInv default at 0 instead of -1, so the program doesn't crash anymore.

However, I still have the exact same problem as before involving addItem():
Quote
If I delete an item, it goes away properly. But when I try to add an item while playing, it will only replace one of the empty spots. It won't let me just add items, unless I've "deleted" one already using delItem (the DISPOSE button).

Any ideas? I've attached the full (simplified version) project below this message.

And I'll attach it just as code right here too:
#include <SFML/Graphics.hpp>
#include <vector>

std::vector<sf::Texture> textureArray (4); // textures for sprites for slots 1-3
std::vector<sf::Sprite> spriteArray (4); // sprites for spots 1-3
std::vector<sf::IntRect> invRect (4); // Rects for selecting spots 1-3
int selectInv = 1; // current item spot selected (1-3), default is 1
sf::Texture invEmpty;   // EMPTY
sf::Texture invHPot;    // Health potion

void setAllEmpty() // Set all inventory slots to empty
{
        sf::Texture invEmpty;
        invEmpty.loadFromFile("invEmpty.png");
        for (int i = 1; i <= 3; i++)
        {
                textureArray.at(i) = invEmpty;
        }
}

void delItem(int selectInv)
{
        sf::Texture invEmpty;
        invEmpty.loadFromFile("invEmpty.png");
        textureArray.at(selectInv) = invEmpty;
}

void addItem(sf::Texture textureName)
{
        for (int i = 1; i <= 3; i++)
        {
                if (textureArray.at(i).getSize().x == 5)
                {
                        textureArray.at(i) = textureName;
                        break;
                }
        }
}

int main ()
{
        sf::RenderWindow Screen (sf::VideoMode (800, 600, 32), "Game", sf::Style::Close);

        sf::Texture invEmpty; // a 5 by 5 blank png
                if (!invEmpty.loadFromFile("invEmpty.png")) return EXIT_FAILURE;
        sf::Texture invHPot; // a 43 by 43 png
                if (!invHPot.loadFromFile("invHPot.png")) return EXIT_FAILURE;

        sf::Texture buttonDispose; // DISPOSE button
                if (!buttonDispose.loadFromFile("buttonDispose.png")) return EXIT_FAILURE;
        sf::Sprite buttonDisposeSpr;
                buttonDisposeSpr.setTexture(buttonDispose);
                buttonDisposeSpr.setPosition(400, 400);
        sf::IntRect buttonDispose_box = sf::IntRect(400, 400, 50, 50);

        sf::Texture buttonAddItem; // ADD ITEM button
                if (!buttonAddItem.loadFromFile("buttonAddItem.png")) return EXIT_FAILURE;
        sf::Sprite buttonAddItemSpr;
                buttonAddItemSpr.setTexture(buttonAddItem);
                buttonAddItemSpr.setPosition(500, 400);
        sf::IntRect buttonAddItem_box = sf::IntRect(500, 400, 50, 50);
       
        // Set position of each sprite
        spriteArray.at(1).setPosition(100, 100);
        spriteArray.at(2).setPosition(200, 100);
        spriteArray.at(3).setPosition(300, 100);

        // Create IntRect boxes for each inventory space
        invRect.at(1) = sf::IntRect(100, 100, 43, 43);
        invRect.at(2) = sf::IntRect(200, 100, 43, 43);
        invRect.at(3) = sf::IntRect(300, 100, 43, 43);
       
        setAllEmpty(); // clear inventory

        addItem(invHPot); // give test item

        while (Screen.isOpen())
        {
                Screen.clear();

                // Get mouse cursor info
                float mouseX = sf::Mouse::getPosition(Screen).x;
                float mouseY = sf::Mouse::getPosition(Screen).y;

                sf::Event Event;
                while (Screen.pollEvent (Event))
                {
                        if (Event.type == sf::Event::Closed || Event.key.code == sf::Keyboard::Escape)
                                Screen.close();

                        if (Event.type == sf::Event::MouseButtonPressed)
                        {
                                for (int i = 1; i <= 3; i++)
                                {
                                        if (invRect.at(i).contains(mouseX, mouseY))
                                                { selectInv = i; }
                                }
       
                                if (buttonDispose_box.contains(mouseX, mouseY))
                                { delItem(selectInv); }

                                if (buttonAddItem_box.contains(mouseX, mouseY))
                                { addItem(invHPot); }
                        }

                }

                Screen.draw(buttonAddItemSpr);
                Screen.draw(buttonDisposeSpr);

                for (int i = 1; i <= 3; i++) // Set spriteArray to textureArray
                { spriteArray.at(i).setTexture(textureArray.at(i)); }

                for (int i = 1; i <= 3; i++)
                { Screen.draw(spriteArray.at(i)); }

                Screen.display();

        } // (END) GAME WHILE LOOP

        return 0;
}
 

Thanks so much for any help you can give me. I keep trying to fix this, but something's still not working right :(

[attachment deleted by admin]
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: eXpl0it3r on July 11, 2012, 06:11:43 pm
There are still quite a few mistakes...
I've tried to get this thing to work on my end but I only get the two purple 'buttons' and nothing happens when I click on either of them, but maybe it has to do with my changes, which may have removed some unhealthy side effects in your code.

First off I had to remove all the global varaibles, because the application just crashed because SFML is trying to acquire a mutex on a global resource which somehow fails.
This means: DON'T use global variables (unless you really know what you're doing!), better head into using classes & OOP. ;)

Second your random application closing happen in the following line:
if (Event.type == sf::Event::Closed || Event.key.code == sf::Keyboard::Escape)
This translates to: If the even 'Closed' has happend OR by some random undefined behaviour Event.key.code is suddendly equal to sf::Keybard::Escape. You always have to check first if that event you want to use the parameters of, really happend.

Third you're redefining invEmpty and invHPot all over the place. E.g. here
        sf::Texture invEmpty; // a 5 by 5 blank png
                if (!invEmpty.loadFromFile("invEmpty.png")) return EXIT_FAILURE;
        sf::Texture invHPot; // a 43 by 43 png
                if (!invHPot.loadFromFile("invHPot.png")) return EXIT_FAILURE;
or here:
        sf::Texture invEmpty;
        invEmpty.loadFromFile("invEmpty.png");
If you've decided to use global variables why don't you just use them?

Forth, for your replace problem I think it's the addItem code itself. I'm not sure what you're trying to heck with if (textureArray.at(i).getSize().x == 5), but that's were your problem probably is. Because if every x size is equal to 5, every single texture will get replaced by the given texture (invHPot).

I bet I'd find some more points to add here, but I think it's obvious that the following quote still is true:
I'd suggest to wait some time before you jump directly into game programming, because SFML requires basic C++ knowledge. Or read at least a good C++ book in parallel.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 12, 2012, 06:56:07 am
Quote
First off I had to remove all the global varaibles, because the application just crashed because SFML is trying to acquire a mutex on a global resource which somehow fails.
This means: DON'T use global variables (unless you really know what you're doing!), better head into using classes & OOP. ;)

The global variables are temporary, but not causing any problems. I'll change it later. I know they're not good to use, but I put them there to rapidly generate some working code, so they're only temporary.

Quote
Second your random application closing happen in the following line:
if (Event.type == sf::Event::Closed || Event.key.code == sf::Keyboard::Escape)
This translates to: If the even 'Closed' has happend OR by some random undefined behaviour Event.key.code is suddendly equal to sf::Keybard::Escape. You always have to check first if that event you want to use the parameters of, really happend.

I went ahead and removed the Escape command, since I didn't need it anymore, and now the program won't randomly crash like it used. Thanks for letting me know.

Quote
Third you're redefining invEmpty and invHPot all over the place. E.g. here
        sf::Texture invEmpty; // a 5 by 5 blank png
                if (!invEmpty.loadFromFile("invEmpty.png")) return EXIT_FAILURE;
        sf::Texture invHPot; // a 43 by 43 png
                if (!invHPot.loadFromFile("invHPot.png")) return EXIT_FAILURE;
or here:
        sf::Texture invEmpty;
        invEmpty.loadFromFile("invEmpty.png");
If you've decided to use global variables why don't you just use them?

These are also temporary, just to make the code work. After it works, I'm planning to get rid of most/all of the global variables and organize my code completely.

Quote
Forth, for your replace problem I think it's the addItem code itself. I'm not sure what you're trying to heck with if (textureArray.at(i).getSize().x == 5), but that's were your problem probably is. Because if every x size is equal to 5, every single texture will get replaced by the given texture (invHPot).

The reason is because invEmpty is only 5 by 5 pixels, while every other texture is 43 by 43 pixels. I mention this in the code, but I didn't make it clear enough why I did this. If you test out my code, you'll see the function works. However, it won't let me add items while the game is running (by pushing the ADD ITEM button) - it only lets me add items correctly before running the program, and so far nobody is able to tell me why this happens.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: eXpl0it3r on July 12, 2012, 08:19:54 am
"Hey look at my completly broken and rusty car! Could you please put some new shiny rims on it? I'll get the car fix later, but now I just need those rims!"
That pretty much sums it up for me, I wish you good luck!  :)
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Tresky on July 12, 2012, 10:06:21 am
Quote
"Hey look at my completly broken and rusty car! Could you please put some new shiny rims on it? I'll get the car fix later, but now I just need those rims!"
LOL! Ricers!
http://i9.photobucket.com/albums/a95/rehab_/Ricer/ricer.jpg
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 12, 2012, 10:47:39 am
"Hey look at my completly broken and rusty car! Could you please put some new shiny rims on it? I'll get the car fix later, but now I just need those rims!"
That pretty much sums it up for me, I wish you good luck!  :)

If I knew as much as you do, I'd at least be a bit more helpful to people who are new.
"Hey, I've learned programming for 10 years. Good luck getting to where I am."
That pretty much sums it up for me.
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: mastodona7x on July 12, 2012, 12:11:22 pm
Go easy on him guys, I'm a fellow newbie to C++/sfml but always found the people on here really nice and helpful!! And in the IRC chat too...got all my problems fixed without resorting to insults :) Hope you get your game going it looks like turning into a nice little project to me :)
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: Pikmeir on July 14, 2012, 01:08:08 am
I played around with it for several more hours and finally solved it myself. I think it might be a problem with SFML. I tried everything I could think of and was suggested to me, changed the arrays to vectors, and changed the entire system to use an array of integers that represent different items. Everything gave the same outcome.

So my conclusion is this: this might be a bug in SFML. SFML might get confused or something if the textures are below a certain size, or maybe when switching textures via setTexture() that are different sizes? I'm not sure, since I haven't read the SFML source. Anyway it's safe to say that my code should've worked were this not the issue.

Originally invEmpty was a texture that was 5 by 5 pixels in size. When I simply changed the size to 43 by 43 (the same as the other items), the problem disappeared. I'm pretty sure this is therefore a bug in SFML, and not the result of my stupid programming (although I know my programming is pretty stupid).
Title: Re: Help with arrays, and crashing (RPG inventory system)
Post by: eXpl0it3r on July 14, 2012, 02:42:16 am
I actually didn't wanted to write here anything anymore, but here I go anyways... ::)
If I knew as much as you do, I'd at least be a bit more helpful to people who are new.
"Hey, I've learned programming for 10 years. Good luck getting to where I am."
That pretty much sums it up for me.
Okay, it seems you didn't understand at all what my analogy should have told you. Here again in English: First, if you program something, then don't do it just for 'temporary' cause and specially when other people with more experience tell you to change it, since it may ivoke side effects.
Second, if people tell you to go study and read about certain topics specially basics ones, then do so and don't expect that the knowledge will suddendly fall from the sky. Ignoring such adivce is really ignorant and tells the people willing to help that you're not willing to learn and thus the whole process of helping seems to be for nothing.

So my conclusion is this: this might be a bug in SFML. SFML might get confused or something if the textures are below a certain size, or maybe when switching textures via setTexture() that are different sizes? I'm not sure, since I haven't read the SFML source. Anyway it's safe to say that my code should've worked were this not the issue.

Originally invEmpty was a texture that was 5 by 5 pixels in size. When I simply changed the size to 43 by 43 (the same as the other items), the problem disappeared. I'm pretty sure this is therefore a bug in SFML, and not the result of my stupid programming (although I know my programming is pretty stupid).
Assuming something is defect in someone elses code without even completly understanding what's happening in its own code is just wrong.

If you had read the documentation (or looked at the functions signatures probably provided by your IDE) you could have figured out your problem way earlier and yes it's all "the result of my stupid programming". Since one would never relay on some size of a sprite/texture to figure out the current state.

From the documentation (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560):
Quote from: Laurent
void sf::Sprite::setTexture (const Texture & texture, bool resetRect = false)      
Change the source texture of the sprite.

The texture argument refers to a texture that must exist as long as the sprite uses it. Indeed, the sprite doesn't store its own copy of the texture, but rather keeps a pointer to the one that you passed to this function. If the source texture is destroyed and the sprite tries to use it, the behaviour is undefined. If resetRect is true, the TextureRect property of the sprite is automatically adjusted to the size of the new texture. If it is false, the texture rect is left unchanged.

Parameters:
  • texture   New      texture
  • resetRect      Should the texture rect be reset to the size of the new texture?

If you didn't get what this is all about, here again in plain text: You have to use sprite.setTexture(texture, true); so the rectangle gets reset.

Keep in mind this doesn't mean that everything is solved for sure (since you got so much stuff around that could go wrong, e.g. the removal of item 2 or 3 doesn't work afaik), but it will at least get rid of the (in your opinion) main problem.

And again: Read a book about C++ & RTFM (http://www.sfml-dev.org/documentation/2.0/index.php). ;)
Title: Re: (SFML bug?) Help with arrays, and crashing
Post by: Pikmeir on July 14, 2012, 03:20:51 am
Thanks for finally helping me!
After reading about how textures work in your post (quoted from Laurent), it all makes sense now. Although I solved it by switching my code around, I'll keep this in mind for the next time.

But it is interesting how you must've known this all along, but refused to help someone who knew less than you simply because "I know less than you so I have to learn everything by myself, without anyone's help."

Well, how about if you opened up a book when you were new to programming, and the book only said, "learn it yourself, cuz that's how I did it." Maybe this is a bit exaggerated, and I guess you'll disagree.

Anyway thanks though. I guess there is a purpose for slightly rude, yet experienced programmers like you in the help forums.

I should add that the "thank you" here is real though. I do appreciate you finally giving me a helpful answer, and I really will remember it to not make the same mistakes in the future. But that's how I learn, by trying my best and making mistakes and fixing them, and not being afraid to ask people more experienced than me for help.
Title: Re: (SFML bug?) Help with arrays, and crashing
Post by: eXpl0it3r on July 14, 2012, 03:44:35 am
No I didn't know the answer at all until a few minutes before I posted the other post. And thats because I sat down took your code removed everything that was not needed and step by step added a few things. Thos whole process costed me around 30min. This wohle thing shouldn't have been my work to do but yours. I know your spend quite a lot of time figuring things out, but with minimizing and then slowly progressing you would have found the problem too. But you insisted on keeping your functions and weren't willing to make everything simpler...

I still don't see where I wasn't helping. I pointed out many flaws and errors and just because I didn't sit down for 30 or longer to take apart your messy code back then, you consider me as not willing to help?

Trail & error is always present but there are diffrent angels to it. If someone just throws code at others and expect them to reprogram everything fir them then this is a bad angle, it would be better to follow the advice given by others and spend more time on thinking on it's on and comtinuesly sharing the progress.

And if you're lacking in basic knowledge things that SFML requires then you should maybe refresh your memory on your own or go to a diffrent forum specific to basic C++.
Title: Re: (SFML bug?) Help with arrays, and crashing
Post by: Pikmeir on July 14, 2012, 04:49:05 am
I never expected anyone to reprogram everything. My original post only had a few lines which I shortened as much as possible to illustrate the problem I was getting, and reading it again now I can see that my original problem could've been fixed through just looking over the first post - had I known exactly how SFML textures worked. I didn't know exactly how they worked, so I came here for help.

I will say that the suggestions you first told me I did implement and fix (although I didn't upload it here to avoid repetitively posting my code), but my original problem was still there. When I told you that, you just said my code was horrible (even though I apologized in advance for being new), pointed out unrelated issues that weren't causing my actual problem, and because you seem to have OCD insisted I fixed those before doing anything.

And if you're lacking in basic knowledge things that SFML requires then you should maybe refresh your memory on your own or go to a diffrent forum specific to basic C++.

So basically you're saying, "This forum is for experienced C++ and SFML users only. Get out."
It's quite tongue-in-cheek, but I understand. Thanks for eventually helping me solve the problem, but I'm not sure I'd do it again in exchange for having people push me away from their "help forum" for being inexperienced. I probably will take your advice and stay away from this forum from now on, especially after the welcome I've gotten trying to post my questions here.
Title: Re: (SFML bug?) Help with arrays, and crashing
Post by: eXpl0it3r on July 14, 2012, 12:14:03 pm
...and because you seem to have OCD...
What a creative insult. :)

I never expected anyone to reprogram everything. My original post only had a few lines which I shortened as much as possible to illustrate the problem I was getting.
How else do you expect people to understand your code? I mean if it were nicely laid out it would habe been easy to read and understand but having global objects and a bit more complex machanism there's no other way than to recreate everything to first fully understand what's happening and second to find the bugs.

I will say that the suggestions you first told me I did implement and fix (although I didn't upload it here to avoid repetitively posting my code), but my original problem was still there.
I'm not quite sure what you're refering to, but you probably should have upload that code, so it would've maybe been easier to understand your code.

When I told you that, you just said my code was horrible (even though I apologized in advance for being new), pointed out unrelated issues that weren't causing my actual problem, and because you seem to have OCD insisted I fixed those before doing anything.
That's the problem. When your code is messy it's hard to understand it without having to go through everything and the possibility is quite high that something along the line was causing it.
I gave up helping you because I didn't want to spend my time looking through your messy code but I would have looked through it if you just cleaned it up. And figure that at the end I now even spend my time to go through your code and check back here to read some of your nicely insults.

So basically you're saying, "This forum is for experienced C++ and SFML users only. Get out."
It's quite tongue-in-cheek, but I understand. Thanks for eventually helping me solve the problem, but I'm not sure I'd do it again in exchange for having people push me away from their "help forum" for being inexperienced. I probably will take your advice and stay away from this forum from now on, especially after the welcome I've gotten trying to post my questions here.
Feel free to turn my words around. ::)
What I'm saying is that we're happy to help in most of all problems, but fact is that SFML shouldn't be the first thing anyone starts to program with. There are many basics in C++ that one just have to learn first before digging into a library. So if we notice that there's a lack of knowledge we point that out and since this forum is about SFML and not how to learn C++ we often don't feel like explaining in depth what a good book could tell you even better.

Have fun! :)
Title: Re: Help with RPG inventory system (solved) Thanks!
Post by: Tank on July 15, 2012, 02:49:59 pm
Pikmeier, a warm welcome to the SFML forum, where even newbies get appropriate help! :)

Seriously, there's a big misunderstanding by newbies, very often. You stated that you're new to programming (C++) and SFML. That implies you will at least have problems with a) programming C++ in general, b) understanding C++ code design principles and c) using SFML (together with a and b!).

Up to now, you've probably been able to build some programs that "just run" – *somehow*, but unfortunately you're running into a big problem now, which is often the result of tens or hundreds of other small problems.

So you post in this forum, describe your problem, and because you don't really know where it comes from (because you actually don't have a clue what everything does in detail, or you got lost because of a bad code design), you paste a lot of source code.

That's the first sign for an experienced user that someone is having *problems with basics*, if it's C++ programming or using SFML.

There's really no insulting intended, but imagine you've been through all of that, i.e. you learned your stuff and are now in a position to provide help. Nobody learns from getting replies in a forum, that's just for specific problems that you can't solve. Instead you read bundled information, like books, SFML tutorials or even source code of other projects.

But one thing is *really* for sure: When an experienced user throws "RTFM" or "Read a C++ book, learn the basics!" at you, then chances are high that she or he is, guess what, just right. :)

On IRC a lot of newbies come and go, a lot are asking very basic questions which can be solved by giving them a link to SFML's Doxygen documentation. And often we hear something like "Oh thanks, I haven't yet seen that docs!". You know what that implies? It implies that the proper user did not click on "Documentation" on the website. And especially those users often yell "Why can't you just help me instead of telling me to read myself?"..

So, the main reason why you're getting "RTFM" is that it's a waste of time to explain things to you that are explained in books/articles already, you just have to read them.

Besides of that, also very common, you were able to sort out your problem yourself by investing some more thinking and time into it. *That's* how you learn stuff, not by asking for the fixed source code.

So please don't feel insulted when people tell you to learn your stuff, there's a reason behind it. If you've got *specific* problems we're for sure happy to help you, or general questions about game design etc.

And again, welcome!
Title: Re: Help with RPG inventory system (solved) Thanks!
Post by: Pikmeir on July 15, 2012, 09:54:58 pm
Pikmeier, a warm welcome to the SFML forum, where even newbies get appropriate help! :)

Thanks Tank.
In this situation, I jumped in here after trying to solve it myself for 7 consecutive days unsuccessfully; I couldn't find anywhere in the documentation myself why it wasn't working. I thought it might be an update issue, so I was looking for something like an update() function within the code for several days but I couldn't find one.

Anyway with that said, do you have a recommended C++ book? I've been using the cprogramming.com and learncpp.com tutorials, and have pretty much finished them all and am looking for an actual book to learn more from - by "more" I mean the same things all over again, but from another perspective.
Title: Re: Help with RPG inventory system (solved) Thanks!
Post by: mastodona7x on July 16, 2012, 12:57:39 pm
I just borrowed "C++ for game programmers" by M J Dickheiser from the libray, I too started with learncpp.com and this book goes over some of that stuff in far more depth and all from the point of view of developing games...seems interesting (if a little bit daunting)...I also borrowed "AI game engine programming" which looks good too and has real world examples and AI ideas/code snippets for all different game genres (racing, RTS, RPG, FPS etc etc etc) which makes it quite an interesting read so far.