public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D border1Texture;
private Texture2D border2Texture;
private Texture2D ballPlayerTexture;
private Texture2D coinTexture;
private World _physicsWorld;
private Body ballBody;
private const float scale = 0.01f;
private static Random r = new Random((int)DateTime.Now.Ticks);
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
graphics.IsFullScreen = true;
graphics.SupportedOrientations = DisplayOrientation.LandscapeRight;
graphics.ApplyChanges();
}
private List<Body> coinBodies;
protected override void Initialize()
{
_physicsWorld = new World(new Vector2(0, 10), true);
coinBodies = new List<Body>();
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
border1Texture = Content.Load<Texture2D>("border1");
border2Texture = Content.Load<Texture2D>("border2");
ballPlayerTexture = Content.Load<Texture2D>("ballGame");
coinTexture = Content.Load<Texture2D>("ballPlayer");
_physicsWorld.ContactListener = new GameContactListener();
CreateBall();
CreateWalls();
CreateCoins();
}
private void CreateCoins()
{
var bodyDef = new BodyDef();
bodyDef.type = BodyType.Static;
var coinShape = new CircleShape();
coinShape._radius = coinTexture.Width/2f*scale;
var coinFixture = new FixtureDef();
coinFixture.isSensor = true;
coinFixture.shape = coinShape;
for(var i=0;i<10;i++)
{
var coinBody = _physicsWorld.CreateBody(bodyDef);
coinBody.CreateFixture(coinFixture);
coinBody.Position = new Vector2((float)r.NextDouble()*7.5f +.6f , (float)r.NextDouble() * 4.0f + .5f);
coinBodies.Add(coinBody);
}
}
private void CreateBall()
{
var ballDef = new BodyDef();
ballDef.type = BodyType.Dynamic;
var ballShape = new CircleShape();
ballShape._radius = ballPlayerTexture.Width/2f*scale;
var ballFixture = new FixtureDef();
ballFixture.shape = ballShape;
ballFixture.density = 1.0f;
ballBody = _physicsWorld.CreateBody(ballDef);
ballBody.Position = new Vector2(2.0f, 2.0f);
ballBody.CreateFixture(ballFixture);
}
private void CreateWalls()
{
var bodyDef = new BodyDef();
bodyDef.type = BodyType.Static;
var bodyShape = new PolygonShape();
bodyShape.SetAsEdge(new Vector2(0, .2f), new Vector2(8.0f, .2f));
var topBody = _physicsWorld.CreateBody(bodyDef);
topBody.CreateFixture(bodyShape, 0.0f);
var bottomBody = _physicsWorld.CreateBody(bodyDef);
bodyShape.SetAsEdge(new Vector2(0, 4.6f), new Vector2(8.0f, 4.6f));
bottomBody.CreateFixture(bodyShape, 0.0f);
var leftBody = _physicsWorld.CreateBody(bodyDef);
bodyShape.SetAsEdge(new Vector2(.2f, 0), new Vector2(.2f, 4.8f));
leftBody.CreateFixture(bodyShape, 0.0f);
var rightBody = _physicsWorld.CreateBody(bodyDef);
bodyShape.SetAsEdge(new Vector2(7.8f, 0), new Vector2(7.8f, 4.8f));
rightBody.CreateFixture(bodyShape, 0.0f);
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
_physicsWorld.Step(1/60f, 10, 10);
_physicsWorld.ClearForces();
var node = _physicsWorld.GetBodyList();
while(node!=null)
{
var body = node;
node = node.GetNext();
var coinStatus = (string)body.GetUserData();
if (coinStatus != "Remove") continue;
DestroyCoinBody(body);
}
HandleKeyDown();
base.Update(gameTime);
}
private void DestroyCoinBody(Body b)
{
_physicsWorld.DestroyBody(b);
coinBodies.Remove(b);
}
private KeyboardState prevKeyboardState;
private void HandleKeyDown()
{
var state = Keyboard.GetState();
Vector2 force = new Vector2();
if(state.IsKeyDown(Keys.Left) && prevKeyboardState.IsKeyDown(Keys.Left))
{
force += new Vector2(-10, 0);
}
if (state.IsKeyDown(Keys.Right) && prevKeyboardState.IsKeyDown(Keys.Right))
{
force += new Vector2(10, 0);
}
if (state.IsKeyDown(Keys.Up) && prevKeyboardState.IsKeyDown(Keys.Up))
{
force += new Vector2(0, -10);
}
if (state.IsKeyDown(Keys.Down) && prevKeyboardState.IsKeyDown(Keys.Down))
{
force += new Vector2(0, 10);
}
prevKeyboardState = state;
if(force!=Vector2.Zero)
{
ballBody.ApplyForce(force, ballBody.GetWorldCenter());
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
spriteBatch.Begin();
spriteBatch.Draw(ballPlayerTexture, ballBody.Position/scale, null, Color.White, ballBody.Rotation,
new Vector2(ballPlayerTexture.Width/2f, ballPlayerTexture.Height/2f), 1, SpriteEffects.None,
0);
foreach (var coinBody in coinBodies)
{
spriteBatch.Draw(coinTexture, coinBody.Position/scale, null, Color.White, coinBody.Rotation,
new Vector2(coinTexture.Width/2f, coinTexture.Height/2f), 1, SpriteEffects.None, 0);
}
spriteBatch.Draw(border1Texture, new Vector2(0, 0), Color.White);
spriteBatch.Draw(border1Texture, new Vector2(0, 460), Color.White);
spriteBatch.Draw(border2Texture,new Vector2(20,0),null,Color.White,MathHelper.PiOver2,Vector2.Zero,1,SpriteEffects.None,0);
spriteBatch.Draw(border2Texture, new Vector2(800, 0), null, Color.White, MathHelper.PiOver2, Vector2.Zero, 1, SpriteEffects.None, 0);
spriteBatch.End();
base.Draw(gameTime);
}
}
public class GameContactListener:IContactListener
{
/**
* Just Implement the BeginContact because we are Interested in knowing when the Fixtures overlap
*/
public void BeginContact(Contact contact)
{
//check to see if one of the contacts is a sensor if so then we set its data to a value and remove it
var fixtureA = contact.GetFixtureA();
var fixtureB = contact.GetFixtureB();
if(fixtureA.IsSensor())
{
fixtureA.GetBody().SetUserData("Remove");
}
if (fixtureB.IsSensor())
{
fixtureB.GetBody().SetUserData("Remove");
}
}
public void EndContact(Contact contact)
{
}
public void PostSolve(Contact contact, ref ContactImpulse impulse)
{
}
public void PreSolve(Contact contact, ref Manifold oldManifold)
{
}
}