SlideShare a Scribd company logo
Windows Phone 7 XNA A different kind of phone, designed for a life in motion
GettingstartedwithxnaA frameworktocreategameapplications
TopicsOverview of XNAHow games runThe XNA Game classAdding and managing game assetsCreating and drawing game sprites
XNA XNA is a framework for writing gamesIt includes a set of professional tools for game production and resource managementWindows Phone uses version 4.0 of the frameworkThis is included as part of the Windows Phone SDK
2D and 3D gamesXNA provides full support for 3D gamesIt allows a game program to make full use of the underlying hardware acceleration provided by the graphics hardwareFor the purpose of this course we are going to focus on 2D gamingWindows Phone games be either 2D or 3D5
XNA and SilverlightXNA is completely different from SilverlightThe way that programs are constructed and execute in XNA is quite differentXNA has been optimised for game creationIt does not have any elements for user interface or data bindingInstead it has support for 3D rendering and game content management6
XNA and ProgramsXNA provides a set of classes which allow you to create gameplayThe classes represent game information and XNA resourcesXNA  is also a very good example of how you construct and deploy a set of software resources in a Framework
Creating a GameThe Windows Phone SDK provides a Windows Phone game project type
The Game ProjectThe solution explorer shows the items that make up our game projectThe solution will also contain any content that we add to the game project
Empty Game DisplayAt the moment all our game does is display a blue screenThis is because the behaviour of the Draw method in a brand new project is to clear the screen to blue
Demo 1: New GameDemo11
What a Game Does When it RunsInitialise all the resources at the startfetch all textures, models, scripts etcRepeatedly run the game:Update the game worldread the user input, update the state and position of game elementsDraw the game worldrender the game elements on the viewing device
XNA Game Class MethodspartialclassPongGame : Microsoft.Xna.Framework.Game{protectedoverridevoidLoadContent                              (boolloadAllContent)    {    }protectedoverridevoid Update(GameTimegameTime)    {    }protectedoverridevoid Draw(GameTimegameTime)    {    }}
XNA Methods and gamesNote that our program never calls the LoadContent, Draw and Update methodsThey are called by the XNA Framework LoadContent is called when the game startsDraw is called as often as possibleUpdate is called 30 times a secondNote that this is not the same as an XNA game on Windows PC or Xbox, where Update is called 60 times a second14
Loading Game ContentprotectedoverridevoidLoadContent(){// Create a new SpriteBatch, which can be used to // draw textures.spriteBatch = newSpriteBatch(GraphicsDevice);}LoadContent is called when our game startsIt is where we put the code that loads the content into our gameContent includes images, sounds, models etc.
Game ContentGames are not just programs, they also contain other content:Images for textures and backgroundsSound Effects3D Object MeshesWe need to add this content to our projectThe XNA framework provides a content management system which is integrated into Visual Studio
Image ResourcesThis is a Ball imageI have saved it as a PNG fileThis allows the image to use transparencyYou can use any image resource you like The resources are added to the Visual Studio projectThey are held in the Content directory as part of your project
Using the Content PipelineEach resource is given an asset name The Load method of Content Manager provides access to the resource using the Asset Name that we gave itballTexture = Content.Load<Texture2D>("WhiteDot");
Storing the Ball Texture in the game// Game WorldTexture2D ballTexture;XNA provides a Texture2Dtype which holds a 2D (flat) texture to be drawn on the displayThe game class needs to contain a member variable to hold the ball texture that is to be drawn when the game runsThis variable will be shared by all the methods in the game
Loading Content into the Ball TextureprotectedoverridevoidLoadContent(){// Create a new SpriteBatch, which can be used to     // draw textures.spriteBatch = newSpriteBatch(GraphicsDevice);ballTexture = Content.Load<Texture2D>("WhiteDot");}LoadContentis called when a game startsIt loads an image into the ball textureThe content manager fetches the images which are automatically sent to the target device
Making a “sprite”A sprite is an object on the screen of a gameIt has both a texture and a position on the screen We are creating a sprite object for the ball in our gameWe now have the texture for the objectThe next thing to do is position it on the screen21
Coordinates and PixelsWhen drawing in XNA the position of an object on the screen is given using coordinates based on pixelsA standard Windows Phone screen is 800 pixels wide and 480 pixels highThis gives the range of possible values for display coordinatesIf you draw things off the screen this does not cause XNA problems, but nothing is drawn22
X and Y in XNAThe coordinate system used by XNA sprite drawing puts the origin (0,0) in the top left hand corner of the screenIncreasing X moves an object across the screen towards the rightIncreasing Y moves an object down the screen towards the bottomIt is important that you remember this23
Positioning the Ball using a Rectangle// Game WorldTexture2DballTexture;RectangleballRectangle;We can add a rectangle value to the game to manage the position of the ball on the screenWe will initialise it in the LoadContent method
The Rectangle structureRectangle ballRectangle = newRectangle(    0, 0,ballTexture.Width, ballTexture.Height),Color.White);Rectangle is a struct type which contains a position and a sizeThe code above creates a rectangle positioned at 0,0 (top left hand corner) the same size as ballTextureWe could move our ball by changing the content of the rectangle
Drawing a SpriteIn game programming terms a “sprite” is a texture that can be positioned on the screenWe now have a ball spriteWe have the texture that contains an image of the ballWe have a rectangle that gives the position and size of the sprite itself26
XNA Game Draw Methodprotectedoverridevoid Draw(GameTimegameTime){GraphicsDevice.Clear(Color.CornflowerBlue);base.Draw(gameTime);}The Draw method is called repeatedly when an XNA game is runningIt has the job of drawing the display on the screenA brand new XNA game project  contains a Draw method that clears the screen to CornflowerBlueWe must add our own code to the method to draw the ball
Sprite Batching2D Graphics drawing is handled by a set of “sprite” drawing methods provided by XNAThese create commands that are passed to the graphics deviceThe graphics device will not want to draw everything on a piecemeal basisIdeally all the drawing information, textures and transformations should be provided as a single itemThe SpriteBatch class looks after this for us
SpriteBatch Begin and Endprotectedoverridevoid Draw(GameTimegameTime){GraphicsDevice.Clear(Color.CornflowerBlue);spriteBatch.Begin();    // Code that uses spriteBatch to draw the displayspriteBatch.End();base.Draw(gameTime);}The call to the Begin method tells SpriteBatch to begin a assembling a new set of drawing operationsThe call to the End method tells SpriteBatch that the there are no more operations and causes the rendering to take place
Using SpriteBatch.DrawspriteBatch.Draw(ballTexture, ballRectangle, Color.White);The SpriteBatch class provides a Draw method to do the sprite drawingIt is given parameters to tell it what to do:Texture to drawPosition (expressed as a Rectangle)Draw color
Rectangle Funnew Rectangle(  0, 0,ballTexture.Width, ballTexture.Height)new Rectangle(  0, 0,      // position  200,100)   // sizenew Rectangle(  50, 50,     // position  60, 60)     // size
Demo 2: Dot SizesDemo32
Screen Size and ScalingWe need to make our game images fit the size of the screenWe can find out the size of the screen from the GraphicsDevice used to draw itGraphicsDevice.Viewport.WidthGraphicsDevice.Viewport.HeightWe can use this information to scale the images on the screen
Creating the ballRectangle variableballRectangle = 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 screenWe can then set the position parts of the rectangle to move the ball around the screen
Moving the ball around the screenAt the moment the ball is drawn in the same position each time Draw runsTo move the ball around we need to make this position change over timeWe need to give the game an update behaviourWe must add code to the Update method in the gameThe Update method is where we manage the state of the “game world”
The Update Methodprotectedoverridevoid Update(GameTimegameTime){// TODO: Add your update logic herebase.Update(gameTime);}The Update method is automatically called 30 times a second when a game is runningIt 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
Simple Update Methodprotectedoverridevoid Update(GameTimegameTime){ballRectangle.X++;ballRectangle.Y++;base.Update(gameTime);}Each time the game updates the X and Y position of the ball rectangle is increasedThis will cause it to move across and down the screenNote that I call the base method to allow my parent object to update too
GameTimeAt the moment the Update method is called sixty time a second or once every 16.66 millisecondsWe 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 distanceThis is what the GameTime parameter is for, it gives the time at which the method was called
Demo 2: Moving DotDemo39
SummaryXNA is a Framework of methods that are used to write gamesYou create the games using Visual Studio Games have initialise, update and draw behavioursGame objects are held as textures objects and their position and dimensions as rectangle structures
Creatinggameplaywithxna
TopicsControlling the movement of a spriteCreating multiple spritesUsing touch input to control sprite movementDetecting sprite collisions Displaying text
XNA and PongLast time we got a ball to move down the screenNow we need to make the ball bounce around the screenNow we need to discover how we can create paddles and control them using a gamepad or keyboardThen we can start building a game
Accurate ball positioningfloat ballX = 0;float ballY = 0;The Rectangle provides integer properties that can be used to position the drawing operationTo get more precise control over the movement of an object we need to use floating point position variables
Accurate ball positioningballRectangle.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 rectangleThis is performed during the Update method
Controlling Ball Movementfloat ballXSpeed = 3;float ballYSpeed = 3;To manage the speed of the ball we can use a pair of member variables in our game classOne for the X speed and one for the Y speedEach time Update is called these are used to update the values of the X and Y position of the draw rectangle
Moving the BallballX = ballX + ballXSpeed;ballY= ballY + ballYSpeed;The Update method is where the speed values are used to update the rectangle position for the ballThe next call of Draw will draw the ball in the new position
Going off the Edge
Making the Ball Bounceif (ballX < 0 ||  ballX+ ballRectangle.Width >  GraphicsDevice.Viewport.Width){ballXSpeed = -ballXSpeed;}When the ball reaches the edge of the screen it must change directionWe can do this by reversing the sign of the speed value to reverse the effect of the update
Demo 1: Bouncing BallDemo50
Making a PaddleThe paddle is made from a texture, just like the ballThis time I’ve made a slightly more interesting one which uses transparencyThe paddle is loaded as a texture resource, just as the ball is
Game Variables// Game WorldTexture2DballTexture;RectangleballRectangle;floatballX;floatballY;floatballXSpeed = 3;floatballYSpeed = 3;Texture2DlPaddleTexture;RectanglelPaddleRectangle;floatlPaddleSpeed = 4;floatlPaddleY; // Repeat these for the right paddle// Distance of paddles from screen edgeint margin;
Loading GameTexturesprotectedoverridevoid 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 assetsWe now have three textures in the game
Setting up the paddlesmargin = 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
Initial game positionsThe LoadContent method puts the paddles and balls at their starting positions as shown above55
Paddle controlWe can use the Windows Phone touch screen to control a paddleThe touch screen can track up to four inputs and can detect when touch events start and endWe are just going to test for touches to move the paddle up or down56
Getting the Touch Panel statusTouchCollection touches = TouchPanel.GetState();The TouchPanel class provides a GetState method that will return the touch panel statusThis returns a collection of TouchLocation values that describe the present state of the touch panelThis can contain up to four values
Using the Touch informationif (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
Using the Touch informationif (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
Using the Touch informationif (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
Using the Touch informationif (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
Using the Touch informationif (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
Using the Touch informationif (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
Using the Touch informationif (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)
Demo 2: Paddle ControlDemo65
Detecting CollisionsWe need to make the ball bounce off the paddles when the two collideIn the console version of the game we tested to see if ball and paddle occupied the same part of the screenIn the case of XNA we need to see if the rectangles which control the position of the ball and paddle intersect
Rectangle Intersectionif (ballRectangle.Intersects(lPaddleRectangle)){ballXSpeed = -ballXSpeed;}The Rectangle structure provides a method called Intersects which can be used to detect if two rectangles intersectIf the paddle and ball rectangles intersect we must reverse the X direction of movement of the ball to have it bounce off the paddle
Completing the GameA finished game must also detect when the ball reaches the edges of the screenThis is when a point has been scoredI will leave you to create this codeHowever, you will also need to draw text on the screen to display messages to the playersThis turns out to be very easy
Adding a SpriteFontA SpriteFont is a content item that lets you draw text on the screenIt provides a set of character designs of a particular size
SpriteFont XMLThe font used and the size are set in an XML fileYou can edit this to get different sizes and styles
Loading a FontSpriteFont 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 classYou can use multiple fonts if you want different text styles
Drawing textprotectedoverridevoid 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
Demo 3: Completed Pong GameDemo73
SummaryObjects in games can be made to move by updating their position informationIt is best if the game manages position in floating point valuesThe TouchPanel provides a collection of TouchLocation values that describe touch actionsXNA games can draw text using SpriteFonts
Gamesonwindowsphone
TopicsUsing the Accelerometer to control gameplayPlaying sounds in XNA gamesPlaying sounds in Silverlight programsUsing media in XNA gamesWindows Phone games and orientation
The AccelerometerThe Accelerometer can measure acceleration in X, Y and ZYou can use just the X and Y values to control sprites in 2D gamesThe values that are returned are in the range -1 to +1 in each axisWhen the value is 0 this means the device is flat on that axis
XNA 4.0 AccelerometerThe accelerometer in XNA 4.0 is event drivenThe accelerometer generates events when new readings are availableYou must bind a method to the eventThe method can store the settings for later use
XNA and SilverlightThe reason why the accelerometer is event driven is that XNA actually uses the same sensor interface as SilverlightThis means that we need to include the appropriate sensor library into our programs to obtain accelerometer readings
Adding the Sensors libraryWe need to add Microsoft.Devices.Sensors to the solution references to bring in the library
Adding the NamespaceusingMicrosoft.Devices.Sensors;Once you have added the library you can use the Sensors objectsAdding the namespace to your program makes the code a bit cleanerNote that you only have to do this for the accelerometer
Creating an AccelerometerAccelerometeracc = newAccelerometer();acc.ReadingChanged += newEventHandler<AccelerometerReadingEventArgs>                                               (acc_ReadingChanged);acc.Start();The above code runs in the Initialise method to set up the accelerometerInitialise is called by XNA when a game starts It creates a new Accelerometer, binds an event handler to it and then starts it running
Accelerometer EventsVector3accelState = 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 accelerometerIt copies the readings into a vector
Using the readinglPaddleY = lPaddleY - (accelState.X * lPaddleSpeed);The Pong game only needs to use a single axisThis is the X axis, that runs along the long length of the phoneWe have to reverse the sense of the position update as the value of Y increases down the screen
The accelerometer and orientationThe accelerometer provides the same readings irrespective of the orientation of the deviceIn other words the direction of the axes does not change when the orientation changesFor this reason I would advise you to fix the orientation of a tipping game
“Tipping” gamesThe accelerometer makes it very easy to create “tipping” games, which simulate gravity moving items around the screenThe further you tip the device the greater the force acting on the objectThis leads to a very simple physics model, which is actually very effective
Demo 1: Tipping Pong gameDemo
Threads and ContentionIt turns out that there is a potential problem with the way we are using the accelerometerIt is prone to errors caused by the way that we are using two separate threads of execution to work with the accelerometer valuesOne thread stores the values in the vectorThe other thread reads the values backAt the moment these threads are not synchronised, and this can cause problems
What might happen…Update runs and reads the X value of the accelerationThe Accelerometer event fires and starts running. It generates and stores new values of X, Y and ZUpdate reads the Y and Z values from the updated valuesUpdate now has “scrambled” data
Processes and processorsThe problem is caused by the way that the operating system runs multiple processesEach process is given control for a small time interval and then another is allowed to runIf one process is allowed to interrupt another we can get them “fighting” over data
Adding a LockWe solve the problem by using a “lock” objectA process can “grab” the lock object and hold onto it while it does something that must not be interruptedAt the end of the action it releases the lock objectIf another process needs to use the lock it will be paused until the lock becomes available
Accelerometer Events and LockobjectaccelLock = 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
Accelerometer Events and Locklock (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
Locks and ProgramsThe locking behaviour is provided by the operating systemA process that cannot run because it is waiting for a lock will be held until it canIt is important that code that uses a lock does not take a long time to completeThis might cause other processes to get stuck waiting for the lock to become available
“Deadly Embrace”It is also important that two processes don’t each end up waiting for a lock the other hasThis causes both processes to be stuckYou can do this by making a process either “produce” or “consume” dataYou only tend to get deadly embraces when a process is both a producer and a consumer
Sounds as ContentXNA uses a Content Manager to look after the resources used by a gameEach content type has a “pipeline” of processors that bring it into the project and then package it for inclusion in the game distributableYou don’t need to worry how this worksYou can write your own content library if you wish
XNA Sound TypesSound effectswav files held in memory for quick playbackBackground musicwma and mp3 files loaded and playedManaged as media (more on this later)
Preparing SoundsA good tool for preparing sound files is AudacityIt will also convert between mp3 and wav formatYou can download it for free from	http://audacity.sourceforge.net/
Adding ContentThe simplest way to add content is to drag and drop it into the solutionYou can place it alongside images, or in separate folders
Content PropertiesThe content Properties pane identifies the asset name and the importer to use
SoundEffect variables// Sound effectsSoundEffectdingSound;SoundEffectexplodeSound;These game member variables hold the sound effects for the “Pong” gameThey will be initialised with content when the game starts runningWe do this in LoadContent method does this
The LoadContent methodprotectedoverridevoidLoadContent(){// rest of LoadContent heredingSound= Content.Load<SoundEffect>("ding");explodeSound = Content.Load<SoundEffect>("explode");}LoadContent is called when the game startsThe game contains a Content Manager which manages game content (surprisingly)The Load method uses Generics to determine the required loader
Simple Sound Playbackif (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 instantlyThe Pong game will play the ding sound when the ball hits the top or bottom of the screen
Complex Sound PlaybackSometimes the sound playback is more complexWe might want to play an engine sound continuously when the “engine” is runningWe might  also want to vary the pitch of the sound as it playsTo do this we use a SoundEffectInstanceThis is an object that serves as a handle to a playing sound
The SoundEffectInstanceengineInstance = engineSound.CreateInstance();When we call the Play method on a sound effect this is a “fire and forget” kind of sound playbackTo get more control over a sound we need to create an object that represents itA SoundEffect can be asked to create an object representing an instance of a sound being played by using the CreateInstance method
Playing SoundsengineInstance.Play();...engineInstance.Pause();...engineInstance.Stop();The Play method on a SoundEffectInstance will start sound playbackWe can also call Pause and Stop to control the sound
Controlling VolumeengineInstance.Volume= accelVector.Length() / volFactor;The Volume property lets you adjust the volume of a playing soundThe range is from 0 to 1:0 no sound+1 maximum volume
Controlling PitchengineInstance.Pitch = accelVector.Length() / soundFactor;The Pitch property lets you adjust the pitch of a playing soundThe range is from -1 to 1:-1 octave low0 normal pitch+1 octave high
Controlling PositionengineInstance.Pan = cheesePan;The Pan property lets you adjust the pan position of a playing soundThe range is from -1 to 1:-1 hard left0 center+1 right
Sound Statusif (engineInstance.State == SoundState.Stopped){engineInstance.Play();}The SoundEffectInstance exposes a property that gives the playing statusThis is updated when the sound stops playingThe code above will play the sound again if it is stoppedThis is a primitive kind of looping
Looping SoundsengineInstance.IsLooped = true;I can get the looping effect by simply restarting playback from the SoundEffectInstance each time the game detects that it has stoppedHowever, there is a much easier way of getting this effectI simply set the IsLooped property to true
Demo 2: Games with SoundsDemo
Silverlight and XNAIf you want to play sound effects in a Silverlight program you use the XNA SoundEffect classThe process is as follows:Add XNA to a Silverlight gameLoad the sound effect from a resourcePlay the sound effect as with XNAKeep the XNA system updated
Adding XNA to a Silverlight GameThe first thing to do is add the reference to the XNA Framework to the solutionYou might get a warning when you do this, but it is OK114
Adding XNA to a Silverlight GameNext you add the namespaces so you can easily use the objects115
Adding Sound ResourcesNow you can add the sound itselfThese are stored as items of content in the solutionwav files work wellCreate a folder in your solution to keep things tidy116
Adding Sound ResourcesNow you need to set the properties of the sound itemMake sure the build action is set to Content117
Loading a SoundEffect118Beep = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds/beep.wav"));This code runs at the start of the gameIt creates a SoundEffect value from the sound resourcesThis mechanism is used in Silverlight because there is no Content Manager for a Silverlight application
Playing a SoundEffect119beep.Play();The Play method works in exactly the same was as in XNAIf you want more control of the sound playback you can create and use SoundEffectInstance values to control a sound during playback
Keeping XNA Awake120The XNA framework is driven by repeated calls of Draw and Update methods In Silverlight these do not happenWe need to update XNA to allow sound playback The FrameworkDispatcher.Update() method must be called at regular intervals to keep XNA sound workingThe best way to do this is to create a timer
Creating a Timer121usingSystem.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 pageWe can create one that fires at the same rate as XNA, 30 times a secondWe can also bind a method to the tick event
The Timer Tick event handler122voidtimer_Tick(object sender, EventArgs e){FrameworkDispatcher.Update();}When the timer ticks it just updates the XNA framework to keep sound playback working correctlyYou can also use this technique to animate Silverlight displays
Demo 3: Silverlight with SoundDemo
OrientationWindows Phone games can be played in many orientationsBy default the game is configured for landscape orientation
Forcing Game OrientationYou can force a particular orientation by setting the size of the back bufferThis works by using the scaling hardware in the Windows Phone display
The Magical ScalerThe scaler uses hardware, so your game is not slowed down by itIt interpolates to make the scaling look goodIt scales from 240x240 to 800x480 (or 480x800) It will add a letterbox (black bars) if the chosen aspect ratio doesn’t match the hardwareViewport properties and touch input positions in your program always match the scaled screen
Selecting OrientationsYour game can indicate which orientations it can supportThe game above can support anything!
Detecting ChangesThere is an event you can bind to if you need to detect orientation changes
Using the full screenThe Windows Phone uses the top of the screen for status informationThis is not always displayed, but when an XNA game runs this space is always reserved for the status informationYou can see this if you change the theme background to Light
Using the Full ScreenIf you ask to use the full screen this will hide the status barYou can do this in the Initialize method for your game
XNA games and the Lock ScreenThe user of the phone can configure a Screen time-out value in the lock & wallpaper screenThis will time the screen out after a given interval if no user input is detectedThe system checks for user input from the touch screen and the hardware buttonsIt does not test the accelerometerThis means that games that are accelerometer controlled are liable to be timed out
Disabling the screen timeoutGuide.IsScreenSaverEnabled = false;This statement disables the screen timeoutYour game will now run uninterruptedYou should use this with care howeverThe game is now in a position to run until the phone battery goes flatYou can re-enable the timeout by setting the property to true
SummaryThe Windows Phone supports gameplay in multiple orientations which you can set in your game codeThe accelerometer allows games to be controlled by tipping the phoneXNA and Silverlight can play back soundXNA programs can access the media library in the phone
Exercise 1: Use Multi-Touch in a windowsphonegame
Exercise 2: use theaccelerometer in anxnaprogram

More Related Content

WP7 HUB_XNA overview

  • 1. Windows Phone 7 XNA A different kind of phone, designed for a life in motion
  • 3. TopicsOverview of XNAHow games runThe XNA Game classAdding and managing game assetsCreating and drawing game sprites
  • 4. XNA XNA is a framework for writing gamesIt includes a set of professional tools for game production and resource managementWindows Phone uses version 4.0 of the frameworkThis is included as part of the Windows Phone SDK
  • 5. 2D and 3D gamesXNA provides full support for 3D gamesIt allows a game program to make full use of the underlying hardware acceleration provided by the graphics hardwareFor the purpose of this course we are going to focus on 2D gamingWindows Phone games be either 2D or 3D5
  • 6. XNA and SilverlightXNA is completely different from SilverlightThe way that programs are constructed and execute in XNA is quite differentXNA has been optimised for game creationIt does not have any elements for user interface or data bindingInstead it has support for 3D rendering and game content management6
  • 7. XNA and ProgramsXNA provides a set of classes which allow you to create gameplayThe classes represent game information and XNA resourcesXNA is also a very good example of how you construct and deploy a set of software resources in a Framework
  • 8. Creating a GameThe Windows Phone SDK provides a Windows Phone game project type
  • 9. The Game ProjectThe solution explorer shows the items that make up our game projectThe solution will also contain any content that we add to the game project
  • 10. Empty Game DisplayAt the moment all our game does is display a blue screenThis is because the behaviour of the Draw method in a brand new project is to clear the screen to blue
  • 11. Demo 1: New GameDemo11
  • 12. What a Game Does When it RunsInitialise all the resources at the startfetch all textures, models, scripts etcRepeatedly run the game:Update the game worldread the user input, update the state and position of game elementsDraw the game worldrender the game elements on the viewing device
  • 13. XNA Game Class MethodspartialclassPongGame : Microsoft.Xna.Framework.Game{protectedoverridevoidLoadContent (boolloadAllContent) { }protectedoverridevoid Update(GameTimegameTime) { }protectedoverridevoid Draw(GameTimegameTime) { }}
  • 14. XNA Methods and gamesNote that our program never calls the LoadContent, Draw and Update methodsThey are called by the XNA Framework LoadContent is called when the game startsDraw is called as often as possibleUpdate is called 30 times a secondNote that this is not the same as an XNA game on Windows PC or Xbox, where Update is called 60 times a second14
  • 15. Loading Game ContentprotectedoverridevoidLoadContent(){// Create a new SpriteBatch, which can be used to // draw textures.spriteBatch = newSpriteBatch(GraphicsDevice);}LoadContent is called when our game startsIt is where we put the code that loads the content into our gameContent includes images, sounds, models etc.
  • 16. Game ContentGames are not just programs, they also contain other content:Images for textures and backgroundsSound Effects3D Object MeshesWe need to add this content to our projectThe XNA framework provides a content management system which is integrated into Visual Studio
  • 17. Image ResourcesThis is a Ball imageI have saved it as a PNG fileThis allows the image to use transparencyYou can use any image resource you like The resources are added to the Visual Studio projectThey are held in the Content directory as part of your project
  • 18. Using the Content PipelineEach resource is given an asset name The Load method of Content Manager provides access to the resource using the Asset Name that we gave itballTexture = Content.Load<Texture2D>("WhiteDot");
  • 19. Storing the Ball Texture in the game// Game WorldTexture2D ballTexture;XNA provides a Texture2Dtype which holds a 2D (flat) texture to be drawn on the displayThe game class needs to contain a member variable to hold the ball texture that is to be drawn when the game runsThis variable will be shared by all the methods in the game
  • 20. Loading Content into the Ball TextureprotectedoverridevoidLoadContent(){// Create a new SpriteBatch, which can be used to // draw textures.spriteBatch = newSpriteBatch(GraphicsDevice);ballTexture = Content.Load<Texture2D>("WhiteDot");}LoadContentis called when a game startsIt loads an image into the ball textureThe 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 gameIt has both a texture and a position on the screen We are creating a sprite object for the ball in our gameWe now have the texture for the objectThe next thing to do is position it on the screen21
  • 22. Coordinates and PixelsWhen drawing in XNA the position of an object on the screen is given using coordinates based on pixelsA standard Windows Phone screen is 800 pixels wide and 480 pixels highThis gives the range of possible values for display coordinatesIf you draw things off the screen this does not cause XNA problems, but nothing is drawn22
  • 23. X and Y in XNAThe coordinate system used by XNA sprite drawing puts the origin (0,0) in the top left hand corner of the screenIncreasing X moves an object across the screen towards the rightIncreasing Y moves an object down the screen towards the bottomIt is important that you remember this23
  • 24. Positioning the Ball using a Rectangle// Game WorldTexture2DballTexture;RectangleballRectangle;We can add a rectangle value to the game to manage the position of the ball on the screenWe will initialise it in the LoadContent method
  • 25. The Rectangle structureRectangle ballRectangle = newRectangle( 0, 0,ballTexture.Width, ballTexture.Height),Color.White);Rectangle is a struct type which contains a position and a sizeThe code above creates a rectangle positioned at 0,0 (top left hand corner) the same size as ballTextureWe could move our ball by changing the content of the rectangle
  • 26. Drawing a SpriteIn game programming terms a “sprite” is a texture that can be positioned on the screenWe now have a ball spriteWe have the texture that contains an image of the ballWe have a rectangle that gives the position and size of the sprite itself26
  • 27. XNA Game Draw Methodprotectedoverridevoid Draw(GameTimegameTime){GraphicsDevice.Clear(Color.CornflowerBlue);base.Draw(gameTime);}The Draw method is called repeatedly when an XNA game is runningIt has the job of drawing the display on the screenA brand new XNA game project contains a Draw method that clears the screen to CornflowerBlueWe must add our own code to the method to draw the ball
  • 28. Sprite Batching2D Graphics drawing is handled by a set of “sprite” drawing methods provided by XNAThese create commands that are passed to the graphics deviceThe graphics device will not want to draw everything on a piecemeal basisIdeally all the drawing information, textures and transformations should be provided as a single itemThe SpriteBatch class looks after this for us
  • 29. SpriteBatch Begin and Endprotectedoverridevoid Draw(GameTimegameTime){GraphicsDevice.Clear(Color.CornflowerBlue);spriteBatch.Begin(); // Code that uses spriteBatch to draw the displayspriteBatch.End();base.Draw(gameTime);}The call to the Begin method tells SpriteBatch to begin a assembling a new set of drawing operationsThe call to the End method tells SpriteBatch that the there are no more operations and causes the rendering to take place
  • 30. Using SpriteBatch.DrawspriteBatch.Draw(ballTexture, ballRectangle, Color.White);The SpriteBatch class provides a Draw method to do the sprite drawingIt is given parameters to tell it what to do:Texture to drawPosition (expressed as a Rectangle)Draw color
  • 31. Rectangle Funnew Rectangle( 0, 0,ballTexture.Width, ballTexture.Height)new Rectangle( 0, 0, // position 200,100) // sizenew Rectangle( 50, 50, // position 60, 60) // size
  • 32. Demo 2: Dot SizesDemo32
  • 33. Screen Size and ScalingWe need to make our game images fit the size of the screenWe can find out the size of the screen from the GraphicsDevice used to draw itGraphicsDevice.Viewport.WidthGraphicsDevice.Viewport.HeightWe can use this information to scale the images on the screen
  • 34. Creating the ballRectangle variableballRectangle = 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 screenWe can then set the position parts of the rectangle to move the ball around the screen
  • 35. Moving the ball around the screenAt the moment the ball is drawn in the same position each time Draw runsTo move the ball around we need to make this position change over timeWe need to give the game an update behaviourWe must add code to the Update method in the gameThe Update method is where we manage the state of the “game world”
  • 36. The Update Methodprotectedoverridevoid Update(GameTimegameTime){// TODO: Add your update logic herebase.Update(gameTime);}The Update method is automatically called 30 times a second when a game is runningIt 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 Methodprotectedoverridevoid Update(GameTimegameTime){ballRectangle.X++;ballRectangle.Y++;base.Update(gameTime);}Each time the game updates the X and Y position of the ball rectangle is increasedThis will cause it to move across and down the screenNote that I call the base method to allow my parent object to update too
  • 38. GameTimeAt the moment the Update method is called sixty time a second or once every 16.66 millisecondsWe 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 distanceThis is what the GameTime parameter is for, it gives the time at which the method was called
  • 39. Demo 2: Moving DotDemo39
  • 40. SummaryXNA is a Framework of methods that are used to write gamesYou create the games using Visual Studio Games have initialise, update and draw behavioursGame objects are held as textures objects and their position and dimensions as rectangle structures
  • 42. TopicsControlling the movement of a spriteCreating multiple spritesUsing touch input to control sprite movementDetecting sprite collisions Displaying text
  • 43. XNA and PongLast time we got a ball to move down the screenNow we need to make the ball bounce around the screenNow we need to discover how we can create paddles and control them using a gamepad or keyboardThen we can start building a game
  • 44. Accurate ball positioningfloat ballX = 0;float ballY = 0;The Rectangle provides integer properties that can be used to position the drawing operationTo get more precise control over the movement of an object we need to use floating point position variables
  • 45. Accurate ball positioningballRectangle.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 rectangleThis is performed during the Update method
  • 46. Controlling Ball Movementfloat ballXSpeed = 3;float ballYSpeed = 3;To manage the speed of the ball we can use a pair of member variables in our game classOne for the X speed and one for the Y speedEach time Update is called these are used to update the values of the X and Y position of the draw rectangle
  • 47. Moving the BallballX = ballX + ballXSpeed;ballY= ballY + ballYSpeed;The Update method is where the speed values are used to update the rectangle position for the ballThe next call of Draw will draw the ball in the new position
  • 49. Making the Ball Bounceif (ballX < 0 || ballX+ ballRectangle.Width > GraphicsDevice.Viewport.Width){ballXSpeed = -ballXSpeed;}When the ball reaches the edge of the screen it must change directionWe can do this by reversing the sign of the speed value to reverse the effect of the update
  • 50. Demo 1: Bouncing BallDemo50
  • 51. Making a PaddleThe paddle is made from a texture, just like the ballThis time I’ve made a slightly more interesting one which uses transparencyThe paddle is loaded as a texture resource, just as the ball is
  • 52. Game Variables// Game WorldTexture2DballTexture;RectangleballRectangle;floatballX;floatballY;floatballXSpeed = 3;floatballYSpeed = 3;Texture2DlPaddleTexture;RectanglelPaddleRectangle;floatlPaddleSpeed = 4;floatlPaddleY; // Repeat these for the right paddle// Distance of paddles from screen edgeint margin;
  • 53. Loading GameTexturesprotectedoverridevoid 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 assetsWe now have three textures in the game
  • 54. Setting up the paddlesmargin = 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 positionsThe LoadContent method puts the paddles and balls at their starting positions as shown above55
  • 56. Paddle controlWe can use the Windows Phone touch screen to control a paddleThe touch screen can track up to four inputs and can detect when touch events start and endWe are just going to test for touches to move the paddle up or down56
  • 57. Getting the Touch Panel statusTouchCollection touches = TouchPanel.GetState();The TouchPanel class provides a GetState method that will return the touch panel statusThis returns a collection of TouchLocation values that describe the present state of the touch panelThis can contain up to four values
  • 58. Using the Touch informationif (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 informationif (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 informationif (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 informationif (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 informationif (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 informationif (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 informationif (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)
  • 65. Demo 2: Paddle ControlDemo65
  • 66. Detecting CollisionsWe need to make the ball bounce off the paddles when the two collideIn the console version of the game we tested to see if ball and paddle occupied the same part of the screenIn the case of XNA we need to see if the rectangles which control the position of the ball and paddle intersect
  • 67. Rectangle Intersectionif (ballRectangle.Intersects(lPaddleRectangle)){ballXSpeed = -ballXSpeed;}The Rectangle structure provides a method called Intersects which can be used to detect if two rectangles intersectIf 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 GameA finished game must also detect when the ball reaches the edges of the screenThis is when a point has been scoredI will leave you to create this codeHowever, you will also need to draw text on the screen to display messages to the playersThis turns out to be very easy
  • 69. Adding a SpriteFontA SpriteFont is a content item that lets you draw text on the screenIt provides a set of character designs of a particular size
  • 70. SpriteFont XMLThe font used and the size are set in an XML fileYou can edit this to get different sizes and styles
  • 71. Loading a FontSpriteFont 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 classYou can use multiple fonts if you want different text styles
  • 72. Drawing textprotectedoverridevoid 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
  • 73. Demo 3: Completed Pong GameDemo73
  • 74. SummaryObjects in games can be made to move by updating their position informationIt is best if the game manages position in floating point valuesThe TouchPanel provides a collection of TouchLocation values that describe touch actionsXNA games can draw text using SpriteFonts
  • 76. TopicsUsing the Accelerometer to control gameplayPlaying sounds in XNA gamesPlaying sounds in Silverlight programsUsing media in XNA gamesWindows Phone games and orientation
  • 77. The AccelerometerThe Accelerometer can measure acceleration in X, Y and ZYou can use just the X and Y values to control sprites in 2D gamesThe values that are returned are in the range -1 to +1 in each axisWhen the value is 0 this means the device is flat on that axis
  • 78. XNA 4.0 AccelerometerThe accelerometer in XNA 4.0 is event drivenThe accelerometer generates events when new readings are availableYou must bind a method to the eventThe method can store the settings for later use
  • 79. XNA and SilverlightThe reason why the accelerometer is event driven is that XNA actually uses the same sensor interface as SilverlightThis means that we need to include the appropriate sensor library into our programs to obtain accelerometer readings
  • 80. Adding the Sensors libraryWe need to add Microsoft.Devices.Sensors to the solution references to bring in the library
  • 81. Adding the NamespaceusingMicrosoft.Devices.Sensors;Once you have added the library you can use the Sensors objectsAdding the namespace to your program makes the code a bit cleanerNote that you only have to do this for the accelerometer
  • 82. Creating an AccelerometerAccelerometeracc = newAccelerometer();acc.ReadingChanged += newEventHandler<AccelerometerReadingEventArgs> (acc_ReadingChanged);acc.Start();The above code runs in the Initialise method to set up the accelerometerInitialise 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 EventsVector3accelState = 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 accelerometerIt copies the readings into a vector
  • 84. Using the readinglPaddleY = lPaddleY - (accelState.X * lPaddleSpeed);The Pong game only needs to use a single axisThis is the X axis, that runs along the long length of the phoneWe have to reverse the sense of the position update as the value of Y increases down the screen
  • 85. The accelerometer and orientationThe accelerometer provides the same readings irrespective of the orientation of the deviceIn other words the direction of the axes does not change when the orientation changesFor this reason I would advise you to fix the orientation of a tipping game
  • 86. “Tipping” gamesThe accelerometer makes it very easy to create “tipping” games, which simulate gravity moving items around the screenThe further you tip the device the greater the force acting on the objectThis leads to a very simple physics model, which is actually very effective
  • 87. Demo 1: Tipping Pong gameDemo
  • 88. Threads and ContentionIt turns out that there is a potential problem with the way we are using the accelerometerIt is prone to errors caused by the way that we are using two separate threads of execution to work with the accelerometer valuesOne thread stores the values in the vectorThe other thread reads the values backAt 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 accelerationThe Accelerometer event fires and starts running. It generates and stores new values of X, Y and ZUpdate reads the Y and Z values from the updated valuesUpdate now has “scrambled” data
  • 90. Processes and processorsThe problem is caused by the way that the operating system runs multiple processesEach process is given control for a small time interval and then another is allowed to runIf one process is allowed to interrupt another we can get them “fighting” over data
  • 91. Adding a LockWe solve the problem by using a “lock” objectA process can “grab” the lock object and hold onto it while it does something that must not be interruptedAt the end of the action it releases the lock objectIf another process needs to use the lock it will be paused until the lock becomes available
  • 92. Accelerometer Events and LockobjectaccelLock = 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 Locklock (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 ProgramsThe locking behaviour is provided by the operating systemA process that cannot run because it is waiting for a lock will be held until it canIt is important that code that uses a lock does not take a long time to completeThis 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 hasThis causes both processes to be stuckYou can do this by making a process either “produce” or “consume” dataYou only tend to get deadly embraces when a process is both a producer and a consumer
  • 96. Sounds as ContentXNA uses a Content Manager to look after the resources used by a gameEach content type has a “pipeline” of processors that bring it into the project and then package it for inclusion in the game distributableYou don’t need to worry how this worksYou can write your own content library if you wish
  • 97. XNA Sound TypesSound effectswav files held in memory for quick playbackBackground musicwma and mp3 files loaded and playedManaged as media (more on this later)
  • 98. Preparing SoundsA good tool for preparing sound files is AudacityIt will also convert between mp3 and wav formatYou can download it for free from http://audacity.sourceforge.net/
  • 99. Adding ContentThe simplest way to add content is to drag and drop it into the solutionYou can place it alongside images, or in separate folders
  • 100. Content PropertiesThe content Properties pane identifies the asset name and the importer to use
  • 101. SoundEffect variables// Sound effectsSoundEffectdingSound;SoundEffectexplodeSound;These game member variables hold the sound effects for the “Pong” gameThey will be initialised with content when the game starts runningWe do this in LoadContent method does this
  • 102. The LoadContent methodprotectedoverridevoidLoadContent(){// rest of LoadContent heredingSound= Content.Load<SoundEffect>("ding");explodeSound = Content.Load<SoundEffect>("explode");}LoadContent is called when the game startsThe game contains a Content Manager which manages game content (surprisingly)The Load method uses Generics to determine the required loader
  • 103. Simple Sound Playbackif (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 instantlyThe Pong game will play the ding sound when the ball hits the top or bottom of the screen
  • 104. Complex Sound PlaybackSometimes the sound playback is more complexWe might want to play an engine sound continuously when the “engine” is runningWe might also want to vary the pitch of the sound as it playsTo do this we use a SoundEffectInstanceThis is an object that serves as a handle to a playing sound
  • 105. The SoundEffectInstanceengineInstance = engineSound.CreateInstance();When we call the Play method on a sound effect this is a “fire and forget” kind of sound playbackTo get more control over a sound we need to create an object that represents itA SoundEffect can be asked to create an object representing an instance of a sound being played by using the CreateInstance method
  • 106. Playing SoundsengineInstance.Play();...engineInstance.Pause();...engineInstance.Stop();The Play method on a SoundEffectInstance will start sound playbackWe can also call Pause and Stop to control the sound
  • 107. Controlling VolumeengineInstance.Volume= accelVector.Length() / volFactor;The Volume property lets you adjust the volume of a playing soundThe range is from 0 to 1:0 no sound+1 maximum volume
  • 108. Controlling PitchengineInstance.Pitch = accelVector.Length() / soundFactor;The Pitch property lets you adjust the pitch of a playing soundThe range is from -1 to 1:-1 octave low0 normal pitch+1 octave high
  • 109. Controlling PositionengineInstance.Pan = cheesePan;The Pan property lets you adjust the pan position of a playing soundThe range is from -1 to 1:-1 hard left0 center+1 right
  • 110. Sound Statusif (engineInstance.State == SoundState.Stopped){engineInstance.Play();}The SoundEffectInstance exposes a property that gives the playing statusThis is updated when the sound stops playingThe code above will play the sound again if it is stoppedThis is a primitive kind of looping
  • 111. Looping SoundsengineInstance.IsLooped = true;I can get the looping effect by simply restarting playback from the SoundEffectInstance each time the game detects that it has stoppedHowever, there is a much easier way of getting this effectI simply set the IsLooped property to true
  • 112. Demo 2: Games with SoundsDemo
  • 113. Silverlight and XNAIf you want to play sound effects in a Silverlight program you use the XNA SoundEffect classThe process is as follows:Add XNA to a Silverlight gameLoad the sound effect from a resourcePlay the sound effect as with XNAKeep the XNA system updated
  • 114. Adding XNA to a Silverlight GameThe first thing to do is add the reference to the XNA Framework to the solutionYou might get a warning when you do this, but it is OK114
  • 115. Adding XNA to a Silverlight GameNext you add the namespaces so you can easily use the objects115
  • 116. Adding Sound ResourcesNow you can add the sound itselfThese are stored as items of content in the solutionwav files work wellCreate a folder in your solution to keep things tidy116
  • 117. Adding Sound ResourcesNow you need to set the properties of the sound itemMake sure the build action is set to Content117
  • 118. Loading a SoundEffect118Beep = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds/beep.wav"));This code runs at the start of the gameIt creates a SoundEffect value from the sound resourcesThis mechanism is used in Silverlight because there is no Content Manager for a Silverlight application
  • 119. Playing a SoundEffect119beep.Play();The Play method works in exactly the same was as in XNAIf you want more control of the sound playback you can create and use SoundEffectInstance values to control a sound during playback
  • 120. Keeping XNA Awake120The XNA framework is driven by repeated calls of Draw and Update methods In Silverlight these do not happenWe need to update XNA to allow sound playback The FrameworkDispatcher.Update() method must be called at regular intervals to keep XNA sound workingThe best way to do this is to create a timer
  • 121. Creating a Timer121usingSystem.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 pageWe can create one that fires at the same rate as XNA, 30 times a secondWe can also bind a method to the tick event
  • 122. The Timer Tick event handler122voidtimer_Tick(object sender, EventArgs e){FrameworkDispatcher.Update();}When the timer ticks it just updates the XNA framework to keep sound playback working correctlyYou can also use this technique to animate Silverlight displays
  • 123. Demo 3: Silverlight with SoundDemo
  • 124. OrientationWindows Phone games can be played in many orientationsBy default the game is configured for landscape orientation
  • 125. Forcing Game OrientationYou can force a particular orientation by setting the size of the back bufferThis works by using the scaling hardware in the Windows Phone display
  • 126. The Magical ScalerThe scaler uses hardware, so your game is not slowed down by itIt interpolates to make the scaling look goodIt scales from 240x240 to 800x480 (or 480x800) It will add a letterbox (black bars) if the chosen aspect ratio doesn’t match the hardwareViewport properties and touch input positions in your program always match the scaled screen
  • 127. Selecting OrientationsYour game can indicate which orientations it can supportThe game above can support anything!
  • 128. Detecting ChangesThere is an event you can bind to if you need to detect orientation changes
  • 129. Using the full screenThe Windows Phone uses the top of the screen for status informationThis is not always displayed, but when an XNA game runs this space is always reserved for the status informationYou can see this if you change the theme background to Light
  • 130. Using the Full ScreenIf you ask to use the full screen this will hide the status barYou can do this in the Initialize method for your game
  • 131. XNA games and the Lock ScreenThe user of the phone can configure a Screen time-out value in the lock & wallpaper screenThis will time the screen out after a given interval if no user input is detectedThe system checks for user input from the touch screen and the hardware buttonsIt does not test the accelerometerThis means that games that are accelerometer controlled are liable to be timed out
  • 132. Disabling the screen timeoutGuide.IsScreenSaverEnabled = false;This statement disables the screen timeoutYour game will now run uninterruptedYou should use this with care howeverThe game is now in a position to run until the phone battery goes flatYou can re-enable the timeout by setting the property to true
  • 133. SummaryThe Windows Phone supports gameplay in multiple orientations which you can set in your game codeThe accelerometer allows games to be controlled by tipping the phoneXNA and Silverlight can play back soundXNA programs can access the media library in the phone
  • 134. Exercise 1: Use Multi-Touch in a windowsphonegame
  • 135. Exercise 2: use theaccelerometer in anxnaprogram

Editor's Notes

  1. Start Visual StudioSelect File&gt;New&gt;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.
  2. 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
  3. 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
  4. 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.
  5. 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.
  6. 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.
  7. Use a vector in case the way that the accelerometer works changes at some future time 
  8. 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.
  9. Use a vector in case the way that the accelerometer works changes at some future time 
  10. I’ve written a content extension for a wordlist importer, you can write others.
  11. Make the point that for sound effects you need wav files
  12. Make the point that content can be organised into folders
  13. Note that this is an improvement over the SoundEffect class, where the Play method is “fire and forget
  14. Note that I use the length of the acceleration vector to set the pitch of the sound.
  15. Note that I use the length of the acceleration vector to set the pitch of the sound.
  16. This is a primitive form of looping, but we have a much better one.
  17. This is how to really make sounds loop
  18. 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.
  19. Make the point that you can tailor the resolution and frequency to suit the application and keep the file small.
  20. If the action isn’t content, the sound won’t work.
  21. If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
  22. If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
  23. 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.
  24. If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
  25. If people have used XNA before this will be obvious stuff. But for Silverlight folks this will be new.
  26. 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.
  27. http://blogs.msdn.com/b/shawnhar/archive/2010/07/12/orientation-and-rotation-on-windows-phone.aspx
  28. 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
  29. http://blogs.msdn.com/b/shawnhar/archive/2010/07/12/orientation-and-rotation-on-windows-phone.aspx