Refactoring the Sprite

In my last post I talked about how I’d begun the process of implementing the Component pattern in my project. There were some excellent responses to that post that you should read. I’ll definitely be changing how my Component system works in the future – I think I will have an array for each type of game component in the scene and store all the game components there. My GameObjects will just have pointers to the correct components.

I was doing some reading about the component pattern, and some improvements. I came across a great series of blog posts about Entity Systems. These sound quite appealing and I’d like to implement this change to my component implementation at some point. Right now though, I plan on making my components work together in the Update functions of their GameObject classes. I went ahead and added a stub for my Player object – I will add the gameplay logic in the Update function:

class PlayerObject : public GameObject
 void Update();

However I spent most of my time tonight on refactoring my existing Sprite code into a SpriteComponent. This mostly involved removing code that was no longer being used – and making sure that the SpriteComponent is only responsible for drawing a Sprite to the screen (and nothing else). There was a little bit of gameplay logic in the Update function:

//wrap sprite around the screen when they move off
 if(m_oCentrePos.x < 0)
 m_oCentrePos.x = 800;
 else if(m_oCentrePos.x > 800)
 m_oCentrePos.x = 0;
 if(m_oCentrePos.y < 0)
 m_oCentrePos.y = 600;
 else if(m_oCentrePos.y > 600)
 m_oCentrePos.y = 0;

I removed this code from the Sprite and I think I will move this to the PlayerObject Update function. This means that the m_oCentrePos variable (which I’ve actually renamed to m_position in SpriteComponent) either needs to be publicly accessible or I need to add translation functions to modify it. Since I haven’t implemented any parenting of objects and everything is in the same co-ordinate space right now I have just made the position public. When I add the ability to parent GameObjects to one another (probably a scene graph, if I can remember how to make one) then I will rethink whether the position should be public or not.

Removing this gameplay logic actually made it clear that the only time the position (and rotation and scale) were used was in the draw function. So I thought it made more sense to remove variables as member variables and just pass them into the Draw function:

void SpriteComponent::Update(glm::vec3 a_position, float a_fRotationAngle, 
float a_fScale)
 m_globalTransform = glm::translate(glm::mat4(1), 
 glm::vec3(a_position.x, a_position.y, a_position.z)) *
 glm::rotate(glm::mat4(1), a_fRotationAngle, glm::vec3(0, 0, 1)) * 
 glm::scale(glm::mat4(1), glm::vec3(a_fScale, a_fScale, 1));

So I guess I’ll need to make another component that contains these variables (maybe something like Unity’s transform?)

Contrarily, I added the vertex buffer, index buffer and a pointer to the shader program to the sprite component as member variables (in hindsight perhaps the VB and IB should be pointers too – so I can share them between sprites).

Lastly, I noticed that in the Sprite constructor I was actually loading the texture for the Sprite. Looking at this now – I think it’s a bad idea to load from file at this point since a Sprite could get initialised in the middle of a frame (and loading things from file is sloooow). I haven’t changed anything yet, but it makes sense to me to load all the textures when the program opens, then just pass the texture handle to the Sprite Component.
This would mean perhaps having a global collection of texture handles – I was thinking a dictionary (oh, that’s a map in C++). I will fix this up once I’m done with my Component system.

It feels like everything I’m doing in the last few blog posts is quite simple – however I know software architecture was not a skill of mine at this time last year and I would never have been able to do all this. So I want to explain my thought processes in case someone at the skill level of last year me stumbles across this.

I’m actually rather embarrassed by how bad I was at software architecture last year. It worries me that I taught students for so long at a tertiary level while not having this knowledge. I must have passed on so many bad habits! If any of my old students are reading this – I’m so, so sorry. I think I’m kind of writing these blog posts for all of you. These are the things I wish I’d taught you.

As always, you can find my code on github (currently the component system is not hooked up to the game though). Make sure to check the component branch since I haven’t moved anything into master yet.

One thought on “Refactoring the Sprite

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s