A rough PhysicsComponent

After refactoring the Sprite and turning it into a SpriteComponent I thought the next most obvious candidate for my new component system was a PhysicsComponent that will be responsible for moving the GameObject.

Basically I had a look at my existing player class and decided that there was quite a bit of code related to the movement of the sprite itself. So I decided to pull all that out and move it into my new PhysicsComponent. My PhysicComponent currently looks like this:

class PhysicsComponent : public Component {
public:
 PhysicsComponent();
 PhysicsComponent(const glm::vec3 a_position, const float a_fRotationSpeed, 
                  const float a_fRotationAngle = 0);
 void AddForce(const glm::vec2 a_force) { m_acceleration += a_force; }
 void AddRotation(const float a_fRotation) 
                  { m_fRotationAngle += a_fRotation; }
 glm::vec3 GetPosition() const { return m_position; }
 float GetRotation() const { return m_fRotationAngle; }
 void Update(const double a_dDeltaTime);

private:
 glm::vec3 m_position;
 float m_fRotationAngle;

 glm::vec2 m_velocity;
 glm::vec2 m_acceleration;
 float m_fRotationSpeed;

 static const float m_fFrictionValue;
};

Basically I want to store and manipulate the position and rotation of a GameObject – so I’ve provided getters for these values since other components will need to work with them (so far just my SpriteComponent).

Something I probably knew already, but had forgotten, is that static const class members must be initialised outside of the class declaration, and also outside of any member functions. So at the top of PhysicsComponent.cpp I have the line:

const float PhysicsComponent::m_fFrictionValue = 0.97;

Though really the friction shouldn’t be the same for all objects, so I guess I might turn this into a regular const in my next coding session.

All the interesting code is really inside the Update function – it’s basically a straight conversion from what I had in the Player Update function.

void PhysicsComponent::Update(const double a_dDelaTime)
{
 m_velocity.x += m_acceleration.x * a_dDelaTime;
 m_velocity.y += m_acceleration.y * a_dDelaTime;

 glm::vec4 rotationVector = glm::rotate(glm::mat4(1), 
                            m_fRotationAngle + 90, glm::vec3(0, 0, 1)) 
                            * glm::vec4(m_fRotationSpeed, 0, 0, 1);

 m_position.x += m_velocity.x * a_dDelaTime * rotationVector.x;
 m_position.y += m_velocity.y * a_dDelaTime * rotationVector.y;

 m_velocity *= m_fFrictionValue;

 m_acceleration.x = 0;
 m_acceleration.y = 0;
}

Here I’m just calculating the velocity based on any forces that had been added since the last update (I kind of like this approach, means I can apply multiple forces and just add to the acceleration in a frame). Then calculating the rotation (perhaps I should cache this vector and only calculate this if the rotation actually changes? Right now I’m doing it every frame..) and using these two results to calculate my current position. I also adjust the velocity down a bit to simulate friction (though there probably isn’t friction in space).

Lastly I set the acceleration to 0. This feels a bit hacky since I don’t really think acceleration works like this. But it works well for the moment.

Since the PhysicsComponent needs the delta time in the Update function then I needed to add it as an argument in the Update function of the base class. Which made me realise that the SpriteComponent Update function was incorrect. I was passing in position, rotation and scale, which meant it wasn’t actually overwriting the base Update and attempts at polymorphism wouldn’t work. So I decided to go back to having the position, rotation and scale as members of the SpriteComponent – and public ones at that, since they need to be set externally after object creation (more on this shortly). This meant I could fix the parameters of the Update function so they matched the base class.

I also realised I had not written a constructor for my Component class – so I had no way of setting the ComponentType. Once this was fixed I could set the type properly from SpriteComponent and PhysicsComponent.

Once finished with all this I decided to try and put some of this together into my PlayerObject. This is the result so far:

void PlayerObject::Update(const double a_dDeltaTime)
{
 GameObject::Update(a_dDeltaTime);

 GLFWwindow* currentContext = glfwGetCurrentContext();
 PhysicsComponent* physicsComponent = 
          dynamic_cast<PhysicsComponent*>(GameObject::GetComponent(PHYSICS));
 if (physicsComponent != nullptr) {
     if (glfwGetKey(currentContext, 'W')) {
         physicsComponent->AddForce(glm::vec2(150, 150));
     }

     if (glfwGetKey(currentContext, 'A')) {
         physicsComponent->AddRotation(3);
     }

     if (glfwGetKey(currentContext, 'D')) {
         physicsComponent->AddRotation(-3);
     }
 }

 SpriteComponent* spriteComponent = 
          dynamic_cast<SpriteComponent*>(GameObject::GetComponent(SPRITE));
 if (spriteComponent != nullptr) {
     if (physicsComponent != nullptr) {
         spriteComponent->m_position = physicsComponent->GetPosition();
         spriteComponent->m_fRotationAngle = physicsComponent->GetRotation();
     }
     spriteComponent->Draw();
 }
}

A few observations – I dislike the way I’m currently accessing each of these components. However as I mentioned in my previous post, I’m planning on fixing the component system up a bit so that there are shared arrays of components in the Screen and the GameObjects will just contain references to them (either pointers or indices). So I will leave this alone for the moment.

Also – I really don’t like having to set the position and rotation of the Sprite like this. I feel like the Sprite and Physics components will have to work together like this in a number of objects, so I’m going to have to repeat this code. Which is a warning sign that it can probably be done in a different way. I’m just not sure how – though I am going to add this to my list of planned refactors/changes.

OK, that’s all for now. Please let me know what you think, or ask me a question if you don’t understand my logic or a piece of code.

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
{
public:
 PlayerObject();
 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.

Components

Dear Rebecca from last week – you have been programming with Unity and C# for too long and it shows:

I will add a Cleanup function to all Screens so that I can call it before I delete the Screen itself in the main loop.

Uh – that would be known as a destructor. How embarrassing. Anyway, I’ve now added a virtual destructor to the Screen class and overloaded it for any Screens where I was creating memory.

After reading over my other idea from last week:

I also thought it would be a good idea to have some sort of list of Sprites and Texts in the base Screen class.

I think doing that is actually a bit of a waste of time – since some of my Sprites are now hidden within my messy “Player” and “Enemy” classes. I originally wanted to try the Component pattern out on a fresh project – but I might as well give it a go now, especially since I have some classes that would make more sense in this pattern.

To switch to the Component pattern I’ve been referencing the great book Game Programming Patterns by Robert Nystrom. I actually paid for it because it’s helped me so much – but you can also access it for free (legally) here.

Anyway – setting this up is going to take more than one session, so I’ve made another branch for this feature just to make sure I don’t destroy the working game I already had. You can find that branch here if you’d like to have a look at what I’m up to.

I decided to have an abstract Component class which all my components are going to inherit from. To begin with my class looked like this:

class Component {
public:
 virtual void Update() = 0;
private:
};

The other class is a GameObject class (yes, my time with Unity is really rubbing off). I wanted the GameObject to have a collection of Component pointers – then I can add to and remove from this collection if needed. To start with:

class GameObject {
public:
 ~GameObject();
 void AddComponent(Component* a_component);
 void Update();
private:
 std::vector<Component*> m_components;
};

Right now I’m making the assumption that I will only have one Component of each type in a GameObject. So, if I have a Sprite component – I can only have 1 Sprite within a GameObject. Currently there’s no safeguard for this – I’ll have to do this in the future.

Once I got up to the RemoveComponent function in GameObject I got a tad stuck (actually, I spent a good twenty minutes trying to get out of the C# mindset I usually work in – with reflection this solution looks a bit different). I want to be able to remove a Component by type since I’m not likely to have a pointer to the exact Component  that I want to delete. Which means I need to have some way of determining the type of Component at runtime.

I’m not super happy with the solution I’ve rested on for now, but perhaps I can revisit it once I’ve learned more and make it better. I decided to add a type variable to Component that should make identifying it a bit easier.

enum ComponentTypes {
 RENDERER,
 PHYSICS,
};

class Component {
public:
 virtual void Update() = 0;
 ComponentTypes GetComponentType() { return m_componentType; }
private:
 ComponentTypes m_componentType;
};

The reason I am a bit dubious about this is because I will have to add a field to this enum each time I add a new Component child class. It seems like it would be easy to forget to do this, which could cause bugs. Having some way where a Component child class could register itself as a type somehow would be good – will have to think more on this.

Anyway, it’s now a lot easier to make a RemoveComponent function – I just need to pass it a type and loop through looking for that type.

void GameObject::RemoveComponent(ComponentTypes a_type)
{
   int indexToErase;

   for (int i = 0; i < m_components.size(); i++) {
     if (m_components[i]->GetComponentType() == a_type) {
       indexToErase = i;
       break;
     }
   }

   m_components.erase(m_components.begin() + indexToErase);
}

This could definitely be done better. I want to take performance into account a little bit – so I would like to find out:

  1. Is a vector the correct data structure for this? (I know vectors perform well for iteration, but slowly for removals + resizing. I am doing a lot of iteration though…)
  2. Should I be using this vector? Should I roll my own? Or should I try using the EASTL since they’ve just released it? (I’m leaning towards the last option since I’d learn quite a bit from that experience).

I also added a GetComponent function to the GameObject – mostly because Unity has one and I use that all the time, so it seemed like a good idea. It’s really the same as the remove function – I just loop through until I find a component of the correct type and return it.

Right, quite happy with my progress for tonight – next time I will try and adapt my Sprite class into a Component, which may get ugly :p

If you have any questions or suggestions then please let me know – pretty sure the comments here work, if not then feel free to tweet at me: @chainedchaos31

Small additions, refactors and planning

Finally had time and motivation today to get back to my old OpenGL project. Today I wanted to add a “win” and “lose” screen and just tidy up the Screens (which are really states) in general.

For some reason I had a stack in main where I would push screens onto if I needed to change. However I wanted the screen flow to be like this: “Main Menu” -> “Game” -> “Lose” -> “Main Menu”. So I didn’t want to put the lose screen over the game screen in the stack since I didn’t want to return to the game screen when the lose screen was done.

I figured that it made much more sense to just have a pointer to the current screen.

The way I currently change screens is by analysing the return value of the update function. If the return value is the current screen I do nothing, if the return value is null then the game loop ends. If the return value is a different screen then I delete the old current screen and replace it with the screen that was returned. (Why did I not do this in the first place?)

So, I added the Win and Lose screens – which was a trivial task, they looked almost identical to the MainMenu screen.

So much so, in fact, that I want to refactor the Screens a bit next time. I want to move the common code (so far just the calls to set the projection matrix in the shaders) down into the base Screen class. I also thought it would be a good idea to have some sort of list of Sprites and Texts in the base Screen class. Then the Draw function can just loop through them all and draw them (maybe even more ideally they would have an ordering I can specify so things will be drawn in the correct order).

Also, I’m currently not cleaning up a single thing, so I have memory leaks all over the place. I will add a Cleanup function to all Screens so that I can call it before I delete the Screen itself in the main loop.

The setup of each Text also seems convoluted and repetitive, but I’m not sure I want to change that for this project. Perhaps I will just iterate on it for the next project I’m planning.

The code of my project is located here – for those who’d like to look at what I’ve changed.

For the next project I’d like to experiment a bit more with the Component system. I think I will take inspiration from Unity’s GameObject and try to emulate that in my own engine. This was suggested to me last year when I started this project, but I lacked the experience and confidence to try it out. I now feel WAY more confident (and even excited) about piecing together a component system on my own – so I’m pretty happy with how my knowledge has progressed from last year.