3. Topics Overview of XNA How games run The XNA Game class Adding and managing game assets Creating and drawing game sprites
4. XNA XNA is a framework for writing games It includes a set of professional tools for game production and resource management Windows Phone uses version 4.0 of the framework This is included as part of the Windows Phone SDK
5. 2D and 3D games XNA provides full support for 3D games It allows a game program to make full use of the underlying hardware acceleration provided by the graphics hardware For the purpose of this course we are going to focus on 2D gaming Windows Phone games be either 2D or 3D 5
6. XNA and Silverlight XNA is completely different from Silverlight The way that programs are constructed and execute in XNA is quite different XNA has been optimised for game creation It does not have any elements for user interface or data binding Instead it has support for 3D rendering and game content management 6
7. XNA and Programs XNA provides a set of classes which allow you to create gameplay The classes represent game information and XNA resources XNA is also a very good example of how you construct and deploy a set of software resources in a Framework
8. Creating a Game The Windows Phone SDK provides a Windows Phone game project type
9. The Game Project The solution explorer shows the items that make up our game project The solution will also contain any content that we add to the game project
10. Empty Game Display At the moment all our game does is display a blue screen This is because the behaviour of the Draw method in a brand new project is to clear the screen to blue
12. What a Game Does When it Runs Initialise all the resources at the start fetch all textures, models, scripts etc Repeatedly run the game: Update the game world read the user input, update the state and position of game elements Draw the game world render the game elements on the viewing device
14. XNA Methods and games Note that our program never calls the LoadContent, Draw and Update methods They are called by the XNA Framework LoadContent is called when the game starts Draw is called as often as possible Update is called 30 times a second Note that this is not the same as an XNA game on Windows PC or Xbox, where Update is called 60 times a second 14
15. Loading Game Content protectedoverridevoidLoadContent() { // Create a new SpriteBatch, which can be used to // draw textures. spriteBatch = newSpriteBatch(GraphicsDevice); } LoadContent is called when our game starts It is where we put the code that loads the content into our game Content includes images, sounds, models etc.
16. Game Content Games are not just programs, they also contain other content: Images for textures and backgrounds Sound Effects 3D Object Meshes We need to add this content to our project The XNA framework provides a content management system which is integrated into Visual Studio
17. Image Resources This is a Ball image I have saved it as a PNG file This allows the image to use transparency You can use any image resource you like The resources are added to the Visual Studio project They are held in the Content directory as part of your project
18. Using the Content Pipeline Each resource is given an asset name The Load method of Content Manager provides access to the resource using the Asset Name that we gave it ballTexture = Content.Load<Texture2D>("WhiteDot");
19. Storing the Ball Texture in the game // Game World Texture2D ballTexture; XNA provides a Texture2Dtype which holds a 2D (flat) texture to be drawn on the display The game class needs to contain a member variable to hold the ball texture that is to be drawn when the game runs This variable will be shared by all the methods in the game
20. Loading Content into the Ball Texture protectedoverridevoidLoadContent() { // Create a new SpriteBatch, which can be used to // draw textures. spriteBatch = newSpriteBatch(GraphicsDevice); ballTexture = Content.Load<Texture2D>("WhiteDot"); } LoadContentis called when a game starts It loads an image into the ball texture The content manager fetches the images which are automatically sent to the target device
21. Making a “sprite” A sprite is an object on the screen of a game It has both a texture and a position on the screen We are creating a sprite object for the ball in our game We now have the texture for the object The next thing to do is position it on the screen 21
22. Coordinates and Pixels When drawing in XNA the position of an object on the screen is given using coordinates based on pixels A standard Windows Phone screen is 800 pixels wide and 480 pixels high This gives the range of possible values for display coordinates If you draw things off the screen this does not cause XNA problems, but nothing is drawn 22
23. X and Y in XNA The coordinate system used by XNA sprite drawing puts the origin (0,0) in the top left hand corner of the screen Increasing X moves an object across the screen towards the right Increasing Y moves an object down the screen towards the bottom It is important that you remember this 23
24. Positioning the Ball using a Rectangle // Game World Texture2DballTexture; RectangleballRectangle; We can add a rectangle value to the game to manage the position of the ball on the screen We will initialise it in the LoadContent method
25. The Rectangle structure Rectangle ballRectangle = newRectangle( 0, 0, ballTexture.Width, ballTexture.Height), Color.White); Rectangle is a struct type which contains a position and a size The code above creates a rectangle positioned at 0,0 (top left hand corner) the same size as ballTexture We could move our ball by changing the content of the rectangle
26. Drawing a Sprite In game programming terms a “sprite” is a texture that can be positioned on the screen We now have a ball sprite We have the texture that contains an image of the ball We have a rectangle that gives the position and size of the sprite itself 26
27. XNA Game Draw Method protectedoverridevoid Draw(GameTimegameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); base.Draw(gameTime); } The Draw method is called repeatedly when an XNA game is running It has the job of drawing the display on the screen A brand new XNA game project contains a Draw method that clears the screen to CornflowerBlue We must add our own code to the method to draw the ball
28. Sprite Batching 2D Graphics drawing is handled by a set of “sprite” drawing methods provided by XNA These create commands that are passed to the graphics device The graphics device will not want to draw everything on a piecemeal basis Ideally all the drawing information, textures and transformations should be provided as a single item The SpriteBatch class looks after this for us
29. SpriteBatch Begin and End protectedoverridevoid Draw(GameTimegameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); // Code that uses spriteBatch to draw the display spriteBatch.End(); base.Draw(gameTime); } The call to the Begin method tells SpriteBatch to begin a assembling a new set of drawing operations The call to the End method tells SpriteBatch that the there are no more operations and causes the rendering to take place
30. Using SpriteBatch.Draw spriteBatch.Draw(ballTexture, ballRectangle, Color.White); The SpriteBatch class provides a Draw method to do the sprite drawing It is given parameters to tell it what to do: Texture to draw Position (expressed as a Rectangle) Draw color
31. Rectangle Fun new Rectangle( 0, 0, ballTexture.Width, ballTexture.Height) new Rectangle( 0, 0, // position 200,100) // size new Rectangle( 50, 50, // position 60, 60) // size
33. Screen Size and Scaling We need to make our game images fit the size of the screen We can find out the size of the screen from the GraphicsDevice used to draw it GraphicsDevice.Viewport.WidthGraphicsDevice.Viewport.Height We can use this information to scale the images on the screen
34. Creating the ballRectangle variable ballRectangle = newRectangle( 0, 0, GraphicsDevice.Viewport.Width / 20, GraphicsDevice.Viewport.Width/ 20); If we use this rectangle to draw our ball texture it will be drawn as a square which is a twentieth of the width of the screen We can then set the position parts of the rectangle to move the ball around the screen
35. Moving the ball around the screen At the moment the ball is drawn in the same position each time Draw runs To move the ball around we need to make this position change over time We need to give the game an update behaviour We must add code to the Update method in the game The Update method is where we manage the state of the “game world”
36. The Update Method protectedoverridevoid Update(GameTimegameTime) { // TODO: Add your update logic here base.Update(gameTime); } The Update method is automatically called 30 times a second when a game is running It is in charge of managing the “game world” In a pong game this means updating the bat and the ball positions and checking for collisions
37. Simple Update Method protectedoverridevoid Update(GameTimegameTime) { ballRectangle.X++; ballRectangle.Y++; base.Update(gameTime); } Each time the game updates the X and Y position of the ball rectangle is increased This will cause it to move across and down the screen Note that I call the base method to allow my parent object to update too
38. GameTime At the moment the Update method is called sixty time a second or once every 16.66 milliseconds We can also let the update "free run", in which case we need to know the time since the last call so we can move objects the right distance This is what the GameTime parameter is for, it gives the time at which the method was called
40. Summary XNA is a Framework of methods that are used to write games You create the games using Visual Studio Games have initialise, update and draw behaviours Game objects are held as textures objects and their position and dimensions as rectangle structures
42. Topics Controlling the movement of a sprite Creating multiple sprites Using touch input to control sprite movement Detecting sprite collisions Displaying text
43. XNA and Pong Last time we got a ball to move down the screen Now we need to make the ball bounce around the screen Now we need to discover how we can create paddles and control them using a gamepad or keyboard Then we can start building a game
44. Accurate ball positioning float ballX = 0; float ballY = 0; The Rectangle provides integer properties that can be used to position the drawing operation To get more precise control over the movement of an object we need to use floating point position variables
45. Accurate ball positioning ballRectangle.X = (int)(ballX + 0.5f); ballRectangle.Y = (int)(ballY+ 0.5f); The floating point position values are converted to integers to set the position of the draw rectangle This is performed during the Update method
46. Controlling Ball Movement float ballXSpeed = 3; float ballYSpeed = 3; To manage the speed of the ball we can use a pair of member variables in our game class One for the X speed and one for the Y speed Each time Update is called these are used to update the values of the X and Y position of the draw rectangle
47. Moving the Ball ballX = ballX + ballXSpeed; ballY= ballY + ballYSpeed; The Update method is where the speed values are used to update the rectangle position for the ball The next call of Draw will draw the ball in the new position
49. Making the Ball Bounce if (ballX < 0 || ballX+ ballRectangle.Width > GraphicsDevice.Viewport.Width) { ballXSpeed = -ballXSpeed; } When the ball reaches the edge of the screen it must change direction We can do this by reversing the sign of the speed value to reverse the effect of the update
51. Making a Paddle The paddle is made from a texture, just like the ball This time I’ve made a slightly more interesting one which uses transparency The paddle is loaded as a texture resource, just as the ball is
52. Game Variables // Game World Texture2DballTexture; RectangleballRectangle; floatballX; floatballY; floatballXSpeed = 3; floatballYSpeed = 3; Texture2DlPaddleTexture; RectanglelPaddleRectangle; floatlPaddleSpeed = 4; floatlPaddleY; // Repeat these for the right paddle // Distance of paddles from screen edge int margin;
53. Loading GameTextures protectedoverridevoid LoadContent() { ballTexture = Content.Load<Texture2D>("ball"); lPaddleTexture = Content.Load<Texture2D>("lpaddle"); rPaddleTexture = Content.Load<Texture2D>("rpaddle"); // scale the texture draw rectangles here } When the game starts the LoadContent method is called to load textures and other game assets We now have three textures in the game
54. Setting up the paddles margin = GraphicsDevice.Viewport.Width / 20; lPaddleRectangle =newRectangle( margin, 0, GraphicsDevice.Viewport.Width / 20, GraphicsDevice.Viewport.Height / 5); rPaddleRectangle = newRectangle( GraphicsDevice.Viewport.Width– lPaddleRectangle.Width- margin, 0, GraphicsDevice.Viewport.Width / 20, GraphicsDevice.Viewport.Height / 5); This code positions the paddles on the screen and sets up their sizes
55. Initial game positions The LoadContent method puts the paddles and balls at their starting positions as shown above 55
56. Paddle control We can use the Windows Phone touch screen to control a paddle The touch screen can track up to four inputs and can detect when touch events start and end We are just going to test for touches to move the paddle up or down 56
57. Getting the Touch Panel status TouchCollection touches = TouchPanel.GetState(); The TouchPanel class provides a GetState method that will return the touch panel status This returns a collection of TouchLocation values that describe the present state of the touch panel This can contain up to four values
58. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } If we have a touch location we use the position of the touch to move the paddle up or down
59. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } If the collection contains some TouchLocationwe update the paddle position
60. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } Get the touch location at the start of the collection
61. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } Test the Y component of the position of touch against half the height of the screen
62. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } Move the paddle down if the player touches the bottom half of the screen
63. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } Move the paddle up if the player touches the top half of the screen
64. Using the Touch information if (touches.Count > 0) { if (touches[0].Position.Y > GraphicsDevice.Viewport.Height/ 2) { lPaddleY = lPaddleY + lPaddleSpeed; } else { lPaddleY = lPaddleY - lPaddleSpeed; } } Remember that increasing Y moves things down the screen (origin at top left)
66. Detecting Collisions We need to make the ball bounce off the paddles when the two collide In the console version of the game we tested to see if ball and paddle occupied the same part of the screen In the case of XNA we need to see if the rectangles which control the position of the ball and paddle intersect
67. Rectangle Intersection if (ballRectangle.Intersects(lPaddleRectangle)) { ballXSpeed = -ballXSpeed; } The Rectangle structure provides a method called Intersects which can be used to detect if two rectangles intersect If the paddle and ball rectangles intersect we must reverse the X direction of movement of the ball to have it bounce off the paddle
68. Completing the Game A finished game must also detect when the ball reaches the edges of the screen This is when a point has been scored I will leave you to create this code However, you will also need to draw text on the screen to display messages to the players This turns out to be very easy
69. Adding a SpriteFont A SpriteFont is a content item that lets you draw text on the screen It provides a set of character designs of a particular size
70. SpriteFont XML The font used and the size are set in an XML file You can edit this to get different sizes and styles
71. Loading a Font SpriteFont font; protectedoverridevoidLoadContent() { // Rest of LoadContent here font = Content.Load<SpriteFont>("MessageFont");} The Content Manager will fetch the font The font can be stored in a variable which a member of the game class You can use multiple fonts if you want different text styles
72. Drawing text protectedoverridevoid Draw(GameTimegameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); spriteBatch.DrawString( font, "Hello world", newVector2(100, 100), Color.White); // Rest of Draw here } The DrawString method renders a string using the font that has been loaded
74. Summary Objects in games can be made to move by updating their position information It is best if the game manages position in floating point values The TouchPanel provides a collection of TouchLocation values that describe touch actions XNA games can draw text using SpriteFonts
76. Topics Using the Accelerometer to control gameplay Playing sounds in XNA games Playing sounds in Silverlight programs Using media in XNA games Windows Phone games and orientation
77. The Accelerometer The Accelerometer can measure acceleration in X, Y and Z You can use just the X and Y values to control sprites in 2D games The values that are returned are in the range -1 to +1 in each axis When the value is 0 this means the device is flat on that axis
78. XNA 4.0 Accelerometer The accelerometer in XNA 4.0 is event driven The accelerometer generates events when new readings are available You must bind a method to the event The method can store the settings for later use
79. XNA and Silverlight The reason why the accelerometer is event driven is that XNA actually uses the same sensor interface as Silverlight This means that we need to include the appropriate sensor library into our programs to obtain accelerometer readings
80. Adding the Sensors library We need to add Microsoft.Devices.Sensors to the solution references to bring in the library
81. Adding the Namespace usingMicrosoft.Devices.Sensors; Once you have added the library you can use the Sensors objects Adding the namespace to your program makes the code a bit cleaner Note that you only have to do this for the accelerometer
82. Creating an Accelerometer Accelerometeracc = newAccelerometer(); acc.ReadingChanged += newEventHandler<AccelerometerReadingEventArgs> (acc_ReadingChanged); acc.Start(); The above code runs in the Initialise method to set up the accelerometer Initialise is called by XNA when a game starts It creates a new Accelerometer, binds an event handler to it and then starts it running
83. Accelerometer Events Vector3accelState = Vector3.Zero; voidacc_ReadingChanged (object sender, AccelerometerReadingEventArgs e) { accelState.X = (float)e.X; accelState.Y = (float)e.Y; accelState.Z = (float)e.Z; } This method runs when a new reading is available from the accelerometer It copies the readings into a vector
84. Using the reading lPaddleY = lPaddleY - (accelState.X * lPaddleSpeed); The Pong game only needs to use a single axis This is the X axis, that runs along the long length of the phone We have to reverse the sense of the position update as the value of Y increases down the screen
85. The accelerometer and orientation The accelerometer provides the same readings irrespective of the orientation of the device In other words the direction of the axes does not change when the orientation changes For this reason I would advise you to fix the orientation of a tipping game
86. “Tipping” games The accelerometer makes it very easy to create “tipping” games, which simulate gravity moving items around the screen The further you tip the device the greater the force acting on the object This leads to a very simple physics model, which is actually very effective
88. Threads and Contention It turns out that there is a potential problem with the way we are using the accelerometer It is prone to errors caused by the way that we are using two separate threads of execution to work with the accelerometer values One thread stores the values in the vector The other thread reads the values back At the moment these threads are not synchronised, and this can cause problems
89. What might happen… Update runs and reads the X value of the acceleration The Accelerometer event fires and starts running. It generates and stores new values of X, Y and Z Update reads the Y and Z values from the updated values Update now has “scrambled” data
90. Processes and processors The problem is caused by the way that the operating system runs multiple processes Each process is given control for a small time interval and then another is allowed to run If one process is allowed to interrupt another we can get them “fighting” over data
91. Adding a Lock We solve the problem by using a “lock” object A process can “grab” the lock object and hold onto it while it does something that must not be interrupted At the end of the action it releases the lock object If another process needs to use the lock it will be paused until the lock becomes available
92. Accelerometer Events and Lock objectaccelLock = newobject(); voidacc_ReadingChanged (object sender, AccelerometerReadingEventArgs e) { lock (accelLock) { accelState.X = (float)e.X; accelState.Y = (float)e.Y; accelState.Z = (float)e.Z; } } The lock object is just a token which is grabbed and released by the lock keyword
93. Accelerometer Events and Lock lock (accelLock) { lPaddleY = lPaddleY - (accelState.X * lPaddleSpeed); } In the Update method the statement that uses the accelerometer reading is protected by a lock This means that it is not possible for the reading process to be interrupted
94. Locks and Programs The locking behaviour is provided by the operating system A process that cannot run because it is waiting for a lock will be held until it can It is important that code that uses a lock does not take a long time to complete This might cause other processes to get stuck waiting for the lock to become available
95. “Deadly Embrace” It is also important that two processes don’t each end up waiting for a lock the other has This causes both processes to be stuck You can do this by making a process either “produce” or “consume” data You only tend to get deadly embraces when a process is both a producer and a consumer
96. Sounds as Content XNA uses a Content Manager to look after the resources used by a game Each content type has a “pipeline” of processors that bring it into the project and then package it for inclusion in the game distributable You don’t need to worry how this works You can write your own content library if you wish
97. XNA Sound Types Sound effects wav files held in memory for quick playback Background music wma and mp3 files loaded and played Managed as media (more on this later)
98. Preparing Sounds A good tool for preparing sound files is Audacity It will also convert between mp3 and wav format You can download it for free from http://audacity.sourceforge.net/
99. Adding Content The simplest way to add content is to drag and drop it into the solution You can place it alongside images, or in separate folders
100. Content Properties The content Properties pane identifies the asset name and the importer to use
101. SoundEffect variables // Sound effects SoundEffectdingSound; SoundEffectexplodeSound; These game member variables hold the sound effects for the “Pong” game They will be initialised with content when the game starts running We do this in LoadContent method does this
102. The LoadContent method protectedoverridevoidLoadContent() { // rest of LoadContent here dingSound= Content.Load<SoundEffect>("ding"); explodeSound = Content.Load<SoundEffect>("explode"); } LoadContent is called when the game starts The game contains a Content Manager which manages game content (surprisingly) The Load method uses Generics to determine the required loader
103. Simple Sound Playback if (ballY < 0 || ballY+ ballRectangle.Height > GraphicsDevice.Viewport.Height) { ballYSpeed = -ballYSpeed; dingSound.Play(); } An instance of the SoundEffect class provides a Play method that plays the sound instantly The Pong game will play the ding sound when the ball hits the top or bottom of the screen
104. Complex Sound Playback Sometimes the sound playback is more complex We might want to play an engine sound continuously when the “engine” is running We might also want to vary the pitch of the sound as it plays To do this we use a SoundEffectInstance This is an object that serves as a handle to a playing sound
105. The SoundEffectInstance engineInstance = engineSound.CreateInstance(); When we call the Play method on a sound effect this is a “fire and forget” kind of sound playback To get more control over a sound we need to create an object that represents it A SoundEffect can be asked to create an object representing an instance of a sound being played by using the CreateInstance method
106. Playing Sounds engineInstance.Play(); ... engineInstance.Pause(); ... engineInstance.Stop(); The Play method on a SoundEffectInstance will start sound playback We can also call Pause and Stop to control the sound
107. Controlling Volume engineInstance.Volume= accelVector.Length() / volFactor; The Volume property lets you adjust the volume of a playing sound The range is from 0 to 1: 0 no sound +1 maximum volume
108. Controlling Pitch engineInstance.Pitch = accelVector.Length() / soundFactor; The Pitch property lets you adjust the pitch of a playing sound The range is from -1 to 1: -1 octave low 0 normal pitch +1 octave high
109. Controlling Position engineInstance.Pan = cheesePan; The Pan property lets you adjust the pan position of a playing sound The range is from -1 to 1: -1 hard left 0 center +1 right
110. Sound Status if (engineInstance.State == SoundState.Stopped) { engineInstance.Play(); } The SoundEffectInstance exposes a property that gives the playing status This is updated when the sound stops playing The code above will play the sound again if it is stopped This is a primitive kind of looping
111. Looping Sounds engineInstance.IsLooped = true; I can get the looping effect by simply restarting playback from the SoundEffectInstance each time the game detects that it has stopped However, there is a much easier way of getting this effect I simply set the IsLooped property to true
113. Silverlight and XNA If you want to play sound effects in a Silverlight program you use the XNA SoundEffect class The process is as follows: Add XNA to a Silverlight game Load the sound effect from a resource Play the sound effect as with XNA Keep the XNA system updated
114. Adding XNA to a Silverlight Game The first thing to do is add the reference to the XNA Framework to the solution You might get a warning when you do this, but it is OK 114
115. Adding XNA to a Silverlight Game Next you add the namespaces so you can easily use the objects 115
116. Adding Sound Resources Now you can add the sound itself These are stored as items of content in the solution wav files work well Create a folder in your solution to keep things tidy 116
117. Adding Sound Resources Now you need to set the properties of the sound item Make sure the build action is set to Content 117
118. Loading a SoundEffect 118 Beep = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds/beep.wav")); This code runs at the start of the game It creates a SoundEffect value from the sound resources This mechanism is used in Silverlight because there is no Content Manager for a Silverlight application
119. Playing a SoundEffect 119 beep.Play(); The Play method works in exactly the same was as in XNA If you want more control of the sound playback you can create and use SoundEffectInstance values to control a sound during playback
120. Keeping XNA Awake 120 The XNA framework is driven by repeated calls of Draw and Update methods In Silverlight these do not happen We need to update XNA to allow sound playback The FrameworkDispatcher.Update() method must be called at regular intervals to keep XNA sound working The best way to do this is to create a timer
121. Creating a Timer 121 usingSystem.Windows.Threading; DispatcherTimer timer = newDispatcherTimer(); timer.Tick += newEventHandler(timer_Tick); timer.Interval = TimeSpan.FromTicks(333333); timer.Start(); A DispatcherTimer is a timer that runs in the same thread as the Silverlight page We can create one that fires at the same rate as XNA, 30 times a second We can also bind a method to the tick event
122. The Timer Tick event handler 122 voidtimer_Tick(object sender, EventArgs e) { FrameworkDispatcher.Update(); } When the timer ticks it just updates the XNA framework to keep sound playback working correctly You can also use this technique to animate Silverlight displays
124. Orientation Windows Phone games can be played in many orientations By default the game is configured for landscape orientation
125. Forcing Game Orientation You can force a particular orientation by setting the size of the back buffer This works by using the scaling hardware in the Windows Phone display
126. The Magical Scaler The scaler uses hardware, so your game is not slowed down by it It interpolates to make the scaling look good It scales from 240x240 to 800x480 (or 480x800) It will add a letterbox (black bars) if the chosen aspect ratio doesn’t match the hardware Viewport properties and touch input positions in your program always match the scaled screen
127. Selecting Orientations Your game can indicate which orientations it can support The game above can support anything!
128. Detecting Changes There is an event you can bind to if you need to detect orientation changes
129. Using the full screen The Windows Phone uses the top of the screen for status information This is not always displayed, but when an XNA game runs this space is always reserved for the status information You can see this if you change the theme background to Light
130. Using the Full Screen If you ask to use the full screen this will hide the status bar You can do this in the Initialize method for your game
131. XNA games and the Lock Screen The user of the phone can configure a Screen time-out value in the lock & wallpaper screen This will time the screen out after a given interval if no user input is detected The system checks for user input from the touch screen and the hardware buttons It does not test the accelerometer This means that games that are accelerometer controlled are liable to be timed out
132. Disabling the screen timeout Guide.IsScreenSaverEnabled = false; This statement disables the screen timeout Your game will now run uninterrupted You should use this with care however The game is now in a position to run until the phone battery goes flat You can re-enable the timeout by setting the property to true
133. Summary The Windows Phone supports gameplay in multiple orientations which you can set in your game code The accelerometer allows games to be controlled by tipping the phone XNA and Silverlight can play back sound XNA programs can access the media library in the phone
Start Visual StudioSelect File>New>Project to open the New Project dialogSelect XNA Game Studio 4 from the list of available templates on the leftSelect Windows Phone Game (4.0) from the template selection.Change the name to PongGame.Click OK.The project will now be created.Click Run to run the project. The emulator will start and display the blue screen.Click Stop to stop the program.Close Visual Studio and return to the presentation.
Open the PongGame project in Demo 2 Dot Sizes.Run the program.Rotate the emulator display so that it is landscape with the controls on the right. Explain that this is the default orientation for Windows Phone games.Open the file Game1.cs and navigate to the Draw method.Change the draw position and size of the dot in response to suggestions from the class.Try to draw the dot off the screen. Ask what will happen.Answer: XNA will just clip the display. This will work fineTry to draw a really big dot. Ask what will happen.Answer: The dot will be clipped again.Put the
Open the PongGame project in Demo 2 Moving Dot.Run the program.Show that the dot moves slowly down the screen.Ask what controls the speed of movement:Answer It is the rate at which Update is called and the size of the change applied to the position of the dot.Open the file Game1.cs and navigate to the Update method.Change the code to:ballRectangle.X++;ballRectangle.X++;Ask what this would do to the game.Answer: It would cause the ball to move across the screen and not down. The ball will also move twice as fast.Make the point that the game is presently being
Start Visual StudioOpen the project Demo 1 Bouncing Ball in the demo folder.Run the project. Show that the ball bounces from each edge.Close Visual Studio and return to the presentation.
Start Visual StudioOpen the project Demo 2 Paddle Control in the demo folder.Run the project. Ensure that the emulator is in landscape mode as per the above display.Click on the top of the screen to make the left paddle move up. Click on the top to make the paddle move down.Close Visual Studio and return to the presentation.
Start Visual StudioOpen the project Demo 3 Complete Game in the demo folder.Run the project. Ensure that the emulator is in landscape mode as per the above display.Show that the left paddle is controlled by the user and the right hand one has “unbeatable” AI.Ask how this was done.Answer: The Y position of the right hand paddle is set by the Y position of the ball.Ask how we can make the computer beatable. Answer: We could instead make the computer paddle move towards the ball at a speed slightly less than that of the ball. This would just require the use of a conditional statement to update the Y position accordingly.Make the point that they will be working on this game on the practical session to improve gameplay and make it multi-player.
Use a vector in case the way that the accelerometer works changes at some future time
It is only possible to demonstrate this using an actual phone, as the emulator does not provide accelerometer simulation.Start Visual StudioOpen the project Demo 1 Tipping Pong in the demo folder.Set the deployment to Windows Phone 7 DeviceRun the project. Show that by tipping the phone the left paddle can be made to move up and down.
Use a vector in case the way that the accelerometer works changes at some future time
I’ve written a content extension for a wordlist importer, you can write others.
Make the point that for sound effects you need wav files
Make the point that content can be organised into folders
Note that this is an improvement over the SoundEffect class, where the Play method is “fire and forget
Note that I use the length of the acceleration vector to set the pitch of the sound.
Note that I use the length of the acceleration vector to set the pitch of the sound.
This is a primitive form of looping, but we have a much better one.
This is how to really make sounds loop
Start Visual StudioOpen the project Demo 2 Game with Sounds in the demo folder.Run the project. Ensure that your machine has sound enabled.The program will make sounds when the ball hits objects.
Make the point that you can tailor the resolution and frequency to suit the application and keep the file small.
If the action isn’t content, the sound won’t work.
If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.We will cover SoundEffectInstance in the XNA part of the course.
If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
Start Visual StudioOpen the project Demo 3 Silverlight with Sound in the demo folder.Run the project. Ensure that your machine has sound enabled.The program will make sounds when you click on the equals button.
The scaler is magic. If you find that your game is running a bit slow, decrease the resolution and let the scaler take the strain.Fast moving games can run with much lower resolutions. The scaler will interpolate to make the pictures look good.http://blogs.msdn.com/b/shawnhar/archive/2010/07/12/resolution-and-scaling-on-windows-phone.aspx