Skip to content

Commit 964a2bd

Browse files
Merge pull request #44 from MonoGame/feature/moresprites
New articles plus updates
2 parents b6839df + 6a9ec58 commit 964a2bd

13 files changed

+575
-109
lines changed

articles/getting_to_know/howto/graphics/HowTo_Animate_Sprite.md

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -35,100 +35,7 @@ Save the spritesheet to your content project and name it "**AnimatedCharacter**"
3535

3636
2. Create a new class called `AnimatedTexture.cs` in your project and replace its contents with the following:
3737

38-
```csharp
39-
using Microsoft.Xna.Framework;
40-
using Microsoft.Xna.Framework.Content;
41-
using Microsoft.Xna.Framework.Graphics;
42-
43-
/// <summary>
44-
/// A helper class for handling animated textures.
45-
/// </summary>
46-
public class AnimatedTexture
47-
{
48-
private int frameCount;
49-
private Texture2D myTexture;
50-
private float timePerFrame;
51-
private int frame;
52-
private float totalElapsed;
53-
private bool isPaused;
54-
55-
public float Rotation, Scale, Depth;
56-
public Vector2 Origin;
57-
58-
public AnimatedTexture(Vector2 origin, float rotation, float scale, float depth)
59-
{
60-
this.Origin = origin;
61-
this.Rotation = rotation;
62-
this.Scale = scale;
63-
this.Depth = depth;
64-
}
65-
66-
public void Load(ContentManager content, string asset, int frameCount, int framesPerSec)
67-
{
68-
this.frameCount = frameCount;
69-
myTexture = content.Load<Texture2D>(asset);
70-
timePerFrame = (float)1 / framesPerSec;
71-
frame = 0;
72-
totalElapsed = 0;
73-
isPaused = false;
74-
}
75-
76-
public void UpdateFrame(float elapsed)
77-
{
78-
if (isPaused)
79-
return;
80-
totalElapsed += elapsed;
81-
if (totalElapsed > timePerFrame)
82-
{
83-
frame++;
84-
// Keep the Frame between 0 and the total frames, minus one.
85-
frame %= frameCount;
86-
totalElapsed -= timePerFrame;
87-
}
88-
}
89-
90-
public void DrawFrame(SpriteBatch batch, Vector2 screenPos)
91-
{
92-
DrawFrame(batch, frame, screenPos);
93-
}
94-
95-
public void DrawFrame(SpriteBatch batch, int frame, Vector2 screenPos)
96-
{
97-
int FrameWidth = myTexture.Width / frameCount;
98-
Rectangle sourcerect = new Rectangle(FrameWidth * frame, 0,
99-
FrameWidth, myTexture.Height);
100-
batch.Draw(myTexture, screenPos, sourcerect, Color.White,
101-
Rotation, Origin, Scale, SpriteEffects.None, Depth);
102-
}
103-
104-
public bool IsPaused
105-
{
106-
get { return isPaused; }
107-
}
108-
109-
public void Reset()
110-
{
111-
frame = 0;
112-
totalElapsed = 0f;
113-
}
114-
115-
public void Stop()
116-
{
117-
Pause();
118-
Reset();
119-
}
120-
121-
public void Play()
122-
{
123-
isPaused = false;
124-
}
125-
126-
public void Pause()
127-
{
128-
isPaused = true;
129-
}
130-
}
131-
```
38+
[!code-csharp[](files/AnimatedTexture.cs)]
13239

13340
3. In your game's constructor, create an instance of the **AnimatedTexture** class.
13441
This example uses `(0,0)` as the origin of the texture, `no rotation`, a scale of `2`, and a depth of `0.5`.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: Drawing a Masked Sprite over a Background
3+
description: Demonstrates how to draw a foreground and background sprite using the SpriteBatch class, where only part of the foreground sprite masks the background.
4+
requireMSLicense: true
5+
---
6+
7+
## Overview
8+
9+
In this example, you will draw a background texture, followed by another sprite on top of the background with its transparent elements not showing by using a [Blend State](xref:Microsoft.Xna.Framework.Graphics.BlendState) that supports alpha blending.
10+
11+
### End result
12+
13+
![The output of this tutorial](./images/HowTo_DrawSpriteBackground_Final.png)
14+
15+
## Requirements
16+
17+
The example assumes the texture you are loading contains multiple images, one for the background and one for the foreground ship texture.
18+
19+
- ![starfield](images/starfield.png)
20+
- ![ship texture](images/ship.png)
21+
22+
Save the textures to your content project and name it "**AnimatedCharacter**" (this name will used to reference it in the project).
23+
24+
> [!IMPORTANT]
25+
> The foreground sprite in this example must include masking information, e.g. a PNG or DDS file that supports transparency / an alpha channel.
26+
27+
## Drawing a Foreground and Background Sprite
28+
29+
1. Follow the steps of [How To: Draw a Sprite](HowTo_Draw_A_Sprite.md).
30+
A good first step to understanding the loading and drawing of textures and setting up your project.
31+
32+
1. Add some variables and update the **LoadContent** method to load and initialize the content.
33+
34+
```csharp
35+
// Position of foreground sprite on screen
36+
private Vector2 ViperPos;
37+
38+
// The texture for the ship
39+
private Texture2D shipTexture;
40+
41+
// The texture for the background
42+
private Texture2D starTexture;
43+
44+
protected override void LoadContent()
45+
{
46+
// Create a new SpriteBatch, which can be used to draw textures.
47+
spriteBatch = new SpriteBatch(GraphicsDevice);
48+
49+
starTexture = Content.Load<Texture2D>("starfield");
50+
shipTexture = Content.Load<Texture2D>("ship");
51+
Viewport viewport = graphics.GraphicsDevice.Viewport;
52+
53+
ViperPos.X = viewport.Width / 2;
54+
ViperPos.Y = viewport.Height - 100;
55+
}
56+
```
57+
58+
1. In [Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_) method of your game class, call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) for the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch).
59+
60+
1. Specify [BlendState.Opaque](xref:Microsoft.Xna.Framework.Graphics.BlendState).
61+
62+
> [!NOTE]
63+
> This will tell the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) to ignore alpha color values when drawing sprites. By default, the z-order of sprites is the order in which they are drawn.
64+
65+
1. Call the [Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) method, passing in the `starTexture`. Then call [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End).
66+
67+
```csharp
68+
public override void Draw (GameTime game)
69+
{
70+
GraphicsDevice.Clear(Color.CornflowerBlue);
71+
72+
_spriteBatch.Begin(blendState: BlendState.Opaque);
73+
_spriteBatch.Draw (starTexture);
74+
_spriteBatch.End();
75+
}
76+
```
77+
78+
1. After this code, call [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) for the [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) again. This time, specify [BlendState.AlphaBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState).
79+
80+
This will cause pixels on the sprite with an alpha value less than 255 to become progressively transparent based on the magnitude of the alpha value. An alpha of 0 will make the pixel completely transparent.
81+
82+
> [!IMPORTANT]
83+
> Calling [SpriteBatch.Begin](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Begin_Microsoft_Xna_Framework_Graphics_SpriteSortMode_Microsoft_Xna_Framework_Graphics_BlendState_Microsoft_Xna_Framework_Graphics_SamplerState_Microsoft_Xna_Framework_Graphics_DepthStencilState_Microsoft_Xna_Framework_Graphics_RasterizerState_Microsoft_Xna_Framework_Graphics_Effect_System_Nullable_Microsoft_Xna_Framework_Matrix__) with no parameters causes [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) to **default to [BlendState.AlphaBlend](xref:Microsoft.Xna.Framework.Graphics.BlendState)**.
84+
85+
1. Next in the [Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch) method, we draw the `shipTexture`, `ViperPos` with [Color.White](xref:Microsoft.Xna.Framework.Color), finishing off with a call to [SpriteBatch.End](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_End).
86+
87+
```csharp
88+
public override void Draw (GameTime game)
89+
{
90+
_spriteBatch.Begin(blendState: BlendState.Opaque);
91+
_spriteBatch.Draw (starTexture);
92+
_spriteBatch.End();
93+
94+
_spriteBatch.Begin(blendState: BlendState.AlphaBlend);
95+
_spriteBatch.Draw (shipTexture, ViperPos, Color.White);
96+
_spriteBatch.End();
97+
}
98+
```
99+
100+
The end result is a fixed / opaque background with a semi-transparent ship drawn on top for the player. You can of course experiment with layers / parallax transparent backgrounds behind the player too, the choice is up to you.
101+
102+
### Extra Credit
103+
104+
Try using this technique on top of the [How To Make A Scrolling Background](HowTo_Make_Scrolling_Background.md) guide for the beginnings of your very own space shooter :D
105+
106+
## See Also
107+
108+
- [Drawing a Sprite](HowTo_Draw_A_Sprite.md)
109+
- [How To Make A Scrolling Background](HowTo_Make_Scrolling_Background.md)
110+
111+
### Concepts
112+
113+
- [What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md)
114+
115+
### Reference
116+
117+
- [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch)
118+
- [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_)
119+
- [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D)
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Making a Scrolling Background
3+
description: Demonstrates how to draw a scrolling background sprite using the SpriteBatch class
4+
requireMSLicense: true
5+
---
6+
7+
## Overview
8+
9+
In this example, you will draw a texture to the screen and then animate it vertically by scrolling it upwards in a wrapping motion.
10+
11+
### End result
12+
13+
![The output of this tutorial](images/HowTo_ScrollBackground_Final.gif)
14+
15+
> [!NOTE]
16+
> Textures that scroll, especially over the screen background are best if they use seamless or tileable textures, [For Example](https://www.myfreetextures.com/seamless-textures/). Essentially, textures that wrap around the edges to look like a single texture when joined together.
17+
18+
## Requirements
19+
20+
The example assumes the texture you are loading contains multiple frames of the same size in a texture whose size is uniform (also known as a spritesheet), for example, the following spritesheet contains 8 Images of a character in different phases of motion, when player together it looks like it is animated.
21+
22+
![Starfield background](images/starfield.png)
23+
24+
Save the texture to your content project and name it "**Starfield**" (this name will used to reference it in the project).
25+
26+
> [!NOTE]
27+
> The sample also uses a class named **ScrollingBackground**, which is included with the sample below.
28+
>
29+
> The `ScrollingBackground.cs` is a helper to simplify the scrolling of a texture in the vertical direction. Feel free to modify it to work in different directions.
30+
31+
## Drawing a Scrolling Background Sprite
32+
33+
1. Follow the steps of [How To: Draw a Sprite](HowTo_Draw_A_Sprite.md).
34+
A good first step to understanding the loading and drawing of textures and setting up your project.
35+
36+
2. Create a new class called `ScrollingBackground.cs` in your project and replace its contents with the following:
37+
38+
[!code-csharp[](files/ScrollingBackground.cs)]
39+
40+
3. Load the background texture.
41+
42+
```csharp
43+
private ScrollingBackground myBackground;
44+
45+
protected override void LoadContent()
46+
{
47+
_spriteBatch = new SpriteBatch(GraphicsDevice);
48+
49+
// TODO: use this.Content to load your game content here
50+
myBackground = new ScrollingBackground();
51+
Texture2D background = Content.Load<Texture2D>("starfield");
52+
myBackground.Load(GraphicsDevice, background);
53+
}
54+
```
55+
56+
4. Determine the size of the background texture and the size of the screen.
57+
58+
The texture size is determined using the [Height](xref:Microsoft.Xna.Framework.Graphics.Texture2D.Height) and [Width](xref:Microsoft.Xna.Framework.Graphics.Texture2D.Width) properties, and the screen size is determined using the [Viewport](xref:Microsoft.Xna.Framework.Graphics.GraphicsDevice.Viewport) property on the graphics device.
59+
60+
5. Using the texture and screen information, set the origin of the texture to the center of the top edge of the texture, and the initial screen position to the center of the screen.
61+
62+
```csharp
63+
// class ScrollingBackground
64+
private Vector2 screenpos, origin, texturesize;
65+
private Texture2D mytexture;
66+
private int screenheight;
67+
68+
public void Load(GraphicsDevice device, Texture2D backgroundTexture)
69+
{
70+
mytexture = backgroundTexture;
71+
screenheight = device.Viewport.Height;
72+
int screenwidth = device.Viewport.Width;
73+
74+
// Set the origin so that we're drawing from the
75+
// center of the top edge.
76+
origin = new Vector2(mytexture.Width / 2, 0);
77+
78+
// Set the screen position to the center of the screen.
79+
screenpos = new Vector2(screenwidth / 2, screenheight / 2);
80+
81+
// Offset to draw the second texture, when necessary.
82+
texturesize = new Vector2(0, mytexture.Height);
83+
}
84+
```
85+
86+
6. To scroll the background, change the screen position of the background texture in your [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_) method.
87+
88+
> [!NOTE]
89+
> This example moves the background down 100 pixels per second by increasing the screen position's Y value.
90+
91+
```csharp
92+
private float scrollingSpeed = 100;
93+
94+
protected override void Update(GameTime gameTime)
95+
{
96+
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
97+
Exit();
98+
99+
// The time since Update was called last.
100+
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
101+
102+
// TODO: Add your game logic here.
103+
myBackground.Update(elapsed * scrollingSpeed);
104+
105+
base.Update(gameTime);
106+
}
107+
```
108+
109+
The `Y` value is kept no larger than the texture height, making the background scroll from the bottom of the screen back to the top.
110+
111+
```csharp
112+
// class ScrollingBackground
113+
public void Update(float deltaY)
114+
{
115+
screenpos.Y += deltaY;
116+
screenpos.Y %= mytexture.Height;
117+
}
118+
```
119+
120+
7. Draw the background using the origin and screen position calculated in [Game.LoadContent](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_LoadContent) and [Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_).
121+
122+
```csharp
123+
protected override void Draw(GameTime gameTime)
124+
{
125+
GraphicsDevice.Clear(Color.CornflowerBlue);
126+
127+
_spriteBatch.Begin();
128+
myBackground.Draw(_spriteBatch, Color.White);
129+
_spriteBatch.End();
130+
131+
base.Draw(gameTime);
132+
}
133+
```
134+
135+
In case the texture does not cover the screen, another texture is drawn. This subtracts the texture height from the screen position using the **texturesize** vector created at load time. This creates the illusion of a loop.
136+
137+
```csharp
138+
// class ScrollingBackground
139+
public void Draw(SpriteBatch batch, Color color)
140+
{
141+
// Draw the texture, if it is still onscreen.
142+
if (screenpos.Y < screenheight)
143+
{
144+
batch.Draw(mytexture, screenpos, null,
145+
color, 0, origin, 1, SpriteEffects.None, 0f);
146+
}
147+
148+
// Draw the texture a second time, behind the first,
149+
// to create the scrolling illusion.
150+
batch.Draw(mytexture, screenpos - texturesize, null,
151+
color, 0, origin, 1, SpriteEffects.None, 0f);
152+
}
153+
```
154+
155+
## See Also
156+
157+
- [Drawing a Sprite](HowTo_Draw_A_Sprite.md)
158+
- [How to animate a sprite](HowTo_Animate_Sprite.md)
159+
- [Drawing a Masked Sprite over a Background](HowTo_Draw_Sprite_Background.md)
160+
161+
### Concepts
162+
163+
- [What Is a Sprite?](../../whatis/graphics/WhatIs_Sprite.md)
164+
165+
### Reference
166+
167+
- [SpriteBatch](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch)
168+
- [SpriteBatch.Draw](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch#Microsoft_Xna_Framework_Graphics_SpriteBatch_Draw_Microsoft_Xna_Framework_Graphics_Texture2D_Microsoft_Xna_Framework_Vector2_Microsoft_Xna_Framework_Color_)
169+
- [Texture2D](xref:Microsoft.Xna.Framework.Graphics.Texture2D)

0 commit comments

Comments
 (0)