Adding clouds, a tree, and a buzzing bee
First we will add a tree. This is going to be really easy. The reason it's easy is because the tree doesn't move. We will use exactly the same procedure that we used in the previous chapter when we drew the background.
Preparing the tree
Add the following highlighted code. Notice the un-highlighted code, which is the code that we have already written. This should help you identify that the new code should be typed immediately after we set the position of the background, but before the start of the main game loop. We will recap what is actually going on in the new code after you have added it:
int main()
{
// Create a video mode object
VideoMode vm(1920, 1080);
// Create and open a window for the game
RenderWindow window(vm, "Timber!!!", Style::Fullscreen);
// Create a texture to hold a graphic on the GPU
Texture textureBackground;
// Load a graphic into the texture
textureBackground.loadFromFile("graphics/background.png");
// Create a sprite
Sprite spriteBackground;
// Attach the texture to the sprite
spriteBackground.setTexture(textureBackground);
// Set the spriteBackground to cover the screen
spriteBackground.setPosition(0, 0);
// Make a tree sprite Texture textureTree; textureTree.loadFromFile("graphics/tree.png"); Sprite spriteTree; spriteTree.setTexture(textureTree); spriteTree.setPosition(810, 0);
while (window.isOpen())
{
The five lines of code (excluding the comment) that we just added do the following:
- First, we create an object of the type
Texture
calledtextureTree
. - Next, we load a graphic into the texture from the
tree.png
graphics file. - Next, we declare an object of the type
Sprite
calledspriteTree
- Now, we associate
textureTree
withspriteTree
. Whenever we drawspriteTree
it will show thetextureTree
texture, which is a neat tree graphic. - Finally we set the position of the tree using the coordinates
810
on the x axis and 0 on the y axis.
Let's move on to the bee object, which is handled in an almost identical manner.
Preparing the bee
The difference between this next code and the tree code is small but important. As the bee needs to move, we also declare two bee-related variables. Add the highlighted code in the place shown, and see if you can work out how we might use the variables beeActive
and beeSpeed
:
// Make a tree sprite
Texture textureTree;
textureTree.loadFromFile("graphics/tree.png");
Sprite spriteTree;
spriteTree.setTexture(textureTree);
spriteTree.setPosition(810, 0);
// Prepare the bee Texture textureBee; textureBee.loadFromFile("graphics/bee.png"); Sprite spriteBee; spriteBee.setTexture(textureBee); spriteBee.setPosition(0, 800); // Is the bee currently moving? bool beeActive = false; // How fast can the bee fly float beeSpeed = 0.0f;
while (window.isOpen())
{
We create a bee in exactly the same way we created a background and a tree. We use a Texture
and a Sprite
, and associate the two. Note that in the previous bee code there was some new code we haven't seen before. There is a bool
variable for determining whether or not the bee is active. Remember that a bool
variable can be either true
or false
. We initialize beeActive
to false
, for now.
Next, we declare a new float
variable called beeSpeed
. This will hold the speed, in pixels per second, at which our bee will fly across the screen.
Soon we will see how we use these two new variables to move the bee. Before we do, let's set up some clouds in an almost identical manner.
Preparing the clouds
Add the highlighted code shown next. Study the new code and try and work out what it will do:
// Prepare the bee
Texture textureBee;
textureBee.loadFromFile("graphics/bee.png");
Sprite spriteBee;
spriteBee.setTexture(textureBee);
spriteBee.setPosition(0, 800);
// Is the bee currently moving?
bool beeActive = false;
// How fast can the bee fly
float beeSpeed = 0.0f;
// make 3 cloud sprites from 1 texture Texture textureCloud; // Load 1 new texture textureCloud.loadFromFile("graphics/cloud.png"); // 3 New sprites with the same texture Sprite spriteCloud1; Sprite spriteCloud2; Sprite spriteCloud3; spriteCloud1.setTexture(textureCloud); spriteCloud2.setTexture(textureCloud); spriteCloud3.setTexture(textureCloud); // Position the clouds off screen spriteCloud1.setPosition(0, 0); spriteCloud2.setPosition(0, 250); spriteCloud3.setPosition(0, 500); // Are the clouds currently on screen? bool cloud1Active = false; bool cloud2Active = false; bool cloud3Active = false; // How fast is each cloud? float cloud1Speed = 0.0f; float cloud2Speed = 0.0f; float cloud3Speed = 0.0f;
while (window.isOpen())
{
The only thing about the code we have just added that might seem a little odd is that we have only one object of the type Texture
. It's completely normal for multiple Sprite
objects to share a texture. Once a Texture
is stored in the GPU memory it can be associated with a Sprite
object very quickly. It is only the initial loading of the graphic in the loadFromFile
code that is a relatively slow operation. Of course, if we wanted three different-shaped clouds then we would need three textures.
Apart from the minor texture issue, the code we have just added is nothing new compared to the bee. The only difference is that there are three cloud sprites, three bool
variables to determine if each cloud is active and three float
variables to hold the speed for each cloud.
Drawing the tree, the bee, and the clouds
Finally we can draw them all onto the screen by adding this highlighted code in the drawing section:
/*
****************************************
Draw the scene
****************************************
*/
// Clear everything from the last run frame
window.clear();
// Draw our game scene here
window.draw(spriteBackground);
// Draw the clouds window.draw(spriteCloud1); window.draw(spriteCloud2); window.draw(spriteCloud3); // Draw the tree window.draw(spriteTree); // Draw the insect window.draw(spriteBee);
// Show everything we just drew
window.display();
Drawing the three clouds, the bee, and the tree is done in exactly the same way that the background was drawn. Notice, however, the order in which we draw the different objects to the screen. We must draw all the graphics after the background or they will be covered, and we must draw the clouds before the tree or they will look a bit odd drifting in front of the tree. The bee would look OK either in front or behind the tree. I opted to draw the bee in front of the tree so that it can try and distract our lumberjack, a bit like a real bee might.
Run Timber!!! and gaze in awe at the tree, three clouds, and a bee, which don't do anything! They look like they are lining up for a race, where the bee goes backwards.
Using what we know about operators, we could try and move the graphics around that we have just added, but there are a couple of problems. Firstly, real clouds and bees move in a non-uniform manner. They don't have a set speed or location. Although their location and speed are determined by factors such as wind speed or how much of a hurry the bee might be in, to the casual observer the path they take, and their speed, appear random.