When you first create a new project, a SpriteBatch object is declared and instantiated in the LoadContent
method. This is the main object used to render 2D graphics, and
virtually all games (even full 3D games) need to render 2D graphics at
some time. This object can be used to draw a single sprite like you
just did, or it can draw many sprites with a wide variety of options
that can be used to control exactly how you want your images drawn.
Drawing
First, let’s look at the Draw method, which is the one that actually got the picture on to the screen:
spriteBatch.Draw(texture, GraphicsDevice.Viewport.Bounds, Color.White);
This is only one overload of the Draw
method (there are seven total), but it is one of the simplest. The
first parameter is obvious—what texture do you want to draw? In the
project earlier, you loaded your image into this texture, so that is
what is rendered on the screen. This is one of the two parameters
required and it is in every overload for the Draw method.
The other nonoptional parameter to Draw
is the last one in the call, the color. This is the color your image is
“tinted” with (in actuality, it is the color of each pixel in your
image multiplied by the color specified, which is discussed later).
Passing in Color.White, as done here, causes your image to appear with the same colors as the original image, whereas passing in Color.Black causes the image to be replaced by solid black. If you change this to Color.Red, and you will notice that the image is now tinted red. In many cases, you can simply leave this Color.White.
The middle parameter in the Draw
call is the destination rectangle. As the name implies, it is the
rectangle where you want the drawing to occur (hence, the destination).
This rectangle is specified in screen coordinates where 0,0 is the
upper left corner of the rendering area, which in this case is the
window. When in full-screen mode, it is the upper left corner of the
monitor as mentioned earlier. The destination rectangle is useful
because if the image you are drawing isn’t the exact size of the
rectangle you’re drawing, it automatically stretches or shrinks to fit
exactly in that area.
In this case, the destination rectangle is calculated using a property of the GraphicsDevice object. The GraphicsDevice is the object that encapsulates the portions of the graphics card you can control, whereas the Viewport property contains information about where the device renders to on the screen. You used the Bounds
property because it returns the rectangle that encompasses the entire
rendering area, which is why the image you chose covers the entire
window, regardless of what size it was originally when it was loaded.
Before we look at other
methods used on the sprite batch, let’s look at the more overloads for
drawing images on the screen. In your project, right-click the content
project and add a reference to cat.jpg,
which you can find in the downloadable examples. Anyone familiar with
many of the samples that are available for Game Studio realizes that
cats appear all over the samples. This one, however, is a different
cat—it is my own. He is a little bit camera shy though, so please be
gentle with him.
Change the code that loaded the previous image to load the cat image, as the following:
texture = Content.Load<Texture2D>("cat");
This image is 256×256 pixels,
and your window by default is 800×480 pixels. Running the project right
now shows you a stretched version of the cat covering the entire
rendering surface, much like you saw earlier. Now change the Draw method to the following:
spriteBatch.Draw(texture, Vector2.Zero, Color.White);
Notice that a different parameter of type Vector2 replaced the destination rectangle. Like the name implies, Vector2.Zero
returns a vector with both the X and Y value as zero. The new
parameter, called the position, tells the sprite batch where to begin
drawing, so the upper left pixel of the image draws at the spot
specified by this parameter (in this case 0,0, or the upper, left
corner of the rendering area).
Note
The Vector2 class is a value type used to store two-dimensional coordinates, namely an X and Y value.
Using this overload and
specifying a position means that no stretching of the image occurs; it
renders whatever size the source image actually is. Run the application
and notice that the cat is now in the upper, left corner of the window,
but there are large areas of empty background everywhere else. To
render the cat in the center of the window, modify the Draw call as follows:
spriteBatch.Draw(texture,
new Vector2((GraphicsDevice.Viewport.Width-texture.Width)/2,
(GraphicsDevice.Viewport.Height - texture.Height) / 2), Color.White);
This combines information from the Viewport, along with information about the texture to properly position the image in the center of the window as in Figure 1. It still isn’t exciting though because it is a static image that doesn’t do anything.
Notice that the two
overloads so far do remarkably similar things. They both draw an image
to a particular place on the screen of a particular size. The only
difference between them is the one with the destination rectangle
requires you to specify a width, a height, and a position. As a matter
of fact, these three lines produce the same results.
spriteBatch.Draw(texture, Vector2.Zero, Color.White);
spriteBatch.Draw(texture, new Rectangle(0,
0, texture.Width, texture.Height), Color.White);