public class Game1 :Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D ballTexture;
private Texture2D groundTexture;
private Texture2D boxTexture;
private Texture2D boardTexture;
private World world;
private Body BallBody;
private Body BoardBody;
private List<Body> boxBodies;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
// Pre-autoscale settings.
graphics.PreferredBackBufferWidth = 480;
graphics.PreferredBackBufferHeight = 800;
graphics.IsFullScreen = true;
}
protected override void Initialize()
{
world = new World(new Vector2(0, 10), false);
boxBodies = new List<Body>();
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
ballTexture = Content.Load<Texture2D>("ball");
boardTexture = Content.Load<Texture2D>("board");
boxTexture = Content.Load<Texture2D>("box");
groundTexture = Content.Load<Texture2D>("ground");
CreateGroundAndWalls();
CreateBallBody();
CreateBoardBody();
CreateBoxBodies();
}
private const float ScaleFactor = 0.01f;
private void CreateBallBody()
{
var bodyDef = new BodyDef();
bodyDef.type = BodyType.Dynamic;
var circleShape = new CircleShape();
circleShape._radius = .3f;
var ballFixture = new FixtureDef();
ballFixture.shape = circleShape;
ballFixture.restitution = .5f;
ballFixture.density = 1.0f;
BallBody = world.CreateBody(bodyDef);
BallBody.CreateFixture(ballFixture);
BallBody.Position = new Vector2(2.5f, .5f);
}
private void CreateBoardBody()
{
var bodyDef = new BodyDef {type = BodyType.Dynamic};
var boardShape = new PolygonShape();
boardShape.SetAsBox(((boardTexture.Width/2f)*ScaleFactor), ((boardTexture.Height/2f)*ScaleFactor));
var boardFixture = new FixtureDef {shape = boardShape, density=1.0f, friction = 0.1f};
BoardBody = world.CreateBody(bodyDef);
BoardBody.CreateFixture(boardFixture);
BoardBody.Position = new Vector2(2.5f, 1.0f);
}
private void CreateBoxBodies()
{
var bodyDef = new BodyDef {type = BodyType.Dynamic};
var bodyShape = new PolygonShape();
bodyShape.SetAsBox(.25f,.25f);
var boxFixture = new FixtureDef {restitution = .4f, density=1.0f, shape = bodyShape};
for(var i=1;i<6;i++)
{
var boxBody = world.CreateBody(bodyDef);
boxBody.CreateFixture(boxFixture);
boxBody.Position = new Vector2(1.5f, 7.0f-i);
boxBody.SetUserData("Box");
boxBodies.Add(boxBody);
}
for(var i=1;i<6;i++)
{
var boxBody = world.CreateBody(bodyDef);
boxBody.CreateFixture(boxFixture);
boxBody.Position = new Vector2(3.5f, 7.0f-i);
boxBody.SetUserData("Box");
boxBodies.Add(boxBody);
}
}
private void CreateGroundAndWalls()
{
var grounDef = new BodyDef {type = BodyType.Static};
var groundFix = new FixtureDef {restitution = 0.0f, density = 0.0f};
var groundShape = new PolygonShape();
groundShape.SetAsEdge(new Vector2(0, 7.5f), new Vector2(4.8f, 7.5f));
var groundBody = world.CreateBody(grounDef);
groundFix.shape = groundShape;
groundBody.CreateFixture(groundFix);
groundShape.SetAsEdge(new Vector2(0, 0), new Vector2(0f, 8.0f));
var leftBody = world.CreateBody(grounDef);
groundFix.shape = groundShape;
leftBody.CreateFixture(groundFix);
groundShape.SetAsEdge(new Vector2(4.8f, 0), new Vector2(4.8f, 8.0f));
var rightBody = world.CreateBody(grounDef);
groundFix.shape = groundShape;
rightBody.CreateFixture(groundFix);
groundShape.SetAsEdge(new Vector2(0, 0), new Vector2(4.8f, 0));
var topBody = world.CreateBody(grounDef);
groundFix.shape = groundShape;
topBody.CreateFixture(groundFix);
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
world.Step(1/60f, 10, 10);
HandleClick();
base.Update(gameTime);
}
private MouseState prevState;
private void HandleClick()
{
var currentState = Mouse.GetState();
if(prevState.LeftButton==ButtonState.Released && currentState.LeftButton==ButtonState.Pressed)
{
//lets find the closest box
Fixture choosenFixture = null;
var mousePosition = new Vector2(currentState.X, currentState.Y)*ScaleFactor;
var aabb = new AABB();
aabb.upperBound = new Vector2(mousePosition.X+.01f, mousePosition.Y+.01f);
aabb.lowerBound = new Vector2(mousePosition.X-.01f, mousePosition.Y-.01f);
world.QueryAABB(found =>
{
if (found.GetBody().GetUserData() != null)
{
if(found.TestPoint(mousePosition))
choosenFixture = found;
return true;
}
return false;
}, ref aabb);
if(choosenFixture!=null)
{
var bodyToKill = choosenFixture.GetBody();
bodyToKill.SetAwake(true);
world.DestroyBody(bodyToKill);
boxBodies.Remove(bodyToKill);
}
}
prevState = currentState;
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
foreach (var boxBody in boxBodies)
{
spriteBatch.Draw(boxTexture, boxBody.Position / ScaleFactor, null, Color.YellowGreen, boxBody.Rotation, new Vector2(boxTexture.Width / 2f, boxTexture.Height / 2f), 1, SpriteEffects.None, 0);
}
spriteBatch.Draw(boardTexture, BoardBody.Position/ScaleFactor, null, Color.Blue, BoardBody.Rotation,
new Vector2(boardTexture.Width / 2f, boardTexture.Height / 2f), 1, SpriteEffects.None, 0);
spriteBatch.Draw(ballTexture, BallBody.Position/ScaleFactor, null, Color.Red, BallBody.Rotation,
new Vector2(ballTexture.Width/2f, ballTexture.Height/2f), 1, SpriteEffects.None, 0);
spriteBatch.Draw(groundTexture, new Vector2(0, 750), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}