Benchmarking in XNA

Download Report

Transcript Benchmarking in XNA

Constructor and New Fields
// Don't synch draw() with vertical retrace of monitor
graphics.SynchronizeWithVerticalRetrace = false; In Constructor
IsFixedTimeStep = true; // default rate of 1/60 sec
IsFixedTimeStep, when true, will cause XNA to call Update()
only after TargetElapsedTime seconds have passes.
private float fps;
private float updateInterval = 1.0f;
private float timeSinceLastUpdate = 0.0f;
private float framecount = 0;
New private
member fields.
New XNA 3.0 Windows Game
 In Visual Studio 2008
 File -> New -> Project

Project Type: XNA Game Studio 3.0 -> Windows Game (3.0)
 Name: Pong (or whatever you’d like)
 Let’s create some sprites
 In solution explorer

Under content <right click> -> Add new item->Bitmap file
 Create a Ball (mine is 12x12)
 Might want to rename it to ball
 Create a Paddle -- maybe name it paddle (mine is 14x56)
Before we go to far what objects?
 Ball
 Position

2d vector
 Velocity
 2d vector
 Paddle
 Position

2d vector
 Velocity ?
 Maybe, depends on if it keeps moving when user stops pressing
button. For now yes
 What about dimensions?
Let’s create helper class(es)
namespace Pong1
{
public class Thingy
{
public int Height { get; set; }
public int Width { get; set; }
public Vector2 position { get; set; }
What is this?
public Vector2 motion { get; set; }
public Rectangle rect {
get { return new Rectangle((int)position.X, (int)position.Y,
(int)Width, (int)Height); } }
}
public class Paddle : Thingy { }
public class Ball : Thingy { }
Declare some variables
Ball theBall;
Paddle paddle1;
Paddle paddle2;
Texture2D ballTexture;
Texture2D paddleTexture;
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
Initialize()
// Setup window dimensions.
// We could also used defaults and query
graphics.PreferredBackBufferHeight = SCREEN_HEIGHT;
graphics.PreferredBackBufferWidth = SCREEN_WIDTH;
graphics.PreferMultiSampling = false;
graphics.ApplyChanges();
// Initialize Ball
theBall = new Ball();
theBall.position = new Vector2(30, 30);
theBall.motion = new Vector2(3f, 1f);
theBall.Width = 12;
theBall.Height = 12;
Initialize()
// Initialize Paddles
paddle1 = new Paddle();
paddle1.position = new Vector2(0, 10);
paddle1.motion = new Vector2(0, 3);
paddle1.Width = 14;
paddle1.Height = 56;
paddle2 = new Paddle();
paddle2.position = new Vector2(630, 30);
paddle2.motion = new Vector2(0, -3);
paddle2.Width = 14;
paddle2.Height = 56;
Load and Display Sprites
 LoadContent()
ballTexture = Content.Load<Texture2D>("ball");
paddleTexture = Content.Load<Texture2D>("Paddle");
 Draw()
Vector2
spriteBatch.Begin();
spriteBatch.Draw(ballTexture, theBall.position, Color.White);
spriteBatch.Draw(paddleTexture, paddle1.position, Color.Blue);
spriteBatch.Draw(paddleTexture, paddle2.rect, Color.Red);
spriteBatch.End();
 <F5>
Rectangle
Let’s move the ball and paddles
 Update()
//
Move ball and make it bounce at boundaries.
theBall.position += theBall.motion;
if (theBall.position.X <= 0 || theBall.position.X >=
SCREEN_WIDTH)
theBall.motion = new Vector2(theBall.motion.X,
theBall.motion.Y); // reverse X direction
if (theBall.position.Y <= 0 || theBall.position.Y >=
SCREEN_HEIGHT - theBall.Height)
theBall.motion = new Vector2(theBall.motion.X, theBall.motion.Y);
Let’s move the ball and paddles
 Update()
This code looks very similar.
Begs for a convenience function
paddle1.position += paddle1.motion;
if (paddle1.position.Y <= 0) { // Don’t let it go beyond screen.
paddle1.position = new Vector2(paddle1.position.X, 0);
paddle1.motion = new Vector2(paddle1.motion.X, -paddle1.motion.Y)
}
if (paddle1.position.Y >= SCREEN_HEIGHT-paddle1.Height)
paddle1.position = new Vector2(0, SCREEN_HEIGHT - paddle1.Height);
paddle2.position += paddle2.motion;
if (paddle2.position.Y <= 0) {
paddle2.position = new Vector2(paddle2.position.X, 0);
paddle2.motion = new Vector2(paddle2.motion.X, -paddle2.motion.Y);
}
if (paddle2.position.Y >= SCREEN_HEIGHT - paddle2.Height) {
paddle2.position = new Vector2(paddle2.position.X, SCREEN_HEIGHT paddle2.Height);
paddle2.motion = new Vector2(paddle2.motion.X, -paddle2.motion.Y);
}
<F5> Compile and run
Lets add sound
 Solution Explorer
 Content <right click>

Add -> New folder
 Name it sound or audio
 Right click on your new folder

Add -> existing item
 Browse for a sound file you’d like to use, search for .wav
 I used ding.wav
 Also find sounds from the web
 Can use audacity to make and record them
Without using XACT
 Declare variable.
SoundEffect hitWallSound;
 LoadContent()
ContentManager contentManager = new
ContentManager(this.Services, @"Content\sound\");
hitWallSound = contentManager.Load<SoundEffect>("ding");
 Everytime ball hits a wall (in your update)
if (theBall.position.Y <= 0 || … ){
hitWallSound.Play();
theBall.motion = new Vector2(X, -Y);
}
<F5> Compile and run
Collide ball with paddle(s)
 In update()
if (CollisionWithPaddle()) {
Speed up by 3% each hit
hitPaddleSound.play();
theBall.motion = new Vector2(
theBall.motion.X*1.03f, theBall.motion.Y*1.03f);
}
CollisionWithPaddle()
private bool CollisionWithPaddle() {
if (theBall.motion.X > 0) {//Moving Left must hit player2
return(RectsCollide(paddle2.position.X,
paddle2.position.Y, paddle2.Width,
paddle2.Height, theBall.position.X,
theBall.position.Y,theBall.Width,
theBall.Height));
else
return(RectsCollide(paddle1.position.X,
paddle1.position.Y, paddle1.Width, paddle1.Height,
theBall.position.X, theBall.position.Y,
theBall.Width, theBall.Height));
}
RectsCollide()
private bool RectsCollide(float x1, float y1,
float w1, float h1, float x2, float y2,
float w2, float h2)
{
if (x2 - w2<= x1 && x1 <= x2 + w2
&& y1 - h2 <= y2 && y2 <= y1 + h1)
return true;
This is one way to see if two rectangles overlap.
else
For many collisions you’ll want to do pixel level
return false; collisions. Many examples on the web, start with
}
overlapping rectangles, then check for two
pixels in the overlap that are not transparent.
One player game - update()
GamePadState pad1 = GamePad.GetState(PlayerIndex.One);
paddle1.motion = new Vector2(0, 0);
arrow pad or the left thumb
if (pad1.DPad.Down == ButtonState.Pressed) stick will move paddle. Could
paddle1.motion = new Vector2(0, 5);
add keyboard arrow keys.
if (pad1.DPad.Up == ButtonState.Pressed)
KeyboardState keyboard
paddle1.motion = new Vector2(0,-5);
= Keyboard.GetState();
keyboard.IsKeyDown(Keys.Up)
if (pad1.ThumbSticks.Left.Y != 0)
paddle1.motion = new Vector2(0,pad1.ThumbSticks.Left.Y*-5.0f);
paddle1.position += paddle1.motion;
Don’t allow paddle to go past borders
if (paddle1.position.Y <= 0)
paddle1.position = new Vector2(paddle1.position.X, 0);
if (paddle1.position.Y >= SCREEN_HEIGHT-paddle1.Height)
paddle1.position=new Vector2(0,SCREEN_HEIGHT- paddle1.Height);
<F5> Compile and run
Can add AI for other player or
paddle2.Height = 356;
Score
 Solution Explorer
 Content (right click)

Add -> New Item
 Sprite Font
 Change name to Courier New.spritefont

This name is what you want to call it in the program
 Now in the editor, edit the XML to your desire
 Change the fontname to Courier New or whatever you
want, you can look in control panel for available fonts.
 Change the size to 32 for this example
 Can change anything else you want
Score
 Create a type and declare some variables
public class Aplayer {
private int _score = 0;
public int Score {
get { return _score; }
set { _score = value; }
} }
APlayer player1;
APlayer player2;
 In initialize()
player1 = new APlayer();
player2 = new APlayer();
Score - Update()
if (theBall.position.X <= 0 || theBall.position.X >=
SCREEN_WIDTH) // Someone has scored!
{
Can’t just call normalize() since position is a
struct and not a class.
PlayWallHit();
if (theBall.motion.X < 0) player2.Score++;
else player1.Score++;
float L = theBall.motion.Length();
theBall.motion *= new Vector2(-3.0f/L, 3.0f/L);
theBall.position = new Vector2(320,
theBall.position.Y); // Start ball in the middle
}
Score
 Declare some variables
SpriteFont Font1;
Font1 = Content.Load<SpriteFont>("Courier New");
Vector2 score1Pos;
score1Pos = new Vector2(30,30) // Initialize
 Draw score
spriteBatch.DrawString(Font1, player1.Score.ToString(),
score1Pos, Color.White, 0, Vector2.Zero, 1.0f,
SpriteEffects.None, 0.5f);
If you want to center about point
Vector2 FontOrigin = Font1.MeasureString(score) / 2;
spriteBatch.DrawString(Font1, score, score1Pos, Color.White,
0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);
Now What
 Winning game
 Adding paddle momentum
 Make paddle curved so edge bounces different
 Use reflect() from Vector2 and just change the normal
 AI for the 2nd user
 Add two player game, menu to select number of users
 Three player game?
 Four player game?
 Catch ball? Power ups?