+ All Categories
Home > Documents > Constructor and New Fields // Don't synch draw() with vertical retrace of monitor...

Constructor and New Fields // Don't synch draw() with vertical retrace of monitor...

Date post: 14-Dec-2015
Category:
Upload: carlee-records
View: 215 times
Download: 2 times
Share this document with a friend
22
Pong in XNA
Transcript

Pong in XNA

Constructor and New Fields // Don't synch draw() with vertical retrace of monitor

graphics.SynchronizeWithVerticalRetrace = false;

IsFixedTimeStep = true; // default rate of 1/60 sec

private float fps;

private float updateInterval = 1.0f;

private float timeSinceLastUpdate = 0.0f;

private float framecount = 0;

IsFixedTimeStep, when true, will cause XNA to call Update() only after TargetElapsedTime seconds

have passes.

In Constructor

New private member fields.

New XNA 3.0 Windows GameIn 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 spritesIn 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

PaddlePosition

2d vectorVelocity ?

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; } 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 { }

What is this?

Declare some variablesBall 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 querygraphics.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 Paddlespaddle1 = 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 SpritesLoadContent()ballTexture = Content.Load<Texture2D>("ball");paddleTexture = Content.Load<Texture2D>("Paddle");

Draw()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>

Vector2

Rectangle

Let’s move the ball and paddlesUpdate()// 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 paddlesUpdate()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); }

This code looks very similar. Begs for a

convenience function

<F5> Compile and run

Lets add soundSolution 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 XACTDeclare 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()) {hitPaddleSound.play();theBall.motion = new Vector2(

theBall.motion.X*1.03f, theBall.motion.Y*1.03f);}

Speed up by 3% each hit

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; else return false; }

This is one way to see if two rectangles overlap. For many collisions you’ll want

to do pixel level 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);if (pad1.DPad.Down == ButtonState.Pressed) paddle1.motion = new Vector2(0, 5);if (pad1.DPad.Up == ButtonState.Pressed) paddle1.motion = new Vector2(0,-5);if (pad1.ThumbSticks.Left.Y != 0) paddle1.motion = new Vector2(0,pad1.ThumbSticks.Left.Y*-5.0f);paddle1.position += paddle1.motion;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);

arrow pad or the left thumb stick will move paddle. Could add keyboard arrow keys.KeyboardState keyboard = Keyboard.GetState(); keyboard.IsKeyDown(Keys.Up)

Don’t allow paddle to go past borders

<F5> Compile and run Can add AI for other player or paddle2.Height = 356;

ScoreSolution 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 desireChange 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 exampleCan change anything else you want

ScoreCreate a type and declare some variablespublic 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!

{ 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

}

Can’t just call normalize() since position is a struct and not a class.

ScoreDeclare some variables

SpriteFont Font1;Font1 = Content.Load<SpriteFont>("Courier New");Vector2 score1Pos;score1Pos = new Vector2(30,30) // Initialize

Draw scorespriteBatch.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 WhatWinning gameAdding paddle momentumMake paddle curved so edge bounces

differentUse reflect() from Vector2 and just change the

normalAI for the 2nd userAdd two player game, menu to select number

of usersThree player game?Four player game?Catch ball? Power ups?


Recommended