diff --git a/Peli.xaml.cs b/Peli.xaml.cs index 0ce69a1..5de6360 100644 --- a/Peli.xaml.cs +++ b/Peli.xaml.cs @@ -94,8 +94,7 @@ public static void Main() new Application().Run(new Peli()); - //var peli = new Peli(); - //peli.PlayGame_Click(null, null); + //new Peli().PlayGame_Click(null, null); } private static PngBitmapEncoder RenderToBitmap(FrameworkElement sceneItem) diff --git a/PeliXNA/GameScreen.cs b/PeliXNA/GameScreen.cs index 6f822ed..3ea5e50 100644 --- a/PeliXNA/GameScreen.cs +++ b/PeliXNA/GameScreen.cs @@ -48,7 +48,7 @@ protected override void LoadContent() // Load content belonging to the screen manager. _spriteBatch = new SpriteBatch(GraphicsDevice); _lineBrush.Load(GraphicsDevice); - _ukkeli = new Ukkeli(new Vector2(500, 400), GraphicsDevice, _physicsSimulator); + _ukkeli = new Ukkeli(new Vector2(150, 800), GraphicsDevice, _physicsSimulator); foreach (var obstacle in _obstacles) { obstacle.Load(GraphicsDevice, _physicsSimulator); diff --git a/PeliXNA/Primitives/CircleBodyGeom.cs b/PeliXNA/Primitives/CircleBodyGeom.cs index e255a59..83b6768 100644 --- a/PeliXNA/Primitives/CircleBodyGeom.cs +++ b/PeliXNA/Primitives/CircleBodyGeom.cs @@ -35,7 +35,6 @@ public CircleBodyGeom(Vector2 position, int radius, float mass, GraphicsDevice g _geom = GeomFactory.Instance.CreateCircleGeom(physicsSimulator, _body, radius, 32); _geom.RestitutionCoefficient = 0.0f; _geom.FrictionCoefficient = 1.0f; - _geom.CollisionGroup = 1; _geom.CollisionCategories = CollisionCategory.All; _geom.CollidesWith = CollisionCategory.All; this.Color = Color.Yellow; diff --git a/PeliXNA/Primitives/RectangleBodyGeom.cs b/PeliXNA/Primitives/RectangleBodyGeom.cs index 29e8f2d..54fedde 100644 --- a/PeliXNA/Primitives/RectangleBodyGeom.cs +++ b/PeliXNA/Primitives/RectangleBodyGeom.cs @@ -42,7 +42,6 @@ public RectangleBodyGeom(Vector2 position, int width, int height, float mass, Gr _geom = GeomFactory.Instance.CreateRectangleGeom(physicsSimulator, _body, width, height, Vector2.Zero /*offset*/, 0 /*rotation offset*/); _geom.RestitutionCoefficient = 0.0f; _geom.FrictionCoefficient = 1.0f; - _geom.CollisionGroup = 1; _geom.CollisionCategories = CollisionCategory.All; _geom.CollidesWith = CollisionCategory.All; this.Color = Color.Yellow; @@ -66,6 +65,8 @@ public float FrictionCoefficient public int CollisionGroup { set { _geom.CollisionGroup = value; } } + public CollisionCategory CollisionCategories { set { _geom.CollisionCategories = value; } } + public float RotationDeg { get { return (float) MathExt.ToDegrees(_body.Rotation); } diff --git a/PeliXNA/Ukkeli.cs b/PeliXNA/Ukkeli.cs index 383e78d..2355ef7 100644 --- a/PeliXNA/Ukkeli.cs +++ b/PeliXNA/Ukkeli.cs @@ -6,6 +6,7 @@ using FarseerGames.FarseerPhysics; using FarseerGames.FarseerPhysics.Dynamics; using FarseerGames.FarseerPhysics.Dynamics.Joints; +using FarseerGames.FarseerPhysics.Dynamics.Springs; using FarseerGames.FarseerPhysics.Collisions; using FarseerGames.GettingStarted.DrawingSystem; using FarseerGames.FarseerPhysics.Factories; @@ -16,35 +17,119 @@ namespace Net.Brotherus public class Ukkeli { private RectangleBodyGeom _torso; + private RectangleBodyGeom _top; private CircleBodyGeom _feet; + private RectangleBodyGeom[] _connectors; + private RevoluteJoint[] _joints; + private AngleJoint[] _springs; + private GraphicsDevice _graphicsDevice; private PhysicsSimulator _physicsSimulator; - private int FEET_RADIUS = 30; - private int FEET_DISTANCE = 65; - public Ukkeli(Vector2 position, GraphicsDevice graphicsDevice, PhysicsSimulator physicsSimulator) { _graphicsDevice = graphicsDevice; _physicsSimulator = physicsSimulator; + // Feet + _feet = new CircleBodyGeom(position + new Vector2(0, 32), 32, 0.2f, graphicsDevice, physicsSimulator); + _feet.CollisionGroup = 1; + // Torso - _torso = new RectangleBodyGeom(position, new Vector2(32, 96), 2, _graphicsDevice, _physicsSimulator); + _torso = new RectangleBodyGeom(position, 32, 64, 0.2f, _graphicsDevice, _physicsSimulator); + _torso.CollisionGroup = 1; var joint = JointFactory.Instance.CreateFixedAngleJoint(_physicsSimulator, _torso.Body); - joint.TargetAngle = 0.0f; - joint.MaxImpulse = 300.0f; + joint.TargetAngle = 0; + joint.MaxImpulse = 800; + + // Feet-Torso + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _torso.Body, _feet.Body, position + new Vector2(0, 32)); + + // Top + var connectorSize = new Vector2(8, 26); + var connectorMass = 0.5f; + _top = new RectangleBodyGeom(position + new Vector2(0, -112), 32, 32, 2, _graphicsDevice, _physicsSimulator) { CollisionGroup = 2 }; + _connectors = new RectangleBodyGeom[] { + new RectangleBodyGeom(position + new Vector2(-16,-80), connectorSize, connectorMass, graphicsDevice, physicsSimulator) { CollisionGroup = 1 }, + new RectangleBodyGeom(position + new Vector2(16,-80), connectorSize, connectorMass, graphicsDevice, physicsSimulator) { CollisionGroup = 1 }, + new RectangleBodyGeom(position + new Vector2(-16,-48), connectorSize, connectorMass, graphicsDevice, physicsSimulator) { CollisionGroup = 1 }, + new RectangleBodyGeom(position + new Vector2(16,-48), connectorSize, connectorMass, graphicsDevice, physicsSimulator) { CollisionGroup = 1 } + }; + _joints = new RevoluteJoint[] { + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _connectors[0].Body, _top.Body, position + new Vector2(-16,-96) ), + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _connectors[1].Body, _top.Body, position + new Vector2(16, -96)), + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _connectors[0].Body, _connectors[2].Body, position + new Vector2(-16, -64)), + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _connectors[1].Body, _connectors[3].Body, position + new Vector2(16, -64)), + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _connectors[2].Body, _torso.Body, position + new Vector2(-16, -32)), + JointFactory.Instance.CreateRevoluteJoint(physicsSimulator, _connectors[3].Body, _torso.Body, position + new Vector2(16, -32)) + }; + foreach (var j in _joints) + { + j.Softness = 0.0f; + j.BiasFactor = 0.5f; // Correct more strongly + } + + _springs = new AngleJoint[] { + JointFactory.Instance.CreateAngleJoint(physicsSimulator, _top.Body, _connectors[0].Body), + JointFactory.Instance.CreateAngleJoint(physicsSimulator, _top.Body, _connectors[1].Body), + JointFactory.Instance.CreateAngleJoint(physicsSimulator, _connectors[0].Body, _connectors[2].Body), + JointFactory.Instance.CreateAngleJoint(physicsSimulator, _connectors[1].Body, _connectors[3].Body), + JointFactory.Instance.CreateAngleJoint(physicsSimulator, _connectors[2].Body, _torso.Body), + JointFactory.Instance.CreateAngleJoint(physicsSimulator, _connectors[3].Body, _torso.Body) + }; - _feet = new CircleBodyGeom(position + new Vector2(0, FEET_DISTANCE), FEET_RADIUS, 1, graphicsDevice, physicsSimulator); - //var _feetJoint = JointFactory.Instance.CreatePinJoint(physicsSimulator, _torso.Body, new Vector2(0, FEET_DISTANCE), _feet.Body, Vector2.Zero); - JointFactory.Instance.CreateSliderJoint(physicsSimulator, _torso.Body, new Vector2(0, FEET_DISTANCE), _feet.Body, Vector2.Zero, 0, 20); - SpringFactory.Instance.CreateLinearSpring(physicsSimulator, _torso.Body, Vector2.Zero, _feet.Body, Vector2.Zero, 1000, 5); + DoBounce = false; + } + + public float MaxConnectorImpulse + { + set + { + foreach (var spring in _springs) + { + spring.MaxImpulse = value; + } + } + } + + public bool DoBounce + { + set + { + if (value) + { + BounceAngle = 10; + MaxConnectorImpulse = 1000.0f; + } + else + { + BounceAngle = 80; + MaxConnectorImpulse = 100.0f; // Less "bouncy" fall to ground + } + } + } + + public float BounceAngle + { + set + { + var rad = MathExt.ToRadians(value); + _springs[0].TargetAngle = rad; + _springs[1].TargetAngle = -rad; + _springs[2].TargetAngle = -rad*2; + _springs[3].TargetAngle = rad*2; + _springs[4].TargetAngle = rad; + _springs[5].TargetAngle = -rad; + } } public void Draw(SpriteBatch spriteBatch) { _torso.Draw(spriteBatch); + _top.Draw(spriteBatch); _feet.Draw(spriteBatch); + foreach (var connector in _connectors) connector.Draw(spriteBatch); } internal void HandleKeyboardInput(InputState input, GameTime gameTime) @@ -71,15 +156,15 @@ internal void HandleKeyboardInput(InputState input, GameTime gameTime) // jumping if (input.IsNewKeyPress(Keys.LeftShift)) { - + DoBounce = true; } else if (input.IsKeyLifted(Keys.LeftShift)) { - + DoBounce = false; } } - private float TORQUE = 30000f; + private float TORQUE = 60000f; private float MAX_WALK_ANGULAR_SPEED = 8.0f; diff --git a/SceneCanvas.cs b/SceneCanvas.cs index eecbefc..d1585a2 100644 --- a/SceneCanvas.cs +++ b/SceneCanvas.cs @@ -22,7 +22,7 @@ public class SceneCanvas : Canvas private List objectPoints; private List tempLines; - private const double POLYGON_SIDE = 40.0; + private const double POLYGON_SIDE = 25.0; public SceneCanvas() { diff --git a/SeikkailuLaakso.suo b/SeikkailuLaakso.suo index 2eb3dd8..c8f72cf 100644 Binary files a/SeikkailuLaakso.suo and b/SeikkailuLaakso.suo differ