public void ApplyState(NetSessionState sessionState) { FocussedEntity = World.EntityById(sessionState.FocussedEntityId); ActivePlayer = PlayerById(sessionState.ActivePlayerId); Winner = PlayerById(sessionState.WinnerId); TurnState = (TurnState)sessionState.TurnState; State = (SessionState)sessionState.SessionState; }
/// <summary> /// Syncs the given world state into the physics world. /// Creates new physics bodies for entities that don't have one yet. /// </summary> public void PreparePhysicsEngine(World.World worldState) { if (worldState.StaticGeometry.Revision != TerrainRevision) UpdateTerrainBody(worldState.StaticGeometry); TerrainRevision = worldState.StaticGeometry.Revision; worldState.IsSomethingMoving = false; // Add Bodies for new entities var entities = worldState.Entities.ToArray(); foreach (var e in entities) { if (e.Disposed || e.Position.LengthSquared() > 100 * 100 || e.Position.Y < -10) { if (e.Position.Y < -10 && e as Ball != null) // the player drowned Game.Services.GetService<Sound.SoundControl>().PlaySound(Sound.SoundControl.DrownSound); RemoveEntity(e, worldState); continue; } Body body = e.PhysicsBody; if (body == null) { body = new Body(PhysicsWorld); body.BodyType = e.IsStatic ? BodyType.Static : BodyType.Dynamic; body.SleepingAllowed = true; body.Awake = true; body.CreateFixture(new CircleShape(e.Radius, 1.0f)); e.PhysicsBody = body; EntityIdByPhysicsBody[body] = e.ID; if (e is Ball) { body.Friction = 2.0f; body.Restitution = 0.1f; body.FixedRotation = true; body.Mass = 10f; } if (e is Shot) { var shot = e as Shot; body.Restitution = shot.Restitution; body.OnCollision += (a, b, contact) => { Vector2 normal; FixedArray2<Vector2> points; contact.GetWorldManifold(out normal, out points); Fixture targetFixture; if (contact.FixtureA.Body == shot.PhysicsBody) targetFixture = contact.FixtureB; else targetFixture = contact.FixtureA; if (TerrainBodies.Contains(targetFixture.Body)) { // Shot collides with terrain shot.OnTerrainCollision(worldState.StaticGeometry, points[0]); } else if (EntityIdByPhysicsBody.ContainsKey(targetFixture.Body)) { int entityId = EntityIdByPhysicsBody[targetFixture.Body]; Entity entity = worldState.EntityById(entityId); // Mutual collision if (entity != null) { entity.OnEntityCollision(shot); shot.OnEntityCollision(entity); } } return true; }; } } if (body.Position != e.Position || body.Rotation != e.Rotation) body.SetTransform(e.Position, e.Rotation); if (body.LinearVelocity != e.Velocity) // Apparently, the physics engine likes applying an impulse better than overwriting the velocity. // So, apply an impulse that changes the old velocity to the new one. body.ApplyLinearImpulse(body.Mass * (e.Velocity - body.LinearVelocity)); if (body.LinearVelocity.LengthSquared() > 0.0001 || body.AngularVelocity > 0.001) { worldState.IsSomethingMoving = true; } } }