IWKS 3400 Lab 3 1 JK Bennett

Size: px
Start display at page:

Download "IWKS 3400 Lab 3 1 JK Bennett"

Transcription

1 IWKS 3400 Lab 3 1 JK Bennett This lab consists of four parts, each of which demonstrates an aspect of 2D game development. Each part adds functionality. You will first just put a sprite on the screen; then you will make the sprite move, add another sprite, and add collision detection; then you will add user input; finally, you will add sound. By the end of this lab, you will be ready to start creating 2D games. It s probably a good idea to read through the entire lab before starting. This write-up is long, but don t be intimidated by the length, it is detailed in an effort to ensure that everything is explained fully. Feedback on whether this goal has been accomplished is most welcome. First, a few terms. Lobão s definitions are quite good: Sprite: A sprite is a 2D image that can be manipulated independently from the rest of a game scene. This term is used often to describe the image displayed or the class used by the game to display the image (which includes properties such as velocity, position, width, height, and so on). Because the computer always draws the 2D image as a rectangle, a sprite usually encompasses transparent areas so it provides the illusion of a nonrectangular drawing. The term animated sprite refers to a sprite whose images change at predetermined time intervals, to generate the illusion of movement (such as a walking man or a spinning wheel). Texture: A texture refers to a 2D image loaded in a 3D model, which can be seen from any point of view, depending on the position of the model and the position of the camera used to render the scene. You can use textures to help create the illusion of a highly detailed model, when a detailed image is mapped over a simple 3D model. Billboard: In the 3D world, a billboard is a texture that is mapped to a special plane that is always perpendicular to the camera axis. Using 3D-like images in billboarding is an effective technique for creating game components-such as a tree, a road sign, or a torch in the wall-without the need to create highly detailed models. This allows more detailed scenes with the same rendering processing power. Background: A 2D game scene is usually composed of a background image with many sprites displayed over it. When this background is a moving image, you have a scrolling background, which is the main characteristic in games called scrollers. It s also worth mentioning parallax scrolling, a special scrolling technique in which the 2D game has more than one scrolling background with different scrolling speeds, which provides the illusion of a 3D environment. For example, while the player character moves to the left, trees and bushes behind it move at the player s speed, mountains far away from the character move slowly, and clouds in the sky move very slowly. Tiles: These are small images used as tiles to compose a bigger image, usually a level background. For example, platform games typically use tiles to create different platform levels based on the same basic 1 The lab is derived in part from Chapter 2 of Beginning XNA 3.0 Game Programming, Lobão et al., Apress, 2009, and in part from Chapter 13 of XNA Game Studio 4.0 Programming, Miller and Johnson, Addison Wesley,

2 images. The term tiled map is often used to describe game levels created with tiles, and sometimes to describe files with the information needed to create such levels based on tiles. A classic example of the use of tiles is for building a terrain. Role-playing games (RPGs) usually provide a level editor application that lets you build the levels by picking different tiles from the application and joining them together. Screen Coordinates In graphs with which you are probably familiar, the origin is at the lower left, and the x and y axes increase going right and up, respectively. For historical reasons (having to do with how cathode ray tubes work), the origin of our screen coordinates is at the upper left, and the x and y axes increase going right and down, respectively. In addition, screen coordinates are directly related to screen resolution. For example, if the monitor (or window) is configured to a resolution of 800 x 600, the x axis will have 800 pixels (each pixel is an independent point on the screen) and the y axis will have 600 pixels. PART 1. Drawing a Sprite Using MonoGame We will now create a simple example in MonoGame to display a sprite in a given position on the screen. Begin by create a new MonoGame Windows Project. Use Lab3_Mono as the project name (which will also be the name of the project namespace that is created). Be sure to place the project directory on the desktop. Creating the Sprite Class To group the sprite image and some associated properties (such as position, size, and velocity), we will create a simple class, which will be extended as we explore new concepts in this lab. To create the class, right-click the project name (not the solution name) in the Solution Explorer window and choose Add New Item (you can also just Add class). In the New Item dialog box, choose Class as the item type and name it clssprite.cs. Make your clssprite.cs file look like this: using Microsoft.Xna.Framework.Graphics; // for Texture2D using Microsoft.Xna.Framework; // for Vector2 namespace Lab3_Mono class clssprite public Texture2D texture get; set; // sprite texture, read-only property public Vector2 position get; set; // sprite position on screen public Vector2 size get; set; // sprite size in pixels public clssprite(texture2d newtexture, Vector2 newposition, Vector2 newsize) texture = newtexture; position = newposition; size = newsize; 2

3 public void Draw(SpriteBatch spritebatch) spritebatch.draw(texture, position, Color.White); Note the use of C# properties in the definition of the clssprite class. We learned about properties in Lab 2. Properties are also explained in Chapter 19 of Whitaker; you should review that material before proceeding (this will explain the get-set usage, which is different from what you might have seen in other programming languages). The three properties are: 1. texture: Stores the sprite image using MonoGame s Texture2D class. The MonoGame Sprite class has many properties and methods to help deal with textures. The texture is stored in this class as a 2D grid of what are sometimes called texels. Similar to pixels, which are the smallest unit that can be drawn on the screen, texels are the smallest unit that can be stored by the graphics processing unit (GPU); they include color and transparency values. 2. size: Stores the sprite s size using MonoGame s Vector2 class. This class has two properties, X and Y, which are used to store the image width and height. 3. position: Stores the position of the sprite using MonoGame s Vector2 class. The X and Y properties of the class store the screen coordinates for upper left corner of the sprite. For now, this class stores only the sprite properties, and does not include any methods. Adding the Sprite Image The first step in creating a sprite is to include a new image in your game, so you can access it through the MonoGame Content Project. You may choose any image you would like to use for this example, as long as it is in one of the formats supported by MonoGame (use.png and.bmp for now; jpg is problematic when working with transparent areas). The easiest course of action is to click here and then save the enclosed bitmap on your desktop as ball.bmp. This image is a 64 x 64 pixel image of a blue ball with a magenta background, which was created with Windows Paint. 2 To add your image to your project: First, from outside of Visual Studio, copy the ball.bmp file to your project s Content directory. Then, inside Visual Studio, open the project s Content folder in the Solution Explorer window, and double-click on Content.mgcb. This will open the MonoGame Content Pipeline Tool, as shown below: 2 MonoGame allows you to create transparent sections in your sprite in two ways. You can use an advanced image editor, such as Photoshop, GIMP ( ), or Paint.NET ( ) to create image files with transparent areas. Alternatively, you can simply color the areas you do not want to show with magenta (the default color used to represent transparency - this can be changed inside of your project if needed). In our example, the background of the ball image will not be drawn. When creating images with magenta areas in Windows Paint, do not save them in JPG format, as this format does not preserve the original colors when saving. 3

4 Right-click on the Content icon in the tool s Project window, select Add Existing Item, then select ball.bmp. Finally, save the changes to the Content Pipeline (File Save) If you want to make sure that the image you just loaded can be processed by MonoGame, right-click on ball.bmp and select Rebuild. If you get a green check, you are good to go. After including the image in the game solution, click on the image name in the Content Pipeline tool Project window. You will see the recently included image s Properties displayed in the window below. The Properties window presents information that the content importer and the content processor used for this content. Look under Processor Parameters, and under ColorKeyColor, magenta will be displayed. Note also that ColorKeyEnabled is set to true. This tells you that any magenta areas in the image will be transparent. 4

5 Drawing the Sprite on the Screen Once we have an image, the next step is to include the code for drawing it on the screen. To do this, we will need a SpriteBatch (a MonoGame class that draws sprites on the screen) and the texture that will be used as the sprite image (in this case, you will load this texture into your clssprite class). There are (at least) two ways to accomplish this particular task. In this case, we can read the texture from the clssprite class and draw it in the Draw method of the Game1 class, or we can extend the clssprite class to create a Draw method that will draw the sprite. In this lab, we went with Option 2, by including the following new method in the clssprite class (this code was already entered): public void Draw(SpriteBatch spritebatch) spritebatch.draw(texture, position, Color.White); The Draw method has many overloads, which allow you to draw only part of the original texture, to scale or rotate the image, and so on. Here, you are using the simplest one, which receives only three arguments: the texture to draw, the position in screen coordinates (both are already properties of clssprite class), and a color channel modulation used to tint the image. Using any color other than white in this last parameter draws the image with a composition of its original colors and the color tone. 3 Now let s make the necessary modifications to the Game1 class. Your new Windows Game project has already created a SpriteBatch object, so we will begin by creating a clssprite object in the Game1 class. This definition has to be included at the beginning of the class, just after where the device and SpriteBatch objects that were automatically created. Of course, these objects need valid values before they can be used. This is accomplished in the LoadContent method, which is where we include graphics initialization. Because the project already creates the SpriteBatch object, all we need to do is create the clssprite object instance. The Game1.cs code to accomplish all of these objectives is as follows (additions are shown in yellow; only the first part of Game1.cs is relevant at this point): using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace Lab3_Mono /// This is the main type for your game. public class Game1 : Game GraphicsDeviceManager graphics; 3 Note: For information about the other Draw method overloads, see the MSDN documentation for the XNA 4.0 SpriteBatch (which provides correct information, since MonoGame is an open-source implementation of XNA 4.0. Draw method ( ). For example, if you want to rotate your image, look for the overloads that expect the rotation parameter; or use the SpriteEffects parameter, if you just want to flip the sprite horizontally or vertically. Overloads with a scale parameter allow you to change the size of the sprite, which can be used in many ways, such as to create a zoom effect. 5

6 SpriteBatch spritebatch; clssprite mysprite1; public Game1() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // changing the back buffer size changes the window size (in windowed mode) graphics.preferredbackbufferwidth = 700; graphics.preferredbackbufferheight = 500; /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.initialize will enumerate through any components /// and initialize them as well. protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); /// LoadContent will be called once per game and is the place to load /// all of your content. protected override void LoadContent() // Create a new SpriteBatch, which can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f)); /// UnloadContent will be called once per game and is the place to unload /// game-specific content. protected override void UnloadContent() // TODO: Unload any non ContentManager content here /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Update(GameTime gametime) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); 6

7 // TODO: Add your update logic here base.update(gametime); /// This is called when the game should draw itself. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.CornflowerBlue); // Draw the sprite using Alpha Blend, which uses transparency information if available spritebatch.begin(); mysprite1.draw(spritebatch); spritebatch.end(); base.draw(gametime); Note that this code uses Vector2 (0f, 0f) to define a zeroed 2D vector, but you could also use the Vector2.Zero static property instead. MonoGame offers many such properties to improve code readability. Even though we included only a single code line (for creating the mysprite1object), many things are going on here. You created your sprite class by using the content manager to load the Texture2D based on the image asset name: ball. You also defined the sprite position as (0, 0), and decided on the sprite size: 64 pixels wide and 64 pixels tall. For the Sprite Batch s creation, we pass the graphics device as a parameter. This device (represented here by the GraphicsDevice variable) is your entry point to the graphics handling layer, and through it you perform all graphical operations. Here, you are informing the SpriteBatch which device it should use when drawing the sprites. In the next section, you will see how to use the device to change the program s window size. Drawing the Sprite We have also included code to draw the sprite using the SpriteBatch object that we created. You use the SpriteBatch, as its name suggests, to draw a batch of sprites, grouping one or more calls to its Draw method inside a block started by a call to the Begin method and closed by a call to the End method. The Begin method can also receive parameters that will be used when rendering every sprite in the block. A very interesting optional parameter (not used here) of the Begin method is transformmatrix, which receives a transformation matrix that will apply transformations (scale, rotation, or translation) to the entire batch of sprites being drawn. We will learn more about transformation matrices later in the semester. 7

8 Cleaning Up In most programming languages (those without built-in garbage collection like C#), it is a good programming practice to destroy everything you created when the program ends. We can also do this explicitly in C# (which might be appropriate if we had C++ code in our game, in addition to C# code, or if we were coding for a memory-limited device). To do this, you need to dispose of the texture of clssprite that was created in the LoadContent method. You do this in the UnloadContent method. If you wish to try this (you need not), the code to be added for disposing of the object follows: /// UnloadContent will be called once per game and is the place to unload /// all content. protected override void UnloadContent() // TODO: Unload any non ContentManager content here // Free the previously allocated resources mysprite1.texture.dispose(); spritebatch.dispose(); Note that we could also create a Dispose method in the clssprite class to dispose of the texture, and call that method from the UnloadContent method. This would represent a more object-oriented coding practice, and would be appropriate for a more complex game. Game Logic The default Game1.cs game code created by MonoGame includes a place to insert game logic. We won t touch this code for now, but you should see the following code in the file: /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Update(GameTime gametime) // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.exit(); // TODO: Add your update logic here base.update(gametime); Compile (Build Build Solution) and run (Debug Begin Debugging) the program. Doing so should produce the following result on the screen (a window with the ball sprite positioned in the upper-left corner [the (0, 0) position] of the program window). 8

9 If for some reason your code is not working, here are complete copies of clssprite.cs and Game1.cs at this point in the lab. TASK: Compile and run your code. Go through program.cs, Game1.cs, and clssprite.cs and insert comments explaining every interesting line of code. If you like, you can use /* */ comment notation to distinguish your comments from the comments inserted by MonoGame. It is perfectly acceptable, and in fact encouraged, for you to work together on this portion of the lab. Changing the Window Size If you want to change the size of the window (for example, to a 700 x 500 window), you can inform the device about the new dimensions (through the graphics object) in the Game1 constructor, by including the following code lines just after the creation of the graphics object: public Game1() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; //changing the back buffer size changes the window size (in windowed mode) graphics.preferredbackbufferwidth = 700; graphics.preferredbackbufferheight = 500; Make this change and observe the result. These lines change the backbuffer width and height, which is reflected in the window size, because we are working in windowed mode. This backbuffer is part of the technique used to draw the game scene without image flickering, called double buffering. With double buffering, two buffers are used to draw and display the game scene. While the first one is presented to the player, the second, invisible one (the backbuffer) is being drawn. After the drawing is finished, the backbuffer content is moved to the screen, so the player doesn t see only part of the scene if it takes too long to be drawn (the bad visual effect known as flickering). Fortunately, we don t need to worry about such details, because MonoGame hides this complexity. But now you know why the property is called PreferredBackBufferWidth, instead of something like PreferredWindowsWidth. 9

10 Save a copy of your work this far, e.g., by saving a copy of the project, and creating a zip file of the project contents named something like <YourName>-Lab3-Part1.zip. PART 2. In this part of the lab we are going to add code that puts two balls on the screen, sets them in motion, and performs collision detection, so that the balls bounce off the walls, and off one another. Moving the Sprite on the Screen Because we work directly with screen coordinates when creating 2D games, moving a sprite is simple. All we need to do is draw the sprite in a different position. By incrementing the x coordinate of the sprite position, the sprite moves to the right; by decrementing the x coordinate, the sprite moves to the left. If we want to move the sprite down on the screen, we need to increment the y coordinate. We move the sprite up by decrementing the y coordinate. (Recall that the (0, 0) point in screen coordinates is the upper-left corner of the window.) MonoGame provides a specific place to do the game calculations: the Update overridable method. We can move the sprite by simply adding one line in the code, incrementing the X position of the sprite, according to the following line of code: mysprite1.position.x += 1; Because we use the sprite s position property when rendering the sprite in the Draw method, by including this line, we will see the sprite moving across the window, to the right, until it disappears from the screen. To create a more interesting game-like sprite, let s do something a little more sophisticated. First, we will create a new property in the clssprite class, velocity, that defines the sprite velocity on both the x and y axes. Then we will modify the class constructor to receive and store the screen coordinates, so that we can include a method that moves the sprite according to the given velocity. We will keep the sprite from moving off the screen by detecting when it reaches the edge of our window. To do this, the sprite needs to know the screen size so it can check the sprite s position with respect to the screen. We will modify the clssprite constructor to pass this information when the sprite is created (there are of course other ways to do this, but this one is easy). Modify the Game1.cs code as follows: mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); Modify the clssprite code as follows: class clssprite public Texture2D texture get; set; // sprite texture, read-only property public Vector2 position get; set; // sprite position on screen public Vector2 size get; set; // sprite size in pixels public Vector2 velocity get; set; // sprite velocity private Vector2 screensize get; set; // screen size public clssprite(texture2d newtexture, Vector2 newposition, Vector2 newsize, int ScreenWidth, int ScreenHeight) 10

11 texture = newtexture; position = newposition; size = newsize; screensize = new Vector2(ScreenWidth, ScreenHeight); We will set our sprite s velocity to (X,Y) (recall that velocity is a vector) in the LoadContent method, after the sprite-creation code, thus informing the sprite that it should move X pixels per update on the x axis, and Y pixels per update on the y axis. This way, the sprite will move across the screen. We need to create a method, let s call it Move, in the clssprite class that moves the sprite according to the sprite velocity, while respecting the screen boundaries. This function will check to see if the sprite is impinging on a screen boundary, and if so, invert the X or Y velocity component, as appropriate (why does this work?). The code for this method is as follows: public void Move() // if we ll move out of the screen, invert velocity // checking right boundary if (position.x + size.x + velocity.x > screensize.x) velocity = new Vector2(-velocity.X, velocity.y); // checking bottom boundary if (position.y + size.y + velocity.y > screensize.y) velocity = new Vector2(velocity.X, -velocity.y); // checking left boundary if (position.x + velocity.x < 0) velocity = new Vector2(-velocity.X, velocity.y); // checking top boundary if (position.y + velocity.y < 0) velocity = new Vector2(velocity.X, -velocity.y); // since we adjusted the velocity, just add it to the current position position += velocity; Checking for left and top screen boundaries is a direct test, because the sprite position is given by its upper-left corner. However, when checking if the sprite will leave the screen on the right, we must add the sprite width to the sprite s X position to make the sprite bounce with its right corner, or it would leave the screen before bouncing back. Similarly, when checking if the sprite is leaving through the bottom of the screen, we must add the sprite height to its Y position so the sprite will bounce with its bottom edge. Study (but do not yet compile and run) this code until it makes sense. In particular, why is the velocity component added to the position and size component before comparing with screen dimensions? Hint: the sprite is moving while we are making the comparison. Finally, the Update method of the Game1 class has to be modified to call the new Move method, as follows: // Allows the game to exit... // Move the sprite mysprite1.move(); 11

12 Coding for Collision Detection Making the sprite bounce on the window borders is already a simple collision-detection test, but in 2D games, we often want to test for collisions between sprites. There are many collision-detection algorithms for 2D and 3D applications. We will use a simple and reliable algorithm known as the Bounding Box Algorithm. Basically, the algorithm assumes that all sprites are composed of one or more rectangles. If the rectangles of two sprites overlap, the sprites are said to have collided. An easy way to implement the bounding-box test is simply to check if the x,y position of the upper-bound corner in the first box (which wraps the first sprite we want to test) is inside the second box (which wraps the second sprite to test). In other words, we check whether the X and Y values of the box being tested are less than or equal to the corresponding X and Y values of the other box, plus the width of the other box. We will implement this test in the clssprite class, as a method (named Collides) that will receive a sprite as a parameter, and test the received sprite against the current sprite. If there is a collision, the method will return true. The basic code for this test is as follows (add this code to clssprite): public bool Collides(clsSprite othersprite) // check if two sprites intersect return (this.position.x + this.size.x > othersprite.position.x && this.position.x < othersprite.position.x + othersprite.size.x && this.position.y + this.size.y > othersprite.position.y && this.position.y < othersprite.position.y + othersprite.size.y); In this code sample, two boxes will overlap only if both the x and y coordinates of the Rectangle 2 are within range (X to X+width, Y to Y+height) of Rectangle 1. Looking at the left figure below, we see that the y coordinate for Rectangle 2 is not greater than the y coordinate plus the height of Rectangle 1. This means the boxes might be colliding. But when we check the x coordinate of Rectangle 2, we see that it is greater than the x coordinate plus the width of Rectangle 1, which means that no collision is possible. X,Y Width X,Y Width Height Rect. 1 Rect. 1 X,Y Width Height X,Y Width Height Rect. 2 Height Rect. 2 Non-Overlapping Rectangles Overlapping Rectangles The right side of the figure illustrates a case in which we do have a collision. In this case, both the x and y coordinates of Rectangle 2 are within the range of Rectangle 1. In the code sample above, we also do the opposite test, checking if the x and y coordinates of Rectangle 1 are within the range of Rectangle 2. Because we are only checking one point, it is possible for Rectangle 2 s top-left corner to be outside Rectangle 1, but for the top-left corner of Rectangle 1 to be inside Rectangle 2. 12

13 Study these figures, and the code sample, until this all makes sense. Now we want to actually test two sprites colliding. To do that, we need two sprites. First, declare a second sprite: clssprite mysprite1; clssprite mysprite2; Then, in the LoadContent method, include the code for the sprite creation and set initial velocity: protected override void LoadContent() // Load a 2D texture sprite mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); mysprite2 = new clssprite(content.load<texture2d>("ball"), new Vector2(218f, 118f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); // Create a SpriteBatch to render the sprite spritebatch = new SpriteBatch(graphics.GraphicsDevice); // set the speed the sprites will move mysprite1.velocity = new Vector2(5, 5); mysprite2.velocity = new Vector2(3, -3); Now make the second sprite move (in Update): // Move the sprites mysprite1.move(); mysprite2.move(); Finally, in the Draw method, we include the code (do not add this code yet) for drawing the new sprite. The code for drawing the two sprites follows: protected override void Draw(GameTime gametime) graphics.graphicsdevice.clear(color.cornflowerblue); // TODO: Add your drawing code here spritebatch.begin(); mysprite1.draw(spritebatch); mysprite2.draw(spritebatch); spritebatch.end(); base.draw(gametime); We have now created two sprites, gave them an initial velocity, and perform the boundary and collision detection just described. We began by replicating the sprite-creation code for the second sprite, and including 13

14 the code for testing collisions in the Update method of the Game1 class. In the Update method, we included the code to move the first and second sprites, and to simulate bouncing off the walls. If you compile and run your code now, the balls should bounce off of the walls but not off of each other. Let s fix that. On a collision, we will store the velocity of mysprite1 in a new tempvelocity variable, set the velocity of mysprite1 to the velocity to mysprite2, and then set the velocity of mysprite2 to tempvelocity, thus changing the velocity between the sprites. Why is this a reasonable simulation of bouncing? We need to include a call to Collides in the Update method, and change the velocity between the sprites, as follows: if (mysprite1.collides(mysprite2)) Vector2 tempvelocity = mysprite1.velocity; mysprite1.velocity = mysprite2.velocity; mysprite2.velocity = tempvelocity; We could also simply invert the velocities, e.g.: if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; mysprite2.velocity *= -1; After you try the first method (later), come back and try the second. See which simulated collision behavior looks better to you. Since simple is usually better, we will go with Option 2. Compile and run this code and watch it for a while. Do you notice that sometimes the balls bounce when they have not yet touuched? This is because squares have corners, and if we are using a square to represent a circle, their corners will occasionally be the point of intersection. We will fix this issue next. Here is our code so far. Study this code until every line makes sense: Game1.cs using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace Lab3_Mono /// This is the main type for your game. public class Game1 : Game 14

15 GraphicsDeviceManager graphics; SpriteBatch spritebatch; clssprite mysprite1; clssprite mysprite2; public Game1() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // changing the back buffer size changes the window size (in windowed mode) graphics.preferredbackbufferwidth = 700; graphics.preferredbackbufferheight = 500; /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.initialize will enumerate through any components /// and initialize them as well. protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); /// LoadContent will be called once per game and is the place to load /// all of your content. protected override void LoadContent() // Create a new SpriteBatch, which can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); // Load a 2D texture sprite mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); mysprite2 = new clssprite(content.load<texture2d>("ball"), new Vector2(218f, 118f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); // Create a SpriteBatch to render the sprite spritebatch = new SpriteBatch(graphics.GraphicsDevice); // set the speed the sprites will move mysprite1.velocity = new Vector2(5, 5); mysprite2.velocity = new Vector2(3, -3); /// UnloadContent will be called once per game and is the place to unload /// game-specific content. protected override void UnloadContent() // TODO: Unload any non ContentManager content here 15

16 /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Update(GameTime gametime) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); // Move the sprites mysprite1.move(); mysprite2.move(); if (mysprite1.collides(mysprite2)) mysprite1.velocity *= -1; mysprite2.velocity *= -1; base.update(gametime); /// This is called when the game should draw itself. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.CornflowerBlue); // Draw the sprite using Alpha Blend, which uses transparency information if available spritebatch.begin(); mysprite1.draw(spritebatch); mysprite2.draw(spritebatch); spritebatch.end(); base.draw(gametime); clssprite.cs using Microsoft.Xna.Framework.Graphics; // for Texture2D using Microsoft.Xna.Framework; // for Vector2 namespace Lab3_Mono class clssprite public Texture2D texture get; set; public Vector2 position get; set; public Vector2 size get; set; // sprite texture, read-only property // sprite position on screen // sprite size in pixels 16

17 public Vector2 velocity get; set; private Vector2 screensize get; set; // sprite velocity // screen size public clssprite(texture2d newtexture, Vector2 newposition, Vector2 newsize, int ScreenWidth, int ScreenHeight) texture = newtexture; position = newposition; size = newsize; screensize = new Vector2(ScreenWidth, ScreenHeight); public void Move() // if we ll move out of the screen, invert velocity // checking right boundary if (position.x + size.x + velocity.x > screensize.x) velocity = new Vector2(-velocity.X, velocity.y); // checking bottom boundary if (position.y + size.y + velocity.y > screensize.y) velocity = new Vector2(velocity.X, -velocity.y); // checking left boundary if (position.x + velocity.x < 0) velocity = new Vector2(-velocity.X, velocity.y); // checking top boundary if (position.y + velocity.y < 0) velocity = new Vector2(velocity.X, -velocity.y); // since we adjusted the velocity, just add it to the current position position += velocity; public bool Collides(clsSprite othersprite) // check if two sprites intersect return (this.position.x + this.size.x > othersprite.position.x && this.position.x < othersprite.position.x + othersprite.size.x && this.position.y + this.size.y > othersprite.position.y && this.position.y < othersprite.position.y + othersprite.size.y); public void Draw(SpriteBatch spritebatch) spritebatch.draw(texture, position, Color.White); When you ran your code, you saw the sprites moving and bouncing against each other and against the window borders. However, if the boxes happen to collide diagonally, the circles will bounce before they really hit each other. You may have noticed that the sprites look like they are bouncing when they are still separated. There is an easy fix for this when we are dealing with circular objects. When testing for collisions between circles, we can simply check if the distance between the circle centers is less than the sum of their radii. If so, we have a collision. This provides a precise way to test for circle collisions. To change the clssprite code to 17

18 support collisions between two circle sprites, we first create two new read-only properties, center and radius, which are calculated according to the other sprite properties, as follows: class clssprite public Vector2 center get return position + (size / 2); // sprite center public float radius get return size.x / 2; // sprite radius We then add a CircleCollides method to clssprite, as follows: public bool CircleCollides(clsSprite othersprite) // Check if two circle sprites collided return (Vector2.Distance(this.center, othersprite.center) < this.radius + othersprite.radius); Finally, we change the Update method of the Game1 class to call CircleCollides instead of Collides: if (mysprite1.circlecollides(mysprite2)) Vector2 tempvelocity = mysprite1.velocity; mysprite1.velocity = mysprite2.velocity; mysprite2.velocity = tempvelocity; Compile and run the resulting code. Here are complete instances of the Lab3-Part2 Game1.cs and clssprite.cs code. (Be sure to delete all after.cs after you download the code.) The result should be some bouncing sprites! TASK: Go through Game1.cs, and clssprite.cs and insert comments explaining every line of code not previously documented. If you like, you can use /* */ comment notation to distinguish your comments from the comments inserted by MonoGame. It is perfectly acceptable, and in fact encouraged, for you to work together on this portion of the lab. Save a copy of your work this far, e.g., by saving a copy of the project, and creating a zip file of the project contents named something like <YourName>-Lab3-Part2.zip. PART 3 In this part of Lab 3 we will see how to incorporate user input to our game. We will take control of one of the balls with either the keyboard or mouse, and we will show you how to interface with the Xbox game controller (gamepad). 18

19 Adding User Input When you create a new MonoGame Windows Game 4.0 project type, the Update method of the Game1 class already includes code for dealing with user input: // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.exit(); This code introduces the GamePad class: the basic entry point to get user input from the Xbox gamepad. If you explore the GamePad properties and methods using Visual C# 2017 Express IntelliSense (you may not know what this is yet - check out ), you will see how to use the GetState method to get the current state of buttons (Buttons structure), the thumbsticks (ThumbSticks structure), directional pad (DPad structure), and the controller triggers (Triggers structure). There is also a property to inform you if the gamepad is connected (IsConnected). Another interesting detail is that you can vibrate the gamepad by calling the SetVibration method of the GamePad class. Similar to the GamePad class, there are corresponding classes for the keyboard (KeyBoard) and mouse (Mouse). Let s see how we can use this information to incorporate user input. First, in the Game1 class, we need to remove (comment out) the code that sets the starting velocity of mysprite2 in the LoadContent method, and remove (comment out) the call to mysprite2.move in the Update method. Do this now. These changes will prevent mysprite2 from moving by itself. We also need to change the collision-detection code, simplifying it to only invert the mysprite1 velocity, as follows: if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; // mysprite2.velocity *= -1; Now, to make the second sprite move according to gamepad, mouse or keyboard input, we include code for this purpose in the Update method of the Game1 class (here, all but the keyboard code is commented out, just to keep things simple for now), as follows: // Move the sprites mysprite1.move(); // mysprite2.move(); if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; // mysprite2.velocity *= -1; // Change the sprite 2 position using the left thumbstick of the Xbox controller 19

20 // Vector2 LeftThumb = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left; // mysprite2.position += new Vector2(LeftThumb.X, -LeftThumb.Y) * 5; // Change the sprite 2 position using the keyboard KeyboardState keyboardstate = Keyboard.GetState(); if (keyboardstate.iskeydown(keys.up)) mysprite2.position += new Vector2(0, -5); if (keyboardstate.iskeydown(keys.down)) mysprite2.position += new Vector2(0, 5); if (keyboardstate.iskeydown(keys.left)) mysprite2.position += new Vector2(-5, 0); if (keyboardstate.iskeydown(keys.right)) mysprite2.position += new Vector2(5, 0); // Make sprite 2 follow the mouse //if (mysprite2.position.x < Mouse.GetState().X) // mysprite2.position += new Vector2(5, 0); //if (mysprite2.position.x > Mouse.GetState().X) // mysprite2.position += new Vector2(-5, 0); //if (mysprite2.position.y < Mouse.GetState().Y) // mysprite2.position += new Vector2(0, 5); //if (mysprite2.position.y > Mouse.GetState().Y) // mysprite2.position += new Vector2(0, -5); base.update(gametime); In this code, we are adding a Vector2 to mysprite2.position. For the gamepad, this vector is five times the value of the left thumbstick, except that we invert the Y property of the left thumbstick. If this seems odd, recall that in screen coordinates, the X position increments from left to right, and the Y position increments from the top to the bottom of the screen. The values of the X and Y properties of the thumbsticks range from -1 to 1, according to how much the thumbstick is pushed to the right or the bottom (positive values) or left and up (negative values). Therefore, you must invert the y coordinate to move the ball as expected. The multiplication by five is simply to make the ball move faster, according to the gamepad input. To make the gamepad vibrate when mysprite1collides with mysprite2 is also easy. Simply change the collision-detection code in the Update method of the Game1 class, as follows: if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); Note that we need to set the gamepad vibration to zero when the sprites are not colliding; otherwise, it would keep on vibrating continuously. The second and third arguments of the SetVibration method range from 0 to 1 (a floating point number), and define the speed for the left (low-frequency) and right (high-frequency) motors. You can include code in your program to generate different types of vibrations depending on the game conditions, for example, if the game collision is on the left or on the right of the player character. 20

21 Compile and run the program with these changes. You should be able to move one of the sprites with the arrow keys, and cause it to collide. If you have problems, here is a complete copy of the correct code: Game1.cs using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace Lab3_Mono /// This is the main type for your game. public class Game1 : Game GraphicsDeviceManager graphics; SpriteBatch spritebatch; clssprite mysprite1; clssprite mysprite2; public Game1() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // changing the back buffer size changes the window size (in windowed mode) graphics.preferredbackbufferwidth = 700; graphics.preferredbackbufferheight = 500; /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.initialize will enumerate through any components /// and initialize them as well. protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); /// LoadContent will be called once per game and is the place to load /// all of your content. protected override void LoadContent() // Create a new SpriteBatch, which can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); // Load a 2D texture sprite mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); mysprite2 = new clssprite(content.load<texture2d>("ball"), new Vector2(218f, 118f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); 21

22 // Create a SpriteBatch to render the sprite spritebatch = new SpriteBatch(graphics.GraphicsDevice); // set the speed the sprites will move mysprite1.velocity = new Vector2(5, 5); // mysprite2.velocity = new Vector2(3, -3); /// UnloadContent will be called once per game and is the place to unload /// game-specific content. protected override void UnloadContent() // TODO: Unload any non ContentManager content here /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Update(GameTime gametime) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); // Move the sprites mysprite1.move(); // mysprite2.move(); if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); // Change the sprite 2 position using the left thumbstick of the Xbox controller // Vector2 LeftThumb = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left; // mysprite2.position += new Vector2(LeftThumb.X, -LeftThumb.Y) * 5; // Change the sprite 2 position using the keyboard KeyboardState keyboardstate = Keyboard.GetState(); if (keyboardstate.iskeydown(keys.up)) mysprite2.position += new Vector2(0, -5); if (keyboardstate.iskeydown(keys.down)) mysprite2.position += new Vector2(0, 5); if (keyboardstate.iskeydown(keys.left)) mysprite2.position += new Vector2(-5, 0); if (keyboardstate.iskeydown(keys.right)) mysprite2.position += new Vector2(5, 0); // Make sprite 2 follow the mouse //if (mysprite2.position.x < Mouse.GetState().X) // mysprite2.position += new Vector2(5, 0); 22

23 //if (mysprite2.position.x > Mouse.GetState().X) // mysprite2.position += new Vector2(-5, 0); //if (mysprite2.position.y < Mouse.GetState().Y) // mysprite2.position += new Vector2(0, 5); //if (mysprite2.position.y > Mouse.GetState().Y) // mysprite2.position += new Vector2(0, -5); base.update(gametime); /// This is called when the game should draw itself. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.CornflowerBlue); // Draw the sprite using Alpha Blend, which uses transparency information if available spritebatch.begin(); mysprite1.draw(spritebatch); mysprite2.draw(spritebatch); spritebatch.end(); base.draw(gametime); clssprite.cs using Microsoft.Xna.Framework.Graphics; // for Texture2D using Microsoft.Xna.Framework; // for Vector2 namespace Lab3_Mono class clssprite public Texture2D texture get; set; // sprite texture, read-only property public Vector2 position get; set; // sprite position on screen public Vector2 size get; set; // sprite size in pixels public Vector2 velocity get; set; // sprite velocity private Vector2 screensize get; set; // screen size public Vector2 center get return position + (size / 2); // sprite center public float radius get return size.x / 2; // sprite radius public clssprite(texture2d newtexture, Vector2 newposition, Vector2 newsize, int ScreenWidth, int ScreenHeight) texture = newtexture; position = newposition; size = newsize; screensize = new Vector2(ScreenWidth, ScreenHeight); public void Move() // if we ll move out of the screen, invert velocity 23

24 // checking right boundary if (position.x + size.x + velocity.x > screensize.x) velocity = new Vector2(-velocity.X, velocity.y); // checking bottom boundary if (position.y + size.y + velocity.y > screensize.y) velocity = new Vector2(velocity.X, -velocity.y); // checking left boundary if (position.x + velocity.x < 0) velocity = new Vector2(-velocity.X, velocity.y); // checking top boundary if (position.y + velocity.y < 0) velocity = new Vector2(velocity.X, -velocity.y); // since we adjusted the velocity, just add it to the current position position += velocity; public bool Collides(clsSprite othersprite) // check if two sprites intersect return (this.position.x + this.size.x > othersprite.position.x && this.position.x < othersprite.position.x + othersprite.size.x && this.position.y + this.size.y > othersprite.position.y && this.position.y < othersprite.position.y + othersprite.size.y); public bool CircleCollides(clsSprite othersprite) // Check if two circle sprites collided return (Vector2.Distance(this.center, othersprite.center) < this.radius + othersprite.radius); public void Draw(SpriteBatch spritebatch) spritebatch.draw(texture, position, Color.White); Move the sprite with the keyboard. Now change the code to move the sprite with the mouse. When the sprites overlap, mysprite1bounces. If we run this Lab using an Xbox, the gamepad would vibrate when the sprites collide. Note that if you move the controlled sprite to overlap the bouncing sprite, the sprites oscillate rapidly. Why is this so, and how might you correct this problem? For extra credit, implement a working solution to this problem and demonstrate it in class. TASK: Go through Game1.cs, and clssprite.cs and insert comments explaining every line of code not previously documented. If you like, you can use /* */ comment notation to distinguish your comments from the comments inserted by MonoGame. It is perfectly acceptable, and in fact encouraged, for you to work together on this portion of the lab. Save a copy of your work this far, e.g., by saving a copy of the project, and creating a zip file of the project contents named something like <YourName>-Lab3-Part3.zip. 24

25 Part 4 In the last part of this lab, we will add audio to our simple game. We will include background music and sound effects when the balls collide. MonoGame processes sound using the same structure that it uses to manage graphics: the Content Pipeline. To MonoGame, sound is just another type of game content. MonoGame supports audio files in (at least) WAV, WMA, and MP3 4 formats. There are a variety ways to add sound to a MonoGame game: (1) the SoundEffect and SoundEffectInstance classes, which provide a simple and modestly-featured set of methods used to play fire and forget sounds, such as might be used for collisions or explosions; (2) the MediaPlayer and Song classes, which provide support for playing longer sounds, such as background music or victory songs; (3) the AudioListener and AudioEmitter classes, which support positional sound, allowing us to position both the source of the sound and the location of our ear in the game, while continuing to also use the SoundEffect classes; and (4) the powerful (and complex) Microsoft Cross-Platform Audio Creation Tool, known as XACT. Of these four, methods 1-3 all make use of the MonoGame Content Pipeline. XACT does not; it generates precompiled files that bypass the Content Pipeline. We will demonstrate each of these four techniques in this part of Lab 3. We will not cover how to generate the desired sound files themselves. Tools such as Audacity ( can be used to build complex sound files that can then be processed and played by MonoGame. A good introduction to Audacity can be found here: Note that most sounds and music are protected intellectual property. Do not use others sounds or music without permission, and even if you have permission, be sure to appropriately credit the author/owner. Before we begin, we need some sounds. Locate two sound files chord.wav and notify.wav. You can search for these files on the C: drive (these files are installed by default in Windows, as system event sounds; alternatively, you can choose any available.wav files), or you can download this zip file to your desktop (don t forget to unpack the zip file before proceeding). There are four files in this zip file; we will eventually need them all for this lab. Outside of Visual Studio, copy the four files to the Content project sub-directory. Installing XACT (Windows Only) If you are using an Inworks computer, you can skip this step. If you are using your own computer, you must install XACT software as described below or you will be unable to complete that part of the lab. XACT is only available for Windows. 4 There are a number of online admonitions to not use MP3 format in your games, asserting that its use could result in legal challenges above a certain threshold. To the best of my knowledge (*but I am not a lawyer*), MP3 technology became license-free in the United States in April 2017, when U.S. Patent 6,009,399 expired. If this might matter to you, seek the advice of competent counsel. 25

26 Although MonoGame is a very complete clone of Microsoft XNA 4.0, at least as of MonoGame version 3.7, XACT software must be installed separately before MonoGame can make use of its output. Although XACT was created for an older version of Visual Studio, installing XACT is not difficult, as we describe below: 1. Download the XNA installer from Microsoft, or here is a local copy. The desired file is called XNAGS40_setup.exe. 2. Open a command prompt with administrator privileges(start Menu; search for cmd.exe; right-click and Run As Administrator) and cd to the directory containing XNAGS40_setup.exe. 3. Run the command: XNAGS40_setup.exe /x 4. You will now be prompted where to extract. Choose a convenient location and click OK. This will create a couple files, the most important being redists.msi. 5. Run this file (just type redists.msi and hit <enter> at the command line, or double click on the file in Windows Explorer). This will in turn create a directory structure in Program Files (or Program Files x86 on 64-bit Windows ) called Microsoft XNA. 6. Close the command prompt, navigate to that folder in Windows Explorer, then open XNA Game Studio\v4.0\setup: 7. Run xnags_shared.msi then xnags_platform_tools.msi, in that order. Take default options when asked. 8. Open C:\Program Files (x86)\microsoft XNA\XNA Game Studio\v4.0\Tools, and you should see the following: 26

27 9. All of the XACT tools should now be found in the Start Menu, under Microsoft XNA Game Studio 4.0. We will use these tools in a bit. Using SoundEffect to Play Audio Content To play sounds using SoundEffect we first have to add the file to the content project of our game. Right-click the content project and select Add Existing Item. Then, navigate to the chord.wav audio file and click Open. Examine the properties of the added wav file to determine its asset name (in this case, chord ). Now we need to add code to Game1.cs to create an instance of SoundEffect, and to load this effect into the content pipeline. (Note: Do not confuse an instance of the SoundEffect class with a SoundEffectInstance, which is a more robust sound effect handler that allows us to control the playback of a single audio stream from a SoundEffect. We create a SoundEffectInstance by calling the CreateInstance method on the SoundEffect. A SoundEffect can create many instances. Each instance provides a number of controls that enable more advanced playback scenarios, including Play, Pause, Stop, and Resume. Add the following code to Game1.cs: in the using statements using Microsoft.Xna.Framework.Audio; in the class instance variable definitions // Create a SoundEffect resource SoundEffect soundeffect; and in LoadContent() spritebatch = new SpriteBatch(GraphicsDevice); // Load the SoundEffect resource soundeffect = Content.Load<SoundEffect>("chord"); Now that we have loaded the resources for the audio file, we need to play it. We will play the chord.wav file whenever the two sprites collide using a mechanism for sound playback sometimes called fire and forget. It is called fire and forget because after you call the Play method, you don t need to manage the playback of the audio stream. The audio file plays from the start of the file to the end of the file. Although this limits the control you have as a developer on how the playback occurs, it is really simple to use. To play the SoundEffect using fire and forget, add the following code to Game1.cs: if (mysprite1.circlecollides(mysprite2)) 27

28 mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); soundeffect.play(); Compile and run your code. You should hear a boink whenever the two sprites collide. The Play method returns a boolean value that specifies whether the sound was able to play or not. If Play returns true, then the sound plays. If it false returns, there are too many sounds currently playing, so it cannot play. We do not need to worry about this, since we are only playing one sound at this point. The Play method also contains an overload with three parameters to control the volume, pitch, and panning of the playback. Replace soundeffect.play() with: soundeffect.play(1.0f, 0.0f, 0.0f); The first parameter is a float value that determines the volume of the sound. The value can range from 0, which indicates no sound, to 1.0, which means the sound should be full volume with respect to the master volume setting. Use the MasterVolume static property of SoundEffect to set the master volume setting for all SoundEffects. The MasterVolume values range from 0 to 1 with 1 as the default value. The second parameter is a float value that determines the pitch that the sound plays in. The pitch value ranges from -1, which lowers the pitch by one octave, to 1, which raises the pitch by one octave. A value of 0 plays the sound as it is stored in the file. The third parameter controls the pan of the playback. Panning determines how much of the playback occurs from the left and right speakers. The values rage from -1, which comes from only the left speaker, to 1, which comes from only from the right speaker. A value of 0 plays the sound as it was loaded from the file. Experiment with different soundeffect.play parameter values. SoundEffect exposes two additional properties that are useful. The first is the Duration property that returns the length as a TimeSpan of the SoundEffect. The other is Name that returns the name of the SoundEffect. If we need finer control, such as looping or applying effects, we can create a SoundEffectInstance using the SoundEffect.CreateInstance() call. We should also create a separate instance if we want to have multiple concurrent instances of the same sound effect playing. All instances of the same SoundEffect share resources, so, while the number of simultaneous supported sounds varies from platform to platform (based upon memory limitations), the number is large. Let s experiment with SoundEffectInstance. If you have not done so already, add notify.wav, explosion.wav and music.wav to the content pipeline project. Now, modify Game1.cs as shown below: in the class instance variable definitions // Create a SoundEffect resource SoundEffect soundeffect; 28

29 // Create some sound resources SoundEffect soundeffect1; SoundEffect soundeffect2; SoundEffectInstance seinstance; // Since we will loop the music, we only want to play it once bool playmusic = true; in LoadContent() soundeffect = Content.Load<SoundEffect>("chord"); // Load the SoundEffect resource soundeffect1 = Content.Load<SoundEffect>("chord"); soundeffect2 = Content.Load<SoundEffect>("music"); // Create a SoundEffect instance that can be manipulated later seinstance = soundeffect2.createinstance(); seinstance.islooped = true; and in Update() if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); soundeffect1.play(1.0f, 0.0f, 0.0f); if (playmusic) seinstance.play(); playmusic = false; else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); Compile and run this code. Now, in addition to the boink on every collision, you should hear weird chanting that starts at the first collision, and continues thereafter. Here is our code at this point: Game1.cs: using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Audio; namespace Lab3_Mono /// This is the main type for your game. public class Game1 : Game GraphicsDeviceManager graphics; SpriteBatch spritebatch; 29

30 clssprite mysprite1; clssprite mysprite2; // Create some sound resources SoundEffect soundeffect1; SoundEffect soundeffect2; SoundEffectInstance seinstance; // Since we will loop the music, we only want to play it once bool playmusic = true; public Game1() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // changing the back buffer size changes the window size (in windowed mode) graphics.preferredbackbufferwidth = 700; graphics.preferredbackbufferheight = 500; /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.initialize will enumerate through any components /// and initialize them as well. protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); /// LoadContent will be called once per game and is the place to load /// all of your content. protected override void LoadContent() // Create a new SpriteBatch, which can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); // Load the SoundEffect resource soundeffect1 = Content.Load<SoundEffect>("chord"); soundeffect2 = Content.Load<SoundEffect>("music"); // Create a SoundEffect instance that can be manipulated later seinstance = soundeffect2.createinstance(); seinstance.islooped = true; // Load a 2D texture sprite mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); mysprite2 = new clssprite(content.load<texture2d>("ball"), new Vector2(218f, 118f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); // Create a SpriteBatch to render the sprite spritebatch = new SpriteBatch(graphics.GraphicsDevice); 30

31 // set the speed the sprites will move mysprite1.velocity = new Vector2(5, 5); // mysprite2.velocity = new Vector2(3, -3); /// UnloadContent will be called once per game and is the place to unload /// game-specific content. protected override void UnloadContent() // TODO: Unload any non ContentManager content here /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Update(GameTime gametime) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); // Move the sprites mysprite1.move(); // mysprite2.move(); if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); soundeffect1.play(1.0f, 0.0f, 0.0f); if (playmusic) seinstance.play(); playmusic = false; else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); // Change the sprite 2 position using the left thumbstick of the Xbox controller // Vector2 LeftThumb = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left; // mysprite2.position += new Vector2(LeftThumb.X, -LeftThumb.Y) * 5; // Change the sprite 2 position using the keyboard KeyboardState keyboardstate = Keyboard.GetState(); if (keyboardstate.iskeydown(keys.up)) mysprite2.position += new Vector2(0, -5); if (keyboardstate.iskeydown(keys.down)) mysprite2.position += new Vector2(0, 5); if (keyboardstate.iskeydown(keys.left)) mysprite2.position += new Vector2(-5, 0); if (keyboardstate.iskeydown(keys.right)) mysprite2.position += new Vector2(5, 0); // Make sprite 2 follow the mouse 31

32 //if (mysprite2.position.x < Mouse.GetState().X) // mysprite2.position += new Vector2(5, 0); //if (mysprite2.position.x > Mouse.GetState().X) // mysprite2.position += new Vector2(-5, 0); //if (mysprite2.position.y < Mouse.GetState().Y) // mysprite2.position += new Vector2(0, 5); //if (mysprite2.position.y > Mouse.GetState().Y) // mysprite2.position += new Vector2(0, -5); base.update(gametime); /// This is called when the game should draw itself. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.CornflowerBlue); // Draw the sprite using Alpha Blend, which uses transparency information if available spritebatch.begin(); mysprite1.draw(spritebatch); mysprite2.draw(spritebatch); spritebatch.end(); base.draw(gametime); In the example we just completed, the music was encoded as a.wav file. This allowed us to use the sound effect classes to play it. If we want to play an mp3 file, we need to use the MediaPlayer and Song classes, as we will now describe. Using the MediaPlayer and Song Classes to Play Audio Content Playing a song in MonoGame is quite easy. First, we need a song. From among the mp3 files that you own, select one, and add it to the project s content pipeline as we have done before. In this example, I have added AC/DC track Back in Black. You will of course choose you own song. Add the following code to Game1.cs: in the using statements using Microsoft.Xna.Framework.Media; in the class instance variable definitions Song song; 32

33 and in LoadContent() // Change "acdc" to the file prefix of your mp3 song. song = Content.Load<Song>("acdc"); MediaPlayer.Play(song); // play it // Uncomment the following line will also loop the song // MediaPlayer.IsRepeating = true; MediaPlayer.MediaStateChanged += MediaPlayer_MediaStateChanged; Finally, add a new MediaStateChanged event handler that will be called when the song completes, decreasing the volume and playing the song again: void MediaPlayer_MediaStateChanged(object sender, System.EventArgs e) // 0.0f is silent, 1.0f is full volume MediaPlayer.Volume -= 0.1f; MediaPlayer.Play(song); Compile and run your code. Now, there will be three sounds. Your song will start immediately, and play continuously. When the song ends, it will restart, but at a reduced volume. You will also hear the boink on every collision, and you will hear the weird chanting music that starts at the first collision, and continues thereafter (you might want to comment this out at some point). We used an event handler to catch and respond to a MediaStateChanged event (in this case, when the song completes), which decreases the volume and plays the song again. This is probably a good time to add the means to control the volume. Add the following code to Update(): // Media Player Volume if (Keyboard.GetState().IsKeyDown(Keys.RightControl)) if (MediaPlayer.Volume <= 0.1f) MediaPlayer.Volume = 0.0f; else MediaPlayer.Volume -= 0.1f; if (Keyboard.GetState().IsKeyDown(Keys.LeftControl)) if (MediaPlayer.Volume >= 0.9f) MediaPlayer.Volume = 1.0f; else MediaPlayer.Volume += 0.1f; // SoundEffect Volume if (Keyboard.GetState().IsKeyDown(Keys.RightShift)) if (SoundEffect.MasterVolume <= 0.1f) SoundEffect.MasterVolume = 0.0f; else SoundEffect.MasterVolume -= 0.1f; if (Keyboard.GetState().IsKeyDown(Keys.LeftShift)) 33 // Down // Up // Down // Up

34 if (SoundEffect.MasterVolume >= 0.9f) SoundEffect.MasterVolume = 1.0f; else SoundEffect.MasterVolume += 0.1f; Compile and run your code. The right and left control keys should now control the song volume, and the right and left shift keys should control the boink and chanting volume. How cool is that? Here is our code so far: Game1.cs: using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Media; namespace Lab3_Mono /// This is the main type for your game. public class Game1 : Game GraphicsDeviceManager graphics; SpriteBatch spritebatch; clssprite mysprite1; clssprite mysprite2; // Create some sound resources SoundEffect soundeffect1; SoundEffect soundeffect2; SoundEffectInstance seinstance; // Since we will loop the music, we only want to play it once bool playmusic = true; Song song; AudioListener listener; AudioEmitter emitter; public Game1() graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; // changing the back buffer size changes the window size (in windowed mode) graphics.preferredbackbufferwidth = 700; graphics.preferredbackbufferheight = 500; void MediaPlayer_MediaStateChanged(object sender, System.EventArgs e) // 0.0f is silent, 1.0f is full volume MediaPlayer.Volume -= 0.1f; MediaPlayer.Play(song); 34

35 /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.initialize will enumerate through any components /// and initialize them as well. protected override void Initialize() // TODO: Add your initialization logic here base.initialize(); /// LoadContent will be called once per game and is the place to load /// all of your content. protected override void LoadContent() // Create a new SpriteBatch, which can be used to draw textures. spritebatch = new SpriteBatch(GraphicsDevice); // Load the SoundEffect resource soundeffect1 = Content.Load<SoundEffect>("chord"); soundeffect2 = Content.Load<SoundEffect>("music"); // Change "acdc" to the file prefix of your mp3 song. song = Content.Load<Song>("acdc"); MediaPlayer.Play(song); // play it // Uncomment the following line will also loop the song // MediaPlayer.IsRepeating = true; MediaPlayer.MediaStateChanged += MediaPlayer_MediaStateChanged; // Create a SoundEffect instance that can be manipulated later seinstance = soundeffect2.createinstance(); seinstance.islooped = true; listener = new AudioListener(); emitter = new AudioEmitter(); // Load a 2D texture sprite mysprite1 = new clssprite(content.load<texture2d>("ball"), new Vector2(0f, 0f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); mysprite2 = new clssprite(content.load<texture2d>("ball"), new Vector2(218f, 118f), new Vector2(64f, 64f), graphics.preferredbackbufferwidth, graphics.preferredbackbufferheight); // Create a SpriteBatch to render the sprite spritebatch = new SpriteBatch(graphics.GraphicsDevice); // set the speed the sprites will move mysprite1.velocity = new Vector2(5, 5); // mysprite2.velocity = new Vector2(3, -3); /// UnloadContent will be called once per game and is the place to unload /// game-specific content. protected override void UnloadContent() 35

36 // TODO: Unload any non ContentManager content here /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Update(GameTime gametime) if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); // Move the sprites mysprite1.move(); // mysprite2.move(); if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); soundeffect1.play(1.0f, 0.0f, 0.0f); if (playmusic) seinstance.play(); playmusic = false; else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); // Change the sprite 2 position using the left thumbstick of the Xbox controller // Vector2 LeftThumb = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left; // mysprite2.position += new Vector2(LeftThumb.X, -LeftThumb.Y) * 5; // Change the sprite 2 position using the keyboard KeyboardState keyboardstate = Keyboard.GetState(); if (keyboardstate.iskeydown(keys.up)) mysprite2.position += new Vector2(0, -5); if (keyboardstate.iskeydown(keys.down)) mysprite2.position += new Vector2(0, 5); if (keyboardstate.iskeydown(keys.left)) mysprite2.position += new Vector2(-5, 0); if (keyboardstate.iskeydown(keys.right)) mysprite2.position += new Vector2(5, 0); // Make sprite 2 follow the mouse //if (mysprite2.position.x < Mouse.GetState().X) // mysprite2.position += new Vector2(5, 0); //if (mysprite2.position.x > Mouse.GetState().X) // mysprite2.position += new Vector2(-5, 0); //if (mysprite2.position.y < Mouse.GetState().Y) // mysprite2.position += new Vector2(0, 5); //if (mysprite2.position.y > Mouse.GetState().Y) // mysprite2.position += new Vector2(0, -5); // Media Player Volume 36

37 if (Keyboard.GetState().IsKeyDown(Keys.RightControl)) if (MediaPlayer.Volume <= 0.1f) MediaPlayer.Volume = 0.0f; else MediaPlayer.Volume -= 0.1f; if (Keyboard.GetState().IsKeyDown(Keys.LeftControl)) if (MediaPlayer.Volume >= 0.9f) MediaPlayer.Volume = 1.0f; else MediaPlayer.Volume += 0.1f; // SoundEffect Volume if (Keyboard.GetState().IsKeyDown(Keys.RightShift)) if (SoundEffect.MasterVolume <= 0.1f) SoundEffect.MasterVolume = 0.0f; else SoundEffect.MasterVolume -= 0.1f; if (Keyboard.GetState().IsKeyDown(Keys.LeftShift)) if (SoundEffect.MasterVolume >= 0.9f) SoundEffect.MasterVolume = 1.0f; else SoundEffect.MasterVolume += 0.1f; // Down // Up // Down // Up base.update(gametime); /// This is called when the game should draw itself. /// <param name="gametime">provides a snapshot of timing values.</param> protected override void Draw(GameTime gametime) GraphicsDevice.Clear(Color.CornflowerBlue); // Draw the sprite using Alpha Blend, which uses transparency information if available spritebatch.begin(); mysprite1.draw(spritebatch); mysprite2.draw(spritebatch); spritebatch.end(); base.draw(gametime); 37

38 Positional Audio Playback Using the AudioListener and AudioEmitter Classes 5 In this portion of the lab, we will learn how to create sound that appears to come from a certain position, and to play the player s ear at a particular position in the virtual space of the game. We will only work with one sound effect for this example. Modify Game1.cs as shown below (many of these modifications will just be commenting things out): in the class instance variable definitions // Create some sound resources // SoundEffect soundeffect1; bool playmusic = true; bool playmusic = false; AudioListener listener; AudioEmitter emitter; in LoadContent() in Update() // Change "acdc" to the file prefix of your mp3 song. // song = Content.Load<Song>("acdc"); // MediaPlayer.Play(song); // play it // Uncomment the following line will also loop the song // MediaPlayer.IsRepeating = true; // MediaPlayer.MediaStateChanged += MediaPlayer_MediaStateChanged; listener = new AudioListener(); emitter = new AudioEmitter(); // Play the positional sound seinstance.apply3d(listener, emitter); seinstance.play(); // soundeffect1.play(1.0f, 0.0f, 0.0f); /* KeyboardState keyboardstate = Keyboard.GetState(); if (keyboardstate.iskeydown(keys.up)) mysprite2.position += new Vector2(0, -5); if (keyboardstate.iskeydown(keys.down)) mysprite2.position += new Vector2(0, 5); if (keyboardstate.iskeydown(keys.left)) mysprite2.position += new Vector2(-5, 0); if (keyboardstate.iskeydown(keys.right)) mysprite2.position += new Vector2(5, 0); */ // Move the listening position 5 This example derives from a 2015 posting: 38

39 if (Keyboard.GetState().IsKeyDown(Keys.Left)) listener.position = new Vector3(listener.Position.X - 0.1f, listener.position.y, listener.position.z); seinstance.apply3d(listener, emitter); if (Keyboard.GetState().IsKeyDown(Keys.Right)) listener.position = new Vector3(listener.Position.X + 0.1f, listener.position.y, listener.position.z); seinstance.apply3d(listener, emitter); if (Keyboard.GetState().IsKeyDown(Keys.Up)) listener.position = new Vector3(listener.Position.X, listener.position.y + 0.1f, listener.position.z); seinstance.apply3d(listener, emitter); if (Keyboard.GetState().IsKeyDown(Keys.Down)) listener.position = new Vector3(listener.Position.X, listener.position.y - 0.1f, listener.position.z); seinstance.apply3d(listener, emitter); In this example, we loaded a single SoundEffect and started it looping infinitely. We then created an AudioListener and AudioEmitter instance. The AudioListener represents the location of our ear within the virtual world, while the AudioEmitter represents the position of the sound effect. The default location of both is a Vector3 at (0,0,0). We set the position of a SoundEffect by calling Apply3D(). In the Update() call, if the user presses an arrow key, we updated the Position of the AudioListener accordingly. After changing the position of a sound, we have to call Apply3D again. As we press the arrow keys the audio pans and changes volume to correspond with the updated position. Compile and run your code. The apparent position of the sound (or, more precisely, our position relative to the sound), changes when we press the arrow keys. How cool is that? Creating Audio Content with XACT The Microsoft Cross-Platform Audio Creations Tool (XACT) is a powerful graphical audio-authoring tool that enables us to manage large numbers of source wave files and to control their playback in the game. Using the XACT graphical interface, we can load existing wave files, group the files, and layer them with effects. We can also use XACT to set up audio streaming 6. MonoGame calls are used to trigger playback. The XACT tool provides many features, we will only cover the basics of the graphical interface and the XACT features that enable us to get started using the tool. 6 Streaming of XACT-generated content is, as of December 4, 2018, not yet implemented. 39

40 Note: XACT only works for the Windows and Xbox platforms. You must use the SoundEffect and MediaPlayer classes for any other platform. XACT is also old software (last maintained in 2012) that is somewhat cumbersome and unwieldy to use. Because it is powerful and free, there is active work by MonoGame developers to fully support XACT. All of these considerations might lead one to conclude that, at least for the present, XACT is not worth the time to learn. It would hard to argue convincingly with that viewpoint. I will introduce the use of XACT here, and I recommend that you spend enough time to understand the basics. However, if you need to prioritize other work, feel free to do so. We use XACT to create sound banks and wave banks, compiled into an XAP file, which the game can then use through the content manager. In this section, we will learn the basics of how to create audio content with XACT and use it in a program. Follow these steps to create a new XACT project: 1. Start XACT by choosing Start All Programs Microsoft XNA Game Studio 4.0 Tools Microsoft Cross- Platform Audio Creation Tool 3 (XACT3). 2. In the XACT main window, choose File New Project. The New Project Path dialog box displays. Because we use the XACT project in our game s content pipeline, it is often easy to use the content folder of the game to store the XACT project file. Browse to the project s content folder for your Lab3 project, and then enter Lab3Sounds ) as the name for your XACT project (make sure it ends with the.xap extension). Click the Save button. 3. On the left side of the window, Lab3Sounds now appears as a root node, with many types of child nodes below it. The starting elements of an XACT project are wave files that must be loaded from source recordings. In the following example, we will load a single wave file and then play back the sound using MonoGame. First, we need a wave bank to load the source wave files into. A wave bank is a collection of wave files that are grouped together. To add a new wave bank, click the Wave Banks menu and select New Wave Bank. A new entry displays under Wave Banks in the XACT project tree with the default name Wave Bank. We can change the default name by clicking the wave bank in the tree or by rightclicking the wave bank and selecting Rename. A wave bank menu also displays in the right side of the XACT workspace. 4. Next, we need to add a sound bank to the project. A sound bank is a collection of wave banks. To add a new sound bank, click the Sound Banks menu and select New Sound Bank. Just as with the wave bank, the new sound bank is added to the XACT project tree, but this time, the new item displays logically under the Sound Banks tree node. The new sound bank has a default name of Sound Bank, but you can change the name by clicking on the sound bank or by right-clicking the sound bank and selecting Rename. The sound bank window is also added to the XACT workspace to the right. 5. The workspace might be getting cluttered now, with the wave bank and sound bank windows overlapping. XACT provides a nice window-ordering option to organize our windows automatically. 40

41 Click the Window menu to display the windowing options. Select Tile Horizontally from the dropdown menu. 6. At this point, things should look like this: 7. We can now add source wave files to the project. Right-click the Wave Bank in the XACT project tree and select Insert Wave File(s). In the open file dialog box, locate and select the sound file explosion.wav. 8. Finally, we need to set up a cue. We use the cue to play back a sound or a group of sounds. The cue is stored and accessed from the sound bank. The quickest way to add a cue is by dragging a wave from the wave bank onto the cue section of the sound bank windows, which is in the lower left corner of the Sound Bank window (with a heading of Cue Name). 9. After you drag the wave file and create the cue, notice there are a number of new items that display in the sound bank window. This is because a new sound has been created. By default, it is created with the same name as the wave. The sound is displayed in the top left of the sound bank window. After selecting the sound entry, there is a track listing to the right of the window. Each sound can contain a number of tracks. In this case, a single track is created that plays the wave from the wave bank. Below the sound bank is the cue window to which you dragged the wave. A new cue is created using the same name as the wave that was used to create it. The cue is used in the game code to control the playback of the sounds, so a cue is required if you want to cause the sound to be played in your game. A cue is made up 41

42 of multiple sounds from the sound bank entries in the window above it. Because the cue is created by using the dragging shortcut, the sound of the same name is added to the cue. 10. Getting XACT to put its output where we want is something of a pain. XACT will create three files when it builds: Lab3Sounds.xgs Wave Bank.xwb Sound Bank.xsb Somehow, we either have to tell XACT where to put these files (where MonoGame expects to find them), or we have to manually copy the files from where XACT puts them by default to where MonoGame wants to find them. (We could also force MonoGame to look elsewhere, but that makes our code less portable and less readable). Let s go with Option 1. For each of the three files, we must specify the build path in XACT; we will start with Lab3Sounds.xgs. a. Click on Lab3Sounds to highlight it in the main tree view. Now look below the main tree view under the General Settings. The last setting is Windows Global Setting, as shown below: b. Click on the three dots to the right of the Windows Global Setting entry and a dialog box will appear: c. Browse to <your project path>\lab3_mono\lab3_mono\bin\windows\x86\debug\content, and click on Open. d. Now click on the single instance of Wavebank to highlight it in the main tree view. Now look below the main tree view under the General Settings. The last setting is Windows Build Path. e. As before, click on the three dots to the right of the Windows Build Path entry and a dialog box will appear: 42

43 f. Browse to <your project path>\lab3_mono\lab3_mono\bin\windows\x86\debug\content, and click on Open. g. Finally, do the same steps for the single instance of Soundbank. 11. Select File Build in the XACT main menu. This causes XACT to build the project and create the necessary files in our MonoGame project. Check to make sure that the three XACT files were created in <your project path>\lab3_mono\lab3_mono\bin\windows\x86\debug\content. (All of the xnb files created by the Content Pipeline will also be in this directory. 12. Finally, let s save our work. Select File Save Project in the XACT main menu. Don t forget this step or you will get weird error messages later. Now we are ready to insert code into our game project to play this sound. To keep things simple (at least as simple as we can make them using XACT), we will replace the sound that is made when the two sprites collide. First, we need to add the XACT project that we just created to the content project of our game. Just like adding other types of content, it is easy to add the XACT project. Right-click the content project and select Add, and then click Existing Item. Then, browse to and select the Lab3Sounds.xap XACT project file in the dialog box and click the Add button. Building the solution will create three files: Lab3Sounds.xgs is the audio engine file and is named after the XACT project name. The Wave Bank.xwb file contains the data from the wave bank of the same name. The Sound Bank.xsb file contains the data from the sound bank in your XACT project. In Game1.cs, add the following code: AudioEngine audioengine; SoundBank soundbank; WaveBank wavebank; Cue cue; The AudioEngine is used to perform necessary updates to the underlying audio system. The AudioEngine.Update method is required to be called once per frame (we will do this below) to ensure the audio playback stays up to date and is not stalled. The other three variables for the SoundBank, WaveBank, and Cue are the code counterparts to the ones created in the XACT project. Here is a brief description of these objects. AudioEngine: This object is the program reference to the audio services in the computer, and is used mainly to adjust a few general settings and as a parameter to create the wave and sound banks. When creating an AudioEngine object in your program, you need to use the name of the global settings file for the XACT content as a parameter. This settings file name is generated when the XAP file is compiled, and by default has the same name as the XAP file, with an.xgs extension. WaveBank: This is a collection of wave files. To create this bank in your code, you need to pass as parameters the AudioEngine object (which must have been previously created) and the compiled wave bank file, which is generated when you compile your project with the default name Wave Bank.xwb. 43

44 Although the wave bank is not explicitly used in your program, you need to create this object, because the sound cues in the sound bank depend on the wave files in this bank. Sound Bank: This is a collection of sound cues. You can define cues as references to the wave files stored in the wave bank, along with properties that establish details of how to play these wave files, and the methods that let you manage their playback. The code fragment below shows how to extend our game to include code to create and initialize the audio components, and to start, stop, pause, and resume this sound. The Cue class provides the methods and properties that we need to do this. To load the files that were built by processing the XACT project through the content pipeline, add the following lines of code to your game s LoadContent method: // Load files built from XACT project audioengine = new AudioEngine("Content/Lab3Sounds.xgs"); wavebank = new WaveBank(audioEngine, "Content/Wave Bank.xwb"); soundbank = new SoundBank(audioEngine, "Content/Sound Bank.xsb"); In the Update method, insert code to play the cue when the sprites collide: if (mysprite1.circlecollides(mysprite2)) mysprite1.velocity *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); //soundeffect1.play(1.0f, 0.0f, 0.0f); // Get an instance of the cue from the XACT project cue = soundbank.getcue("explosion"); cue.play(); else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); // Update the audio engine audioengine.update(); base.update(gametime); After playing the sound, we call the AudioEngine.Update method to ensure it is called each frame. A Cue has similar playback methods as SoundEffectInstance, such as Play, Pause, Resume, and Stop. There is also an Apply3D method, which takes an AudioListener and AudioEmitter. After Play is called on a Cue, it can t be called again. We can call Pause and then Resume, but calling Play again will cause an InvalidOperationException. To play the sound more than once, we have to create a new Cue instance each time by calling the SoundBank.GetCue method. Each Cue returned from GetCue is its own instance. The code above always creates a new cue instance before we play it. If we don t care about fine sound control, we can use SoundBank.PlayCue( Explosion ); instead of 44

45 cue = soundbank.getcue( Explosion ); cue.play(); to just play the cue, similar to how fire and forget sound effects work. Compile and run the program. You should hear explosions when the sprites collide. Now to test your skills: change the code to make the chord.wav sound play when the moving sprite bounces off any of the four walls. This will require modification of the Move method in clssprite to return a bool indicating that a wall has been hit. Then you can just wrap the call to Move with an if statement, and play the sound if the Move call returns true. Try to figure this out for yourself, perhaps working with a colleague. Streaming Audio: Playing Background Music 7 (SKIP this section) Some sound files are large, especially the sound files that are used to play background music. By default, the wave files used in the XACT project are loaded into memory at runtime. This can cause problems if the wave file is large, because the file might not fit into the memory of small devices, or it might take up more space than what we would like. We solve this problem by streaming the desired audio, i.e., loading what we need when we need it. Streaming is set at the wave bank level for all of the wave files contained within the wave bank. Let s add some streaming music to our project. Open the XACT project that you created previously. Add a new wave bank and call it Music. Select the new wave bank in the XACT project tree. The properties of the wave bank display in the lower left window. In the Type section, select the Streaming button. It should now be highlighted a green color. To add the music source files to the wave bank, right-click the new music wave bank and select Insert Wave File(s). Browse to and select a music file in the dialog window and click the Open button. (You can use the provided Music.wav file, or use your own, but you should remember that XACT is religious about Digital Rights Management - it may not let you incorporate protected material.) Now that the source wave file is added to our streaming wave bank, we need a cue to use for playback. Like we did before, drag the music wave into the sound bank s cue window to create the cue for our music wave. Finally, we need to change the sound that was created for the music cue to mark it as background music. Setting a sound category to Music allows users on the Xbox to play their own music library over our game s music. This allows the user to hear the sound effects in our game, but to override the music to what they are playing using the media playback provided on the Xbox. How cool is that? To change the sound category, select the music sound entry that we just created in the sound bank (select the music entry in the upper left quadrant of the Sound Bank, under Sound Name ). In the gray General window 7 As of December 4, 2018, MonoGame does not support streaming of XACT-generated content, but it appears that there is active work on this issue. Stay tuned. 45

46 in the lower left corner of the XACT window, select the Category drop-down and select Music. Next, click the Infinite checkbox under the Looping section to have the sound continually play until it is stopped. Click on the Music Wave Bank in the XACT tree view to bring up the Paths window and change the build path to <your project path>\lab3_mono\lab3_mono\bin\windows\x86\debug\content, as before. Just above where you changed the build path, click on Streaming, which should then turn green. Build and Save the XACT project, so we can add the music to our project. When you are done, things should look like this: Now to modify the code. We need two additional member variables to add streaming music to the previous example. Add the following two instance variables in Game1.cs: WaveBank streamingwavebank; Cue musiccue; As before, we need to load the wave bank. After the other audio loading in the game s LoadContent method, add the following lines of code: // Load streaming wave bank streamingwavebank = new WaveBank(audioEngine, "Content/Music.xwb", 0, 4); // The audio engine must be updated before the streaming cue is ready 46

GAME:IT Advanced. C# XNA Bouncing Ball First Game Part 1

GAME:IT Advanced. C# XNA Bouncing Ball First Game Part 1 GAME:IT Advanced C# XNA Bouncing Ball First Game Part 1 Objectives By the end of this lesson, you will have learned about and will be able to apply the following XNA Game Studio 4.0 concepts. Intro XNA

More information

Compile and run the code. You should see an empty window, cleared to a dark purple color.

Compile and run the code. You should see an empty window, cleared to a dark purple color. IWKS 3400 LAB 10 1 JK Bennett This lab will introduce most of the techniques required to construct flight simulator style game. Our primary goal is to demonstrate various techniques in the MonoGame environment,

More information

Creating a Role Playing Game with XNA Game Studio 3.0 Part 4 Adding the Action Screen and Tile Engine

Creating a Role Playing Game with XNA Game Studio 3.0 Part 4 Adding the Action Screen and Tile Engine Creating a Role Playing Game with XNA Game Studio 3.0 Part 4 Adding the Action Screen and Tile Engine To follow along with this tutorial you will have to have read the previous tutorials to understand

More information

A camera with a projection and view matrix

A camera with a projection and view matrix A camera with a projection and view matrix Drikus Kleefsman January 25, 2010 Keywords: Xna, world, projection, view, matrix Abstract The first thing you want to have in a 3d scene is a camera to look at

More information

XNA (2D) Tutorial. Pong IAT410

XNA (2D) Tutorial. Pong IAT410 XNA (2D) Tutorial Pong IAT410 Creating a new project 1. From the Start Menu, click All Programs, then the Microsoft XNA Game Studio Express folder, and finally XNA Game Studio Express. 2. When the Start

More information

XNA Workshop at CS&IT Symposium 7/11/11

XNA Workshop at CS&IT Symposium 7/11/11 XNA Workshop at CS&IT Symposium 7/11/11 Time 9:00 to 9:20 9:20 to 9:40 9:40 to 10:10 Mood Light 10:15 to 10:45 Manual Mood Light 10:50 to 11:20 Placing and Moving Image 11:25 to 11:45 Windows Phone Touch

More information

XNA Game Studio 4.0.

XNA Game Studio 4.0. Getting Started XNA Game Studio 4.0 To download XNA Game Studio 4.0 itself, go to http://www.microsoft.com/download/en/details.aspx?id=23714 XNA Game Studio 4.0 needs the Microsoft Visual Studio 2010 development

More information

Unit 5 Test Review Name: Hour: Date: 1) Describe two ways we have used paint to help us as we studied images in monogame.

Unit 5 Test Review Name: Hour: Date: 1) Describe two ways we have used paint to help us as we studied images in monogame. Unit 5 Test Review Name: Hour: Date: Answer the following questions in complete sentences. 1) Describe two ways we have used paint to help us as we studied images in monogame. a) b) 2) Where do you DECLARE

More information

Slides adapted from 4week course at Cornell by Tom Roeder

Slides adapted from 4week course at Cornell by Tom Roeder Slides adapted from 4week course at Cornell by Tom Roeder Interactive Game loop Interactive Game Loop Core Mechanics Physics, AI, etc. Update() Input GamePad, mouse, keybard, other Update() Render changes

More information

XNA 4.0 RPG Tutorials. Part 2. More Core Game Components

XNA 4.0 RPG Tutorials. Part 2. More Core Game Components XNA 4.0 RPG Tutorials Part 2 More Core Game Components I'm writing these tutorials for the new XNA 4.0 framework. The tutorials will make more sense if they are read in order. You can find the list of

More information

A Summoner's Tale MonoGame Tutorial Series. Chapter 9. Conversations Continued

A Summoner's Tale MonoGame Tutorial Series. Chapter 9. Conversations Continued A Summoner's Tale MonoGame Tutorial Series Chapter 9 Conversations Continued This tutorial series is about creating a Pokemon style game with the MonoGame Framework called A Summoner's Tale. The tutorials

More information

Visual C# 2010 Express

Visual C# 2010 Express Review of C# and XNA What is C#? C# is an object-oriented programming language developed by Microsoft. It is developed within.net environment and designed for Common Language Infrastructure. Visual C#

More information

Next, we re going to specify some extra stuff related to our window such as its size and title. Add this code to the Initialize method:

Next, we re going to specify some extra stuff related to our window such as its size and title. Add this code to the Initialize method: IWKS 3400 LAB 7 1 JK Bennett This lab will introduce you to how to create terrain. We will first review some basic principles of 3D graphics, and will gradually add complexity until we have a reasonably

More information

XNA 4.0 RPG Tutorials. Part 3. Even More Core Game Components

XNA 4.0 RPG Tutorials. Part 3. Even More Core Game Components XNA 4.0 RPG Tutorials Part 3 Even More Core Game Components I'm writing these tutorials for the new XNA 4.0 framework. The tutorials will make more sense if they are read in order. You can find the list

More information

XNA 4.0 RPG Tutorials. Part 5. The Tile Engine - Part 2

XNA 4.0 RPG Tutorials. Part 5. The Tile Engine - Part 2 XNA 4.0 RPG Tutorials Part 5 The Tile Engine - Part 2 I'm writing these tutorials for the new XNA 4.0 framework. The tutorials will make more sense if they are read in order. You can find the list of tutorials

More information

Creating a Role Playing Game with XNA Game Studio 3.0 Part 7 Adding Sprites

Creating a Role Playing Game with XNA Game Studio 3.0 Part 7 Adding Sprites Creating a Role Playing Game with XNA Game Studio 3.0 Part 7 Adding Sprites To follow along with this tutorial you will have to have read the previous tutorials to understand much of what it going on.

More information

A Summoner's Tale MonoGame Tutorial Series. Chapter 13. Leveling Up

A Summoner's Tale MonoGame Tutorial Series. Chapter 13. Leveling Up A Summoner's Tale MonoGame Tutorial Series Chapter 13 Leveling Up This tutorial series is about creating a Pokemon style game with the MonoGame Framework called A Summoner's Tale. The tutorials will make

More information

Xna0118-The XNA Framework and. the Game Class

Xna0118-The XNA Framework and. the Game Class OpenStax-CNX module: m49509 1 Xna0118-The XNA Framework and * the Game Class R.G. (Dick) Baldwin This work is produced by OpenStax-CNX and licensed under the Creative Commons Attribution License 4.0 Abstract

More information

How to Program a Primitive Twin-Stick Shooter in Monogame 3.4

How to Program a Primitive Twin-Stick Shooter in Monogame 3.4 How to Program a Primitive Twin-Stick Shooter in Monogame 3.4 This is a tutorial for making a basic twin-stick style shooter in C# using Monogame 3.4 and Microsoft Visual Studio. This guide will demonstrate

More information

A Summoner's Tale MonoGame Tutorial Series. Chapter 3. Tile Engine and Game Play State

A Summoner's Tale MonoGame Tutorial Series. Chapter 3. Tile Engine and Game Play State A Summoner's Tale MonoGame Tutorial Series Chapter 3 Tile Engine and Game Play State This tutorial series is about creating a Pokemon style game with the MonoGame Framework called A Summoner's Tale. The

More information

A Summoner's Tale MonoGame Tutorial Series. Chapter 11. Battling Avatars

A Summoner's Tale MonoGame Tutorial Series. Chapter 11. Battling Avatars A Summoner's Tale MonoGame Tutorial Series Chapter 11 Battling Avatars This tutorial series is about creating a Pokemon style game with the MonoGame Framework called A Summoner's Tale. The tutorials will

More information

Collision Detection Concept

Collision Detection Concept Collision Detection Collision Detection Concept When two fireflies collide we tag them for removal and add an explosion to the blasts list. The position and velocity of the explosion is set to the average

More information

ICS3C/4C/3U/4U Unit 2 Workbook Selection: If Statement

ICS3C/4C/3U/4U Unit 2 Workbook Selection: If Statement Selection: If Statement Selection allows a computer to do different things based on the situation. The if statement checks if something is true and then runs the appropriate code. We will start learning

More information

Computer Games 2011 Selected Game Engines

Computer Games 2011 Selected Game Engines Computer Games 2011 Selected Game Engines Dr. Mathias Lux Klagenfurt University This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 libgdx features High-performance,

More information

2D Graphics in XNA Game Studio Express (Modeling a Class in UML)

2D Graphics in XNA Game Studio Express (Modeling a Class in UML) 2D Graphics in XNA Game Studio Express (Modeling a Class in UML) Game Design Experience Professor Jim Whitehead February 5, 2008 Creative Commons Attribution 3.0 creativecommons.org/licenses/by/3.0 Announcements

More information

Eyes of the Dragon - XNA Part 33 Non-Player Character Conversations

Eyes of the Dragon - XNA Part 33 Non-Player Character Conversations Eyes of the Dragon - XNA Part 33 Non-Player Character Conversations I'm writing these tutorials for the XNA 4.0 framework. Even though Microsoft has ended support for XNA it still runs on all supported

More information

XNA 4.0 RPG Tutorials. Part 22. Reading Data

XNA 4.0 RPG Tutorials. Part 22. Reading Data XNA 4.0 RPG Tutorials Part 22 Reading Data I'm writing these tutorials for the new XNA 4.0 framework. The tutorials will make more sense if they are read in order. You can find the list of tutorials on

More information

Game1.cs class that derives (extends) Game public class Game1 : Microsoft.Xna.Framework.Game {..}

Game1.cs class that derives (extends) Game public class Game1 : Microsoft.Xna.Framework.Game {..} MonoGames MonoGames Basics 1 MonoGames descends from XNA 4, is a framework for developing C# games for Windows, Linux, Mac, Android systems. Visual Studio MonoGames projects will create: Program.cs class

More information

IWKS 3400 LAB 11 1 JK Bennett

IWKS 3400 LAB 11 1 JK Bennett IWKS 3400 LAB 11 1 JK Bennett This lab dives a little bit deeper into HLSL effects, particularly as they relate to lighting and shading. We will begin by reviewing some basic 3D principles, and then move

More information

Session 5.1. Writing Text

Session 5.1. Writing Text 1 Session 5.1 Writing Text Chapter 5.1: Writing Text 2 Session Overview Show how fonts are managed in computers Discover the difference between bitmap fonts and vector fonts Find out how to create font

More information

A Summoner's Tale MonoGame Tutorial Series. Chapter 12. Battling Avatars Continued

A Summoner's Tale MonoGame Tutorial Series. Chapter 12. Battling Avatars Continued A Summoner's Tale MonoGame Tutorial Series Chapter 12 Battling Avatars Continued This tutorial series is about creating a Pokemon style game with the MonoGame Framework called A Summoner's Tale. The tutorials

More information

CMPS 20: Game Design Experience. January 14, 2010 Arnav Jhala

CMPS 20: Game Design Experience. January 14, 2010 Arnav Jhala CMPS 20: Game Design Experience January 14, 2010 Arnav Jhala foreach ( type identifier in array-or-collection ) { } Foreach Statement Iterates through all elements in an array, or collection type Creates

More information

Session A First Game Program

Session A First Game Program 1 Session 11.1 A First Game Program Chapter 11.1: A First Game Program 2 Session Overview Begin the creation of an arcade game Learn software design techniques that apply to any form of game development

More information

Platform Games Drawing Sprites & Detecting Collisions

Platform Games Drawing Sprites & Detecting Collisions Platform Games Drawing Sprites & Detecting Collisions Computer Games Development David Cairns Contents Drawing Sprites Collision Detection Animation Loop Introduction 1 Background Image - Parallax Scrolling

More information

Course 3D_XNA: 3D-Computer Graphics with XNA Chapter C5: Dice with Texture

Course 3D_XNA: 3D-Computer Graphics with XNA Chapter C5: Dice with Texture Course 3D_XNA: 3D-Computer Graphics with XNA Chapter C5: Dice with Texture 1 XBox 360 Controller Project dice1 The Complete Code of Game1.cs The Complete Data of dice.x Experiments Copyright by V. Miszalok,

More information

XNA Development: Tutorial 6

XNA Development: Tutorial 6 XNA Development: Tutorial 6 By Matthew Christian (Matt@InsideGamer.org) Code and Other Tutorials Found at http://www.insidegamer.org/xnatutorials.aspx One of the most important portions of a video game

More information

Hands-On Lab. 2D Game Development with XNA Framework. Lab version: Last updated: 2/2/2011. Page 1

Hands-On Lab. 2D Game Development with XNA Framework. Lab version: Last updated: 2/2/2011. Page 1 Hands-On Lab 2D Game Development with XNA Framework Lab version: 1.0.0 Last updated: 2/2/2011 Page 1 CONTENTS OVERVIEW... 3 EXERCISE 1: BASIC XNA FRAMEWORK GAME WITH GAME STATE MANAGEMENT... 4 General

More information

Pong in Unity a basic Intro

Pong in Unity a basic Intro This tutorial recreates the classic game Pong, for those unfamiliar with the game, shame on you what have you been doing, living under a rock?! Go google it. Go on. For those that now know the game, this

More information

Creating Breakout - Part 2

Creating Breakout - Part 2 Creating Breakout - Part 2 Adapted from Basic Projects: Game Maker by David Waller So the game works, it is a functioning game. It s not very challenging though, and it could use some more work to make

More information

Slides built from Carter Chapter 10

Slides built from Carter Chapter 10 Slides built from Carter Chapter 10 Animating Sprites (textures) Images from wikipedia.org Animating Sprites (textures) Images from wikipedia.org Lets Add to Our XELibrary Going to add a CelAnimationManager

More information

Developing Games with MonoGame*

Developing Games with MonoGame* Developing Games with MonoGame* By Bruno Sonnino Developers everywhere want to develop games. And why not? Games are among the best sellers in computer history, and the fortunes involved in the game business

More information

XNA 4.0 RPG Tutorials. Part 16. Quests and Conversations

XNA 4.0 RPG Tutorials. Part 16. Quests and Conversations XNA 4.0 RPG Tutorials Part 16 Quests and Conversations I'm writing these tutorials for the new XNA 4.0 framework. The tutorials will make more sense if they are read in order. You can find the list of

More information

+ Inheritance. Sometimes we need to create new more specialized types that are similar to types we have already created.

+ Inheritance. Sometimes we need to create new more specialized types that are similar to types we have already created. + Inheritance + Inheritance Classes that we design in Java can be used to model some concept in our program. For example: Pokemon a = new Pokemon(); Pokemon b = new Pokemon() Sometimes we need to create

More information

msdn Hands-On Lab 3D Game Development with XNA Framework Lab version: Last updated: 12/8/2010 Page 1

msdn Hands-On Lab 3D Game Development with XNA Framework Lab version: Last updated: 12/8/2010 Page 1 msdn Hands-On Lab 3D Game Development with XNA Framework Lab version: 1.0.0 Last updated: 12/8/2010 Page 1 CONTENTS OVERVIEW... 2 EXERCISE 1: BASIC XNA GAME STUDIO GAME WITH GAME STATE MANAGEMENT... 4

More information

Introduction to Unreal Engine Blueprints for Beginners. By Chaven R Yenketswamy

Introduction to Unreal Engine Blueprints for Beginners. By Chaven R Yenketswamy Introduction to Unreal Engine Blueprints for Beginners By Chaven R Yenketswamy Introduction My first two tutorials covered creating and painting 3D objects for inclusion in your Unreal Project. In this

More information

LECTURE 4. Announcements

LECTURE 4. Announcements LECTURE 4 Announcements Retries Email your grader email your grader email your grader email your grader email your grader email your grader email your grader email your grader email your grader email your

More information

2D Graphics in XNA Game Studio Express (Plus, Random numbers in C#)

2D Graphics in XNA Game Studio Express (Plus, Random numbers in C#) 2D Graphics in XNA Game Studio Express (Plus, Random numbers in C#) Game Design Experience Professor Jim Whitehead January 16, 2009 Creative Commons Attribution 3.0 creativecommons.org/licenses/by/3.0

More information

AN INTRODUCTION TO SCRATCH (2) PROGRAMMING

AN INTRODUCTION TO SCRATCH (2) PROGRAMMING AN INTRODUCTION TO SCRATCH (2) PROGRAMMING Document Version 2 (04/10/2014) INTRODUCTION SCRATCH is a visual programming environment and language. It was launched by the MIT Media Lab in 2007 in an effort

More information

Hands-On Lab. 3D Game Development with XNA Framework. Lab version: Last updated: 2/2/2011. Page 1

Hands-On Lab. 3D Game Development with XNA Framework. Lab version: Last updated: 2/2/2011. Page 1 Hands-On Lab 3D Game Development with XNA Framework Lab version: 1.0.0 Last updated: 2/2/2011 Page 1 CONTENTS OVERVIEW... 3 EXERCISE 1: BASIC XNA GAME STUDIO GAME WITH GAME STATE MANAGEMENT... 5 Task 1

More information

Computer Graphics - Treasure Hunter

Computer Graphics - Treasure Hunter Computer Graphics - Treasure Hunter CS 4830 Dr. Mihail September 16, 2015 1 Introduction In this assignment you will implement an old technique to simulate 3D scenes called billboarding, sometimes referred

More information

Please go to the Riemer s 2D XNA Tutorial for C# by clicking on You are allowed to progress ahead of me by

Please go to the Riemer s 2D XNA Tutorial for C# by clicking on   You are allowed to progress ahead of me by 2D Shooter game- Part 2 Please go to the Riemer s 2D XNA Tutorial for C# by clicking on http://bit.ly/riemers2d You are allowed to progress ahead of me by reading and doing to tutorial yourself. I ll

More information

Chapter 1. Getting to Know Illustrator

Chapter 1. Getting to Know Illustrator Chapter 1 Getting to Know Illustrator Exploring the Illustrator Workspace The arrangement of windows and panels that you see on your monitor is called the workspace. The Illustrator workspace features

More information

1 Getting started with Processing

1 Getting started with Processing cis3.5, spring 2009, lab II.1 / prof sklar. 1 Getting started with Processing Processing is a sketch programming tool designed for use by non-technical people (e.g., artists, designers, musicians). For

More information

Understanding XNA Framework Performance. Shawn Hargreaves Software Development Engineer XNA Community Game Platform Microsoft

Understanding XNA Framework Performance. Shawn Hargreaves Software Development Engineer XNA Community Game Platform Microsoft Understanding XNA Framework Performance Shawn Hargreaves Software Development Engineer XNA Community Game Platform Microsoft Contents Graphics Offload to the GPU Understand Xbox 360 system calls SpriteBatch,

More information

Smoother Graphics Taking Control of Painting the Screen

Smoother Graphics Taking Control of Painting the Screen It is very likely that by now you ve tried something that made your game run rather slow. Perhaps you tried to use an image with a transparent background, or had a gazillion objects moving on the window

More information

XNA 4.0 RPG Tutorials. Part 25. Level Editor Continued

XNA 4.0 RPG Tutorials. Part 25. Level Editor Continued XNA 4.0 RPG Tutorials Part 25 Level Editor Continued I'm writing these tutorials for the new XNA 4.0 framework. The tutorials will make more sense if they are read in order. You can find the list of tutorials

More information

UI Elements. If you are not working in 2D mode, you need to change the texture type to Sprite (2D and UI)

UI Elements. If you are not working in 2D mode, you need to change the texture type to Sprite (2D and UI) UI Elements 1 2D Sprites If you are not working in 2D mode, you need to change the texture type to Sprite (2D and UI) Change Sprite Mode based on how many images are contained in your texture If you are

More information

3D Graphics with XNA Game Studio 4.0

3D Graphics with XNA Game Studio 4.0 3D Graphics with XNA Game Studio 4.0 Create attractive 3D graphics and visuals in your XNA games Sean James BIRMINGHAM - MUMBAI 3D Graphics with XNA Game Studio 4.0 Copyright 2010 Packt Publishing All

More information

Workshop BOND UNIVERSITY. Bachelor of Interactive Multimedia and Design. Asteroids

Workshop BOND UNIVERSITY. Bachelor of Interactive Multimedia and Design. Asteroids Workshop BOND UNIVERSITY Bachelor of Interactive Multimedia and Design Asteroids FACULTY OF SOCIETY AND DESIGN Building an Asteroid Dodging Game Penny de Byl Faculty of Society and Design Bond University

More information

Visual C# Program: Simple Game 3

Visual C# Program: Simple Game 3 C h a p t e r 6C Visual C# Program: Simple Game 3 In this chapter, you will learn how to use the following Visual C# Application functions to World Class standards: Opening Visual C# Editor Beginning a

More information

Making use of other Applications

Making use of other Applications AppGameKit 2 Collision Using Arrays Making use of other Applications Although we need game software to help makes games for modern devices, we should not exclude the use of other applications to aid the

More information

Programs, Data, and Pretty Colors

Programs, Data, and Pretty Colors C02625228.fm Page 19 Saturday, January 19, 2008 8:36 PM Chapter 2 Programs, Data, and Pretty Colors In this chapter: Introduction...........................................................19 Making a Game

More information

A Summoner's Tale MonoGame Tutorial Series. Chapter 15. Saving Game State

A Summoner's Tale MonoGame Tutorial Series. Chapter 15. Saving Game State A Summoner's Tale MonoGame Tutorial Series Chapter 15 Saving Game State This tutorial series is about creating a Pokemon style game with the MonoGame Framework called A Summoner's Tale. The tutorials will

More information

Adding Depth to Games

Adding Depth to Games Game Maker Tutorial Adding Depth to Games Written by Mark Overmars Copyright 2007-2009 YoYo Games Ltd Last changed: December 23, 2009 Uses: Game Maker 8.0, Pro Edition, Advanced Mode Level: Intermediate

More information

CS Programming Exercise:

CS Programming Exercise: CS Programming Exercise: An Introduction to Java and the ObjectDraw Library Objective: To demonstrate the use of objectdraw graphics primitives and Java programming tools This lab will introduce you to

More information

PixelSurface a dynamic world of pixels for Unity

PixelSurface a dynamic world of pixels for Unity PixelSurface a dynamic world of pixels for Unity Oct 19, 2015 Joe Strout joe@luminaryapps.com Overview PixelSurface is a small class library for Unity that lets you manipulate 2D graphics on the level

More information

Introduction to the Graphics Module Framework

Introduction to the Graphics Module Framework Introduction to the Graphics Module Framework Introduction Unlike the C++ module, which required nothing beyond what you typed in, the graphics module examples rely on lots of extra files - shaders, textures,

More information

Fruit Snake SECTION 1

Fruit Snake SECTION 1 Fruit Snake SECTION 1 For the first full Construct 2 game you're going to create a snake game. In this game, you'll have a snake that will "eat" fruit, and grow longer with each object or piece of fruit

More information

Bloom effect - before. Bloom effect - after. Postprocessing. Motion blur in Valve s Portal - roll

Bloom effect - before. Bloom effect - after. Postprocessing. Motion blur in Valve s Portal - roll Bloom effect - before Postprocessing Prof. Aaron Lanterman School of Electrical and Computer Engineering Georgia Institute of Technology 2 Bloom effect - after Motion blur in Valve s Portal - roll 3 http://www.valvesoftware.com/publications/2008/

More information

Explain the significance of using a computer programming language. Describe the basic template of the Monogame framework.

Explain the significance of using a computer programming language. Describe the basic template of the Monogame framework. I can Explain the significance of using a computer programming language. Describe the basic template of the Monogame framework. A series of steps (actions) performed in a specific order Specifies The ACTIONS

More information

: Rendered background can show navigation mesh : Multi-level backgrounds, priority backgrounds and Z-ordering.

: Rendered background can show navigation mesh : Multi-level backgrounds, priority backgrounds and Z-ordering. Update history: 2017-04-13: Initial release on Marketplace for UE4.15. 2017-05-09: Rendered background can show navigation mesh. 2017-05-19: Multi-level backgrounds, priority backgrounds and Z-ordering.

More information

Better UI Makes ugui Better!

Better UI Makes ugui Better! Better UI Makes ugui Better! 2016 Thera Bytes UG Developed by Salomon Zwecker TABLE OF CONTENTS Better UI... 1 Better UI Elements... 4 1 Workflow: Make Better... 4 2 UI and Layout Elements Overview...

More information

For efficiency, the graphics card will render objects as triangles Any polyhedron can be represented by triangles Other 3D shapes can be approximated

For efficiency, the graphics card will render objects as triangles Any polyhedron can be represented by triangles Other 3D shapes can be approximated By Chris Ewin For efficiency, the graphics card will render objects as triangles Any polyhedron can be represented by triangles Other 3D shapes can be approximated by triangles Source: Wikipedia Don t

More information

the gamedesigninitiative at cornell university Lecture 14 2D Sprite Graphics

the gamedesigninitiative at cornell university Lecture 14 2D Sprite Graphics Lecture 14 Drawing Images Graphics Lectures SpriteBatch interface Coordinates and Transforms Drawing Perspective Camera Projections Drawing Primitives Color and Textures Polygons 2 Drawing Images Graphics

More information

10 Connector Designer

10 Connector Designer PRELIMINARY Connector Designer 10-1 10 Connector Designer About this Section In this section you will learn how to create your own custom connectors and edit them using the optional software connector

More information

Shadows in the graphics pipeline

Shadows in the graphics pipeline Shadows in the graphics pipeline Steve Marschner Cornell University CS 569 Spring 2008, 19 February There are a number of visual cues that help let the viewer know about the 3D relationships between objects

More information

Learning to use the drawing tools

Learning to use the drawing tools Create a blank slide This module was developed for Office 2000 and 2001, but although there are cosmetic changes in the appearance of some of the tools, the basic functionality is the same in Powerpoint

More information

CISC 1600, Lab 2.3: Processing animation, objects, and arrays

CISC 1600, Lab 2.3: Processing animation, objects, and arrays CISC 1600, Lab 2.3: Processing animation, objects, and arrays Prof Michael Mandel 1 Getting set up For this lab, we will again be using Sketchpad. sketchpad.cc in your browser and log in. Go to http://cisc1600.

More information

A simple OpenGL animation Due: Wednesday, January 27 at 4pm

A simple OpenGL animation Due: Wednesday, January 27 at 4pm CMSC 23700 Winter 2010 Introduction to Computer Graphics Project 1 January 12 A simple OpenGL animation Due: Wednesday, January 27 at 4pm 1 Summary This project is the first part of a three-part project.

More information

Session 6. Microsoft and The DigiPen Institute of Technology Webcast Series

Session 6. Microsoft and The DigiPen Institute of Technology Webcast Series Session 6 Microsoft and The DigiPen Institute of Technology Webcast Series HOW TO USE THIS DOCUMENT This e-textbook has been distributed electronically using the Adobe Portable Document Format (PDF) format.

More information

CS1950U Setup Spring 2018

CS1950U Setup Spring 2018 CS1950U Topics in 3D Game Engine Development Barbara Meier CS1950U Setup Spring 2018 Introduction Hi there! This guide is designed to help you get setup for taking CS1950U. It will go through the basics

More information

Session 5.2. Creating Clocks

Session 5.2. Creating Clocks 1 Session 5.2 Creating Clocks Chapter 5.2: Creating Clocks 2 Session Overview Find out how to obtain and use the current date and time in a C# program using the DateTime type Discover how to extract a

More information

Tutorial 4: Texture Mapping Techniques

Tutorial 4: Texture Mapping Techniques Tutorial 4: Texture Mapping Techniques Completion time 40 minutes In the previous tutorial we learned how to create materials, and how to assign texture maps to those materials. In this tutorial we will

More information

Chapter 6 Reacting to Player Input

Chapter 6 Reacting to Player Input Chapter 6 Reacting to Player Input 6.1 Introduction In this chapter, we will show you how your game program can react to mouse clicks and button presses. In order to do this, we need a instruction called

More information

LIGHTCONVERSE TOOLS Interface Overview

LIGHTCONVERSE TOOLS Interface Overview MANUAL 1 Contents Contents... 1 LIGHTCONVERSE TOOLS Interface Overview... 2 Tool Manager... 3 Mouse... 4 Mouse Control Operation:... 4 3D Space Area... 4 Modes... 5 Balance Calculator in Warehouse Mode...

More information

Erasmus+ Project: Yestermorrow Year 1 Maths: Pythagorean Theorem

Erasmus+ Project: Yestermorrow Year 1 Maths: Pythagorean Theorem Erasmus+ Project: Yestermorrow Year 1 Maths: Pythagorean Theorem Workshop (Coding Android Mobile Apps): Collision Detection and the Pythagorean Theorem (Based on the code.org worksheet) WORKSHOP OVERVIEW

More information

2D rendering takes a photo of the 2D scene with a virtual camera that selects an axis aligned rectangle from the scene. The photograph is placed into

2D rendering takes a photo of the 2D scene with a virtual camera that selects an axis aligned rectangle from the scene. The photograph is placed into 2D rendering takes a photo of the 2D scene with a virtual camera that selects an axis aligned rectangle from the scene. The photograph is placed into the viewport of the current application window. A pixel

More information

Computer Games Development Spring Practical 3 GameCore, Transforms & Collision Detection

Computer Games Development Spring Practical 3 GameCore, Transforms & Collision Detection In this practical we are going to look at the GameCore class in some detail and then move on to examine the use of transforms, collision detection and tile maps. Combined with the material concerning sounds

More information

Google SketchUp/Unity Tutorial Basics

Google SketchUp/Unity Tutorial Basics Software used: Google SketchUp Unity Visual Studio Google SketchUp/Unity Tutorial Basics 1) In Google SketchUp, select and delete the man to create a blank scene. 2) Select the Lines tool and draw a square

More information

[ the academy_of_code] Senior Beginners

[ the academy_of_code] Senior Beginners [ the academy_of_code] Senior Beginners 1 Drawing Circles First step open Processing Open Processing by clicking on the Processing icon (that s the white P on the blue background your teacher will tell

More information

Computer Games 2012 Game Development

Computer Games 2012 Game Development Computer Games 2012 Game Development Dr. Mathias Lux Klagenfurt University This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 libgdx features High-performance, cross-platform

More information

Tangents. In this tutorial we are going to take a look at how tangents can affect an animation.

Tangents. In this tutorial we are going to take a look at how tangents can affect an animation. Tangents In this tutorial we are going to take a look at how tangents can affect an animation. One of the 12 Principles of Animation is called Slow In and Slow Out. This refers to the spacing of the in

More information

Visualization Insider A Little Background Information

Visualization Insider A Little Background Information Visualization Insider A Little Background Information Visualization Insider 2 Creating Backgrounds for 3D Scenes Backgrounds are a critical part of just about every type of 3D scene. Although they are

More information

How to draw and create shapes

How to draw and create shapes Adobe Flash Professional Guide How to draw and create shapes You can add artwork to your Adobe Flash Professional documents in two ways: You can import images or draw original artwork in Flash by using

More information

Tutorial 3: Constructive Editing (2D-CAD)

Tutorial 3: Constructive Editing (2D-CAD) (2D-CAD) The editing done up to now is not much different from the normal drawing board techniques. This section deals with commands to copy items we have already drawn, to move them and to make multiple

More information

Avid FX Tutorials. Understanding the Tutorial Exercises

Avid FX Tutorials. Understanding the Tutorial Exercises Avid FX Tutorials Understanding the Tutorial Exercises The following tutorial exercises provide step-by-step instructions for creating various kinds of effects, while exploring many aspects of the Avid

More information

Programming Project 1

Programming Project 1 Programming Project 1 Handout 6 CSCI 134: Fall, 2016 Guidelines A programming project is a laboratory that you complete on your own, without the help of others. It is a form of take-home exam. You may

More information

How to Create a Simple Animation Using MAYA

How to Create a Simple Animation Using MAYA How to Create a Simple Animation Using MAYA Jennifer Soltz July 29, 2011 0 Table of Contents Introduction Safety Information. 2. 3 What you need Materials Overview Diagram. 4. 4 Instructions Setup Modeling

More information

Beaumont Middle School Design Project April May 2014 Carl Lee and Craig Schroeder

Beaumont Middle School Design Project April May 2014 Carl Lee and Craig Schroeder Beaumont Middle School Design Project April May 2014 Carl Lee and Craig Schroeder 1 2 SketchUp 1. SketchUp is free, and you can download it from the website www.sketchup.com. For some K12 use, see www.sketchup.com/3dfor/k12-education.

More information

animation, and what interface elements the Flash editor contains to help you create and control your animation.

animation, and what interface elements the Flash editor contains to help you create and control your animation. e r ch02.fm Page 43 Wednesday, November 15, 2000 8:52 AM c h a p t 2 Animating the Page IN THIS CHAPTER Timelines and Frames Movement Tweening Shape Tweening Fading Recap Advanced Projects You have totally

More information