Sign in to follow this  

Finding and using data

This topic is 3152 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have a recurring question that always seems to crop up when I'm working on a project. How do you go about accessing specific data that you need. Suppose I have a std::list<Sprite*> and I'm on the main menu and want to call NextFrame() on the play button when the mouse is over it. Now I could build up some sort of Id class that is used to access into this list, maybe even a handler class with a pointer to a specific sprite that is created from a string argument. What would be another way to do this? How do I take something generic and make it specific? Shouldn't I generally avoid doing it? And in cases like this, how? What is your solution?

Share this post


Link to post
Share on other sites
Quote:
Original post by livengood
How do you go about accessing specific data that you need.


This is a very general question.

Are you asking specifically about sprite animation, or...?

Apologies if I've misunderstood your post.

Share this post


Link to post
Share on other sites
Let me go in a bit more depth.

All the sprites in this case are stored in a std::list, they have no notion of one another. I want to access my sprite "Play Button" and then call NextFrame() on this "Play Button" sprite. I can't simple call NextFrame() on any sprite. I need to call it on only the "Play Button" sprite. This sprite however has no notion that it's a play button, it remains generic, holding only it's texture ref and orientation data.

I was just asking in general, not specifically about sprite animation. This just happened to be the case at hand.

Hope this helps

Share this post


Link to post
Share on other sites
The problem here is that you're going too generic. That sprite is more than just a sprite - it's a button. Generalizing that away is not a smart idea. Why not write a Button class for it, that offers button-specific functionality, and that contains a Sprite internally for it's representation? Suddenly, it's much easier: a Button updates it's own Sprite whenever it changes state, and you just have to go and check a few buttons whenever you click somewhere, rather than running through every sprite.

Share this post


Link to post
Share on other sites
Quote:
Original post by Captain P
The problem here is that you're going too generic. That sprite is more than just a sprite - it's a button. Generalizing that away is not a smart idea. Why not write a Button class for it, that offers button-specific functionality, and that contains a Sprite internally for it's representation? Suddenly, it's much easier: a Button updates it's own Sprite whenever it changes state, and you just have to go and check a few buttons whenever you click somewhere, rather than running through every sprite.


This makes sense. What construct would then hold the buttons? My main menu in this case has say 6 buttons and each subsequent menu after that has 5 more buttons. I suppose this would be a reasonable place to employ an std::map. I understand what you mean by too generic. This is a 3d game so the large majority of sprites are in fact buttons, I suppose that's why I didn't make the distinction myself.

So to extend on this, in the situation I mentioned in my previous post, the sprites had a relationship as follows: Each Sprite was stored in a SpriteBatch, these batches consisted of sprites that should generally be grouped together, a common case would be the main menu sprite batch (which I could load in from xml), the SpriteBatch(s) were further stored in a SpritePool which is essentially a central update area for all Sprites in the game. In the case you describe this model would be represented more specifically. The 'Menu' would hold a container of 'UIElement' and each 'UIElement' would hold a sprite representation? How would I go about grouping and updating these menus? Would I gather all the menus into a vector for updating? Would I do it one at a time? Maybe make a small UI interface in the engine that can have menus added to it? Hmm, that brings up another question, how do I get this to the renderer. Before I could supply the renderer with a spritepool and it would go through rendering each sprite, in this case each sprite is individual. Do you then add a RenderQueue where each sprite is inserted everyframe? or make the sprite render itself then adding render specific code to each sprite...

Your post was excellent and I appreciate it. It's one of those things that you don't think about until someone else mentions it. I think it has become a syndrome of mine, generalizing like this, thanks.

[Edited by - livengood on May 1, 2009 6:32:23 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by livengood
The 'Menu' would hold a container of 'UIElement' and each 'UIElement' would hold a sprite representation?


That sounds like a good plan. You could even subclass UIElement and write LabelElement, ButtonElement, etc classes, with different behaviours.

Share this post


Link to post
Share on other sites
Quote:
Original post by beebs1
Quote:
Original post by livengood
The 'Menu' would hold a container of 'UIElement' and each 'UIElement' would hold a sprite representation?


That sounds like a good plan. You could even subclass UIElement and write LabelElement, ButtonElement, etc classes, with different behaviours.



Yeah, this makes sense. Looks like I'm adding a GUI to the game. What do you think of the other questions I asked(sorry, edited them in without realizing how quickly you'd respond)

Share this post


Link to post
Share on other sites
Ok.

Off the top of my head, something like this seems reasonable...

You could use a base GUI element, which defines methods for all the 'events' you're going to need. They're probably all going to be empty, but this gives you a common interface to use later on. Each element would likely also keep track of it's position, and maybe it's dimensions. For example:


class GUIElement
{
protected:
float x, y; // Screen-space position.

public:
virtual void setText(const std::wstring &text) {}
virtual void setSprite(const Sprite *sprite) {}

virtual void onClick() {}
virtual void onDraw() {}

// Any other actions you need...
};


You can then subclass this, to create specific elements with different behaviours - maybe labels, buttons, or whatever you're game needs.


class GUIButton : public GUIElement
{
private:
Sprite *sprite;

public:
void onClick()
{
// Button clicked...
}

void onDraw()
{
// However you draw you're sprite.
}
};


To wrap it up, you could use a Menu class which owns a list/map of GUI elements. If you're loading menu layouts from file, for example, you could create and store each element in a map along with some ID. This might look like the following.


class Menu
{
private:
std::map<int, GUIElement*> elements;

public:
// Reads the file and creates the specific elements.
Menu(const std::wstring &filename);

// Draws the menu...
void draw()
{
// Iterate over the std::map and call onDraw() on each element.
}

// Processes a mouse click...
void onClick(float x, float y)
{
// Iterate over the std::map and check if the click-coordinates hit
// any element. If so, call onClick()
}
};


Is that any help?

Share this post


Link to post
Share on other sites
Well yeah, that is about how I plan to do it, aside from changing the name of 'menu' to be more general and adding a SuperClass above all that for the whole jazz. I'm not sure how I can gather up the different sprites for rendering though, as they are all spread out amongst different classes. I mentioned that I could possible queue them up as an operation and then feed that into the rendering. How else would I go about getting all these sprites to render (I don't really want to have render specific code in each sprite)

Share this post


Link to post
Share on other sites
Why not have the renderer own the sprites, and just give out handles. Then every time the elements are drawn, they can pass the sprite handle back to the renderer - it could draw the sprite straight away, or queue it up - but the GUI elements don't need to know either way.

That way the element classes only know about what they need to - where they are, and how they should react to actions.

Share this post


Link to post
Share on other sites
Hmm. My ResourceManager technically already owns the Texture that each sprite uses. I suppose I could make a class that holds the sprites and gives out handles to the UserInterface. The Renderer could then just be fed the Sprites from the intermediate class.

Share this post


Link to post
Share on other sites
I usually create a Screen class, that provides an interface containing an update function, various input functions and the like. It's a sort of state machine, where every Screen instance is a separate state, and there's only one active at the same time. Now, for the actual menus, I derive a class from Screen for each menu - and also one for the actual game. That'll give you classes like MainMenu, OptionsMenu, GameScreen. Now, in each of these classes, you can easily add the GUI elements that you need.

Sure, you can load such information from a file, but I've found adding menu logic to files to be rather tricky - it easily results in writing a basic menu scripting language, which may turn out to take more time than simply writing some code in the main development language. Unless your game already supports scripting, I think it's too much hassle for too little gain. Loading position can be useful, but then you end up with two places that need to be kept in sync: the data file, with the positioning data, and the code file, with the associated logic.


As for sprites, I'd make the renderer own them, and I'd allow the menus and game-code to manipulate them. Now, this renderer should provide an easy-to-use interface for external code - a menu doesn't need to know how these sprites are batched, or that they're even batched at all, it should just tell the renderer to create a sprite with this-and-that texture and at that location. The renderer does that part of the job, while the menu handles the actual menu logic. Each his own job.

As for maps, I don't see the need for a map here. You check which button is hit... and at that point you already know what button you need to work with. What's the whole purpose of mapping buttons to ID's if you're never going to look them up on their ID?

Share this post


Link to post
Share on other sites

This topic is 3152 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this