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?