Smart Mass

Smart Mass

Now we need to add mass to our objects to make the physics system a little more robust: we’ll simply add float mass to our object, update the constructor to allow us to set this float, and in the applyForce() function we’ll divide the force by the mass of the object to get our acceleration that we want to apply: force.div(force).

With that applied we can see that nothing has really changed, if we change the mass of the object we find it accelerates more slowly, but the affect is more obvious when we add a second mover object to the scene. We’ll add another object called ball2 and make sure to set the mouse button to apply wind to it as well:

[pastacode lang=”cpp” manual=”%7BIn%20Main%20before%20render%20loop%7D%0A%0Amover%20ball2(0%2C0%2C0%2C0%2C0%2C0%2C20%2C5)%3B%0Aball2.loadImage(%22Images%2Fball.png%22%2C%20renderer)%3B%0A%0A%0A%0A%7BIn%20event%20handler%7D%0A%0Acase%20SDL_MOUSEBUTTONDOWN%3A%0A%20%20%20%20%20%20%20%20%20%20ball.applyForce(wind)%3B%0A%20%20%20%20%20%20%20%20%20%20ball2.applyForce(wind)%3B%0A%20%20%20%20%20%20%20%20%20%20break%3B%0A%0A%0A%0A%7BIn%20Render%20Loop%7D%0A%0Aball2.applyForce(gravity)%3B%0Aball2.update()%3B%0Aball2.display(renderer)%3B%0Aball2.edgeCollision()%3B” message=”” highlight=”” provider=”manual”/]

 

Notice that we set ball2 to have a mass of 5, this is half of the original ball, so we should see a difference  between them now:

 

The wrapping effect is getting a little tired, let’s change it back to the bounce effect and see what we get:

[pastacode lang=”cpp” manual=”void%20mover%3A%3AedgeCollision()%0A%7B%0A%20%20%20%20if%20(%20(position.getX()%20%3E%3D%20SCREEN_WIDTH)%20%7C%7C%20(position.getX()%20%3C%3D%200)%20)%0A%20%20%20%20%20%20%20%20velocity.setX(velocity.getX()%20*%20-1)%3B%0A%0A%20%20%20%20if%20(%20(position.getY()%20%2B%20%3E%3D%20SCREEN_HEIGHT)%20%7C%7C%20(position.getY()%20%3C%3D%200)%20)%0A%20%20%20%20%20%20%20%20velocity.setY(velocity.getY()%20*%20-1)%3B%0A%7D” message=”” highlight=”” provider=”manual”/]

 

That doesn’t look very good, we should add a width and height variable to our mover object so we can offset our screen edge checking by their values so that ball doesn’t leave the screen, we can have the loadImage() function update those variables as well as add setter and getter functions to allow changing it later on, in addition we should also change the display() function to take the width and height into account so it will scale the image accordingly.

[pastacode lang=”cpp” manual=”void%20mover%3A%3Adisplay(SDL_Renderer*%20ren)%0A%7B%0A%20%20%20%20renderTexture(image%2C%20ren%2C%20position.getX()%2C%20position.getY()%2C%20width%2C%20height)%3B%0A%7D%0A%0Avoid%20mover%3A%3AloadImage(std%3A%3Astring%20imagePath%2C%20SDL_Renderer*%26%20ren)%0A%7B%0A%20%20%20%20%20%20%20%20image%20%3D%20loadTexture(imagePath%2Cren)%3B%0A%20%20%20%20%20%20%20%20SDL_QueryTexture(image%2C%20NULL%2C%20NULL%2C%20%26width%2C%20%26height)%3B%0A%7D” message=”Mover Update and Display” highlight=”” provider=”manual”/]

 

Now we should be able to get these movers bouncing a bit more naturally:

 

What’s more, we can now use the get and set functions we added for the width and the height to set the scale of the balls so that the lighter of the two appears to be smaller:

or even make one an ellipse:

We can also create an array of movers and give them random values:

As an aside, the array of movers has a few special things that need to be done to make it work:

[pastacode lang=”cpp” manual=”%7Bin%20main%20before%20render%20loop%7D%0A%0Amover%20balls%5B25%5D%3B%0A%0Afor(int%20i%3D0%3B%20i%3C25%3B%20i%2B%2B)%0A%7B%0A%20%20%20%20balls%5Bi%5D.mass%20%3D%20rand()%20%25%20100%20%2B%201%3B%0A%20%20%20%20balls%5Bi%5D.loadImage(%22Images%2Fball.png%22%2C%20renderer)%3B%0A%20%20%20%20balls%5Bi%5D.setHeight(balls%5Bi%5D.mass%20%2B%2025)%3B%0A%20%20%20%20balls%5Bi%5D.setWidth(balls%5Bi%5D.height)%3B%0A%7D%0A%0A%0A%0A%7BIn%20event%20handler%7D%0A%0Acase%20SDL_MOUSEBUTTONDOWN%3A%0Afor(int%20i%3D0%3B%20i%3C25%3B%20i%2B%2B)%0A%7B%0A%20%20%20%20balls%5Bi%5D.applyForce(wind)%3B%0A%7D%0A%0A%0A%0A%7Bin%20render%20loop%7D%0A%0Afor(int%20i%3D0%3B%20i%3C25%3B%20i%2B%2B)%0A%7B%0A%20%20%20%20std%3A%3Acout%20%3C%3C%20%22Iteration%20%3A%20%22%20%3C%3C%20i%20%3C%3C%20std%3A%3Aendl%3B%0A%0A%20%20%20%20vec2%20%0A%20%20%20%20balls%5Bi%5D.applyForce(gravity)%3B%0A%20%20%20%20balls%5Bi%5D.update()%3B%0A%20%20%20%20balls%5Bi%5D.display(renderer)%3B%0A%20%20%20%20balls%5Bi%5D.edgeCollision()%3B%0A%20%20%20%20std%3A%3Acout%20%3C%3C%20%22ball%20%22%20%3C%3C%20i%20%3C%3C%20%22acceleration%3A%20%22%20%3C%3C%20balls%5Bi%5D.acceleration.getMag()%20%3C%3C%20std%3A%3Aendl%3B%0A%7D” message=”” highlight=”” provider=”manual”/]

 

The astute observer might notice now that the lighter balls actually fall faster than the heavy balls in this case, showing that gravity is not pulling uniformly as it would in the real world. One way that we can address this is by moving where we are defining the gravitational constant to the for loop that is applying it and multiplying by the objects weight, that way the gravity is constant per-object. There is probably a more elegant way to tackle the gravity problem, but this suits our needs for now.

[pastacode lang=”cpp” manual=”%7Bin%20render%20loop%7D%0A%0Afor(int%20i%3D0%3B%20i%3C25%3B%20i%2B%2B)%0A%7B%0A%20%20%20%20std%3A%3Acout%20%3C%3C%20%22Iteration%20%3A%20%22%20%3C%3C%20i%20%3C%3C%20std%3A%3Aendl%3B%0A%0A%20%20%20%20vec2%20gravity(0%2CGRAV_CONSTANT*balls%5Bi%5D.mass)%3B%0A%20%20%20%20balls%5Bi%5D.applyForce(gravity)%3B%0A%20%20%20%20balls%5Bi%5D.update()%3B%0A%20%20%20%20balls%5Bi%5D.display(renderer)%3B%0A%20%20%20%20balls%5Bi%5D.edgeCollision()%3B%0A%20%20%20%20std%3A%3Acout%20%3C%3C%20%22ball%20%22%20%3C%3C%20i%20%3C%3C%20%22acceleration%3A%20%22%20%3C%3C%20balls%5Bi%5D.acceleration.getMag()%20%3C%3C%20std%3A%3Aendl%3B%0A%7D” message=”” highlight=”” provider=”manual”/]

 

And that’s all for today, next time I think we might look into moving the objects we’re creating from the stack to the heap using pointers and the new keyword and maybe a few more forces like friction.

Leave a Reply

Your email address will not be published. Required fields are marked *