Sprites disappear after about 4-5 seconds (Fixed!)
Alright, I think I see it now. Seems private/protected is pretty much a way to really organize code, in the simliest sense. Thanks for all the help, I learned alot today ^_^.
Some cleanup, to make use of RAII, the initializer list, etc.
// A wrapper for D3DXVECTOR2 to make them easier to initialize.struct vec2 : public D3DXVECTOR2 { vec2(float x, float y) { // I don't think this can be done via the initializer list, unfortunately. this->x = x; this->y = y; }};class Sprite { // A helper cleanup function. // You'll also find this useful if you end up implementing a copy constructor // and or assignment operator. For now I've assumed that Sprite objects should // not be copied at all. To make the compiler enforce this, declare those // functions in the private section and don't implement them, thus: Sprite(const Sprite&); Sprite& operator=(const Sprite&); // Oh yeah, that cleanup function :) void cleanup() { if(m_pSprite) { m_pSprite->Release(); } if(m_pTexture) { m_pTexture->Release(); } } protected: LPD3DXSPRITE m_pSprite; // ID3DXSprite LPDIRECT3DTEXTURE9 m_pTexture; // sprites texture public: // I typically define constructors and destructors inline. You don't have to. // Note that to avoid having the Sprite class dependant on ("coupled to") the // main module, I've provided the device as a parameter. You'll be grateful // for this later if you ever need a second LPDIRECT3DDEVICE9. Sprite(const char* pathname, LPDIRECT3DDEVICE9 dev) : m_pSprite(0), m_pTexture(0), m_RotCenter(0.0f, 0.0f), m_Translation(0.0f, 0.0f), m_Scaling(1.0f, 1.0f), m_ModulateColor(D3DCOLOR_XRGB(255,255,255)), m_Rotation(0.0f) { // We shouldn't create the object if we can't get a valid texture and sprite. if (FAILED(D3DXCreateTextureFromFile(dev, pathname, &m_pTexture)) || !m_pTexture) { throw std::exception("Could not load texture into memory"); // TODO: Make own exception type for this. } if(FAILED(D3DXCreateSprite(g_pd3ddevi, &m_pSprite)) || !m_pSprite) { // Note: need to clean up the texture! cleanup(); throw std::exception("Could not create the new ID3DXSprite Object"); // Same TODO here. } } ~Sprite() { cleanup(); } vec2 m_RotCenter; // center position vec2 m_Translation; // translation factor vec2 m_Scaling; // scaling factor float m_Rotation; // angle of rotation D3DCOLOR m_ModulateColor; // the color to modulate with the sprite bool Render(int x, int y); // renders at a location bool Render();};// Render the sprite at a location.// Don't need to check validity of pointers; the constructor made sure of them.bool Sprite::Render(int x, int y) { vec2 tmp = m_Translation; m_Translation = vec2(x, y); boolean result = Render(); m_Translation = tmp; // restore the old translation. return result;}// Render the sprite at its stored location.bool Sprite::Render() { m_pSprite->Begin(); bool success = !FAILED(m_pSprite->Draw(m_pTexture, NULL, &m_Scaling, &m_RotCenter, m_Rotation, &m_Translation, m_ModulateColor)); // Clean up unconditionally m_pSprite->End(); return success;}// There's too much body code for me to clean up, but example usages then go like:vector<Sprite> tryCreatingAllSprites(const vector<string>& names) { vector<Sprite> result; for (vector<string>::iterator it = names.begin(); it != names.end(); ++it) { try { result.push_back(Sprite(*it, g_pd3ddevi)); } catch (std::exception& e) { MessageBox(0, e.what(), "error", 0); } } // The 'results' now contains Sprite objects corresponding only to those // files which were successfully loaded. return result;}// Or, for working with a single Sprite, and assuming the creation succeeds...Sprite x("Sprite bird front.png", g_pd3ddevi);x.Render(); // at 0,0, because we didn't set it yetx.m_Translation = vec2(40, 40);x.Render(); // at 40, 40x.Render(123, 456); // at 123, 456x.Render(); // at 40, 40 again!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement