wp7 hub_xna overview
Post on 12-May-2015
1.002 Views
Preview:
DESCRIPTION
TRANSCRIPT
Windows Phone 7 XNA A different kind of phone, designed for a life in motion
GETTING STARTED WITH XNA
A framework to create game applications
Topics Overview of XNA How games run The XNA Game class Adding and managing game assets Creating and drawing game sprites
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
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
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
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
Creating a Game
The Windows Phone SDK provides a Windows Phone game project type
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
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
11
Demo 1: New Game
Demo
What a Game Does When it Runs1. Initialise all the resources at the start
fetch all textures, models, scripts etc2. Repeatedly run the game:
1. Update the game world read the user input, update the state and position of game
elements
2. Draw the game world render the game elements on the viewing device
XNA Game Class Methods
partial class PongGame : Microsoft.Xna.Framework.Game
{
protected override void LoadContent
(bool loadAllContent)
{
}
protected override void Update(GameTime gameTime)
{
}
protected override void Draw(GameTime gameTime)
{
}
}
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
Loading Game Content
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.
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to
// draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
}
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
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
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");
Storing the Ball Texture in the game
XNA provides a Texture2D type 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
// Game World
Texture2D ballTexture;
Loading Content into the Ball Texture
LoadContent is 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
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to
// draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
ballTexture = Content.Load<Texture2D>("WhiteDot");
}
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
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
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
Positioning the Ball using a Rectangle
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
// Game World
Texture2D ballTexture;
Rectangle ballRectangle;
The Rectangle structure
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
Rectangle ballRectangle = new Rectangle(
0, 0,
ballTexture.Width, ballTexture.Height),
Color.White);
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
XNA Game Draw Method
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
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
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
SpriteBatch Begin and End
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
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
// Code that uses spriteBatch to draw the display
spriteBatch.End();
base.Draw(gameTime);
}
Using SpriteBatch.Draw
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
spriteBatch.Draw(ballTexture, ballRectangle, Color.White);
Rectangle Funnew Rectangle(
0, 0,
ballTexture.Width,
ballTexture.Height)
new Rectangle(
0, 0, // position
200,100) // size
new Rectangle(
50, 50, // position
60, 60) // size
32
Demo 2: Dot Sizes
Demo
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
Creating the ballRectangle variable
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
ballRectangle = new Rectangle(
0, 0,
GraphicsDevice.Viewport.Width / 20,
GraphicsDevice.Viewport.Width / 20);
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”
The Update Method
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
protected override void Update(GameTime gameTime)
{
// TODO: Add your update logic here
base.Update(gameTime);
}
Simple Update Method
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
protected override void Update(GameTime gameTime)
{
ballRectangle.X++;
ballRectangle.Y++;
base.Update(gameTime);
}
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
39
Demo 2: Moving Dot
Demo
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
CREATING GAMEPLAY WITH XNA
Topics Controlling the movement of a sprite Creating multiple sprites Using touch input to control sprite movement Detecting sprite collisions Displaying text
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
Accurate ball positioning
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
float ballX = 0;
float ballY = 0;
Accurate ball positioning
The floating point position values are converted to integers to set the position of the draw rectangle
This is performed during the Update method
ballRectangle.X = (int)(ballX + 0.5f);
ballRectangle.Y = (int)(ballY + 0.5f);
Controlling Ball Movement
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
float ballXSpeed = 3;
float ballYSpeed = 3;
Moving the Ball
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
ballX = ballX + ballXSpeed;
ballY = ballY + ballYSpeed;
Going off the Edge
(0,0)
(0,height) (width, height)
(width, 0)
x +texture width > width
x < 0
y < 0
y + texture height > height
Making the Ball Bounce
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
if (ballX < 0 ||
ballX + ballRectangle.Width > GraphicsDevice.Viewport.Width)
{
ballXSpeed = -ballXSpeed;
}
50
Demo 1: Bouncing Ball
Demo
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
Game Variables
// Game World
Texture2D ballTexture;
Rectangle ballRectangle;
float ballX;
float ballY;
float ballXSpeed = 3;
float ballYSpeed = 3;
Texture2D lPaddleTexture;
Rectangle lPaddleRectangle;
float lPaddleSpeed = 4;
float lPaddleY; // Repeat these for the right paddle
// Distance of paddles from screen edge
int margin;
Loading GameTextures
When the game starts the LoadContent method is called to load textures and other game assets
We now have three textures in the game
protected override void LoadContent()
{
ballTexture = Content.Load<Texture2D>("ball");
lPaddleTexture = Content.Load<Texture2D>("lpaddle");
rPaddleTexture = Content.Load<Texture2D>("rpaddle");
// scale the texture draw rectangles here
}
Setting up the paddles
This code positions the paddles on the screen and sets up their sizes
margin = GraphicsDevice.Viewport.Width / 20;
lPaddleRectangle = new Rectangle(
margin, 0,
GraphicsDevice.Viewport.Width / 20,
GraphicsDevice.Viewport.Height / 5);
rPaddleRectangle = new Rectangle(
GraphicsDevice.Viewport.Width –
lPaddleRectangle.Width - margin, 0,
GraphicsDevice.Viewport.Width / 20,
GraphicsDevice.Viewport.Height / 5);
Initial game positions
The LoadContent method puts the paddles and balls at their starting positions as shown above
55
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
Getting the Touch Panel status
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
TouchCollection touches = TouchPanel.GetState();
Using the Touch information
If we have a touch location we use the position of the touch to move the paddle up or down
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
Using the Touch information
If the collection contains some TouchLocation we update the paddle position
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
Using the Touch information
Get the touch location at the start of the collection
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
Using the Touch information
Test the Y component of the position of touch against half the height of the screen
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
Using the Touch information
Move the paddle down if the player touches the bottom half of the screen
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
Using the Touch information
Move the paddle up if the player touches the top half of the screen
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
Using the Touch information
Remember that increasing Y moves things down the screen (origin at top left)
if (touches.Count > 0)
{
if (touches[0].Position.Y >
GraphicsDevice.Viewport.Height / 2)
{
lPaddleY = lPaddleY + lPaddleSpeed;
}
else
{
lPaddleY = lPaddleY - lPaddleSpeed;
}
}
65
Demo 2: Paddle Control
Demo
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
Rectangle Intersection
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
if (ballRectangle.Intersects(lPaddleRectangle))
{
ballXSpeed = -ballXSpeed;
}
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
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
SpriteFont XML
The font used and the size are set in an XML file You can edit this to get different sizes and styles
Loading a Font
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
SpriteFont font;
protected override void LoadContent()
{
// Rest of LoadContent here
font = Content.Load<SpriteFont>("MessageFont");
}
Drawing text
The DrawString method renders a string using the font that has been loaded
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.DrawString(
font,
"Hello world",
new Vector2(100, 100),
Color.White);
// Rest of Draw here
}
73
Demo 3: Completed Pong Game
Demo
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
GAMES ON WINDOWS PHONE
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
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
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
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
Adding the Sensors library
We need to add Microsoft.Devices.Sensors to the solution references to bring in the library
Adding the Namespaceusing Microsoft.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
Creating an AccelerometerAccelerometer acc = new Accelerometer();acc.ReadingChanged += new EventHandler<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
Accelerometer Events
Vector3 accelState = Vector3.Zero;void acc_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
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
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
“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
Demo 1: Tipping Pong game
Demo
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
What might happen…
1. Update runs and reads the X value of the acceleration
2. The Accelerometer event fires and starts running. It generates and stores new values of X, Y and Z
3. Update reads the Y and Z values from the updated values
4. Update now has “scrambled” data
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
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
Accelerometer Events and Lock
object accelLock = new object();void acc_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 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
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
“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
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
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)
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 fromhttp://audacity.sourceforge.net/
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
Content Properties
The content Properties pane identifies the asset name and the importer to use
SoundEffect variables
// Sound effectsSoundEffect dingSound;SoundEffect explodeSound;
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
The LoadContent method
protected override void LoadContent(){ // 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
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
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
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
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
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
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
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
Sound Status
1. if (engineInstance.State == SoundState.Stopped)2. {3. engineInstance.Play();4. }
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
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
Demo 2: Games with Sounds
Demo
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
115
Adding XNA to a Silverlight Game
Next you add the namespaces so you can easily use the objects
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
117
Adding Sound Resources
Now you need to set the properties of the sound item
Make sure the build action is set to Content
118
Loading a SoundEffect
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
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
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
using System.Windows.Threading;
DispatcherTimer timer = new DispatcherTimer();timer.Tick += new EventHandler(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
void timer_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
Demo 3: Silverlight with Sound
Demo
Orientation
Windows Phone games can be played in many orientations
By default the game is configured for landscape orientation
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
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
Selecting Orientations
Your game can indicate which orientations it can support
The game above can support anything!
Detecting Changes
There is an event you can bind to if you need to detect orientation changes
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
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
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
Disabling the screen timeout
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
Guide.IsScreenSaverEnabled = false;
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
EXERCISE 1: USE MULTI-TOUCH IN A WINDOWS PHONE GAME
EXERCISE 2: USE THE ACCELEROMETER IN AN XNA PROGRAM
top related