I made a simple pinball game, with only 4 elements: table, ball, 2 bumpers;
table and ball works perfectly(both physics and drawing), but i cant setup the bumpers.
when I draw Meshes!(not models), it has no scale and wrong orientation. I can't get how draw meshes using information from MobileMeshes.
here is all of the code:
Code: Select all
System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using BEPUphysics;
using BEPUphysics.Collidables;
using BEPUphysics.CollisionShapes;
using BEPUphysics.Constraints;
using BEPUphysics.Entities;
using BEPUphysics.Materials;
using BEPUphysics.CollisionRuleManagement;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.DataStructures;
using BEPUphysics.MathExtensions;
namespace WindowsGame5
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
Space space;
SpriteBatch spriteBatch;
Camera Camera;
Model Table_model,Left_model, Right_model,Ball_model;
Sphere Ball_ent;
StaticMesh Table_ent;
MobileMesh Left_ent, Right_ent;
public MouseState MouseState;
public KeyboardState KeyboardState;
public Game()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferMultiSampling = true;
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
space = new Space(); //Create a space that will handle physics.
space.ForceUpdater.Gravity = (new Vector3(0,-(float)Math.Sin(MathHelper.ToRadians(80)),(float)Math.Cos(MathHelper.ToRadians(80))) ) *10;// create a gravity, it is inclined to simulate table inclination, it's bit easier that rotating table;
KeyboardState = new KeyboardState();
MouseState = new MouseState();
Camera = new Camera(this,new Vector3(4f, 20f, 10f), 10);
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
//Load all models that will be used in this Alpha;
//And enable default lght for each;
Table_model = Content.Load<Model>("pinballtable");
Left_model = Content.Load<Model>("LeftFl");
Right_model = Content.Load<Model>("RightFl");
Ball_model = Content.Load<Model>("ball");
//Create an entity for each model that Physics will work with;
//first of all the table;
Vector3[] V;
int[] I;
TriangleMesh.GetVerticesAndIndicesFromModel(Table_model, out V, out I); //get data about shapes.
Table_ent = new StaticMesh(V, I); //asign data to a staticmesh entity;
space.Add(Table_ent); // Add tabl to space, now you can collide eith it;
// ball, as moving sphere to reduce calculs;
Ball_ent = new Sphere(Ball_model.Bones[0].Transform.Translation, Ball_model.Meshes[0].BoundingSphere.Radius, 10f); //position from bones transform, radius from actual model radius, and a random mass value;
Ball_ent.Material.Bounciness = 0f;
Ball_ent.Material.KineticFriction = .8f;
space.Add(Ball_ent); // Add ball to space, now we have a ball on table!super
//Bumpers, two boxes left and right, but i will make them MobileMesh because soon they wont be boxes bun coplex shape.
// first left bumper;
TriangleMesh.GetVerticesAndIndicesFromModel(Left_model,out V,out I);
Left_ent = new MobileMesh(V, I, AffineTransform.Identity, MobileMeshSolidity.Solid); // this is the dclaration;
Left_ent.Position = Left_model.Bones[0].Transform.Translation; // position need to be setup manually becauseof mobileMesh particularities;
Left_ent.OrientationMatrix = Matrix3X3.CreateFromMatrix(Left_model.Bones[0].Transform);// orientation need to be set manually too;
space.Add(Left_ent);// Thats all for left bumper!
//right bumper
TriangleMesh.GetVerticesAndIndicesFromModel(Right_model,out V,out I);
Right_ent = new MobileMesh(V, I, AffineTransform.Identity, MobileMeshSolidity.Clockwise); // this is the dclaration, I use clockwise solidity just cuz it's cheapier;
Right_ent.Position = Right_model.Bones[0].Transform.Translation; // position need to be setup manually becauseof mobileMesh particularities;
Right_ent.Orientation = Quaternion.CreateFromRotationMatrix(Right_model.Bones[0].Transform);// orientation need to be set manually too;
space.Add(Right_ent);// Thats all for right bumper!
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed|| KeyboardState.IsKeyDown(Keys.Escape))
this.Exit();
MouseState = Mouse.GetState();
KeyboardState = Keyboard.GetState();
space.Update();
Camera.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
// TODO: Add your update logic here
if(KeyboardState.IsKeyDown(Keys.Up)){
Vector3 v = new Vector3(0,0,-5);
Ball_ent.ApplyLinearImpulse(ref v);
}
if(KeyboardState.IsKeyDown(Keys.Down)){
Vector3 v = new Vector3(0,0,5);
Ball_ent.ApplyLinearImpulse(ref v);
}
if(KeyboardState.IsKeyDown(Keys.Left)){
Vector3 v = new Vector3(-5,0,0);
Ball_ent.ApplyLinearImpulse(ref v);
}
if(KeyboardState.IsKeyDown(Keys.Right)){
Vector3 v = new Vector3(5,0,0);
Ball_ent.ApplyLinearImpulse(ref v);
}
base.Update(gameTime);
}
/* Matrix M3to4(Matrix3X3 M)
{
var M4 = new Matrix();
M4.Forward = M.Forward;
M4.Left = M.Left;
M4.Up = M.Up;
return M4;
}
*/
void drawFirstMesh(Model M, Entity E)// my custom method to fastly draw some models that folow their physic representation;
{
Matrix[] Mat = new Matrix[2];
ModelMesh D = M.Meshes[0];
BasicEffect B = D.Effects[0] as BasicEffect;
B.EnableDefaultLighting();
B.World =E.WorldTransform;
B.Projection = Camera.ProjectionMatrix;
B.View = Camera.ViewMatrix;
D.Draw();
}
/// <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);
Table_model.Draw(Matrix.Identity, Camera.ViewMatrix, Camera.ProjectionMatrix);
drawFirstMesh(Ball_model, Ball_ent);
//drawFirstMesh(Right_model, Right_ent);
drawFirstMesh(Left_model, Left_ent);
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
PS. Norbo thanks for help with registration.