///<summary>Handles periodically adding children to existing balls.</summary> public static void SetupPeriodicChildSpawning(this Game game, double expectedPerBallPerSecond, int maxChildrenPerBall, int maxGeneration) { game.Balls.CurrentAndFutureItems().Subscribe( ball => { if (ball.Value.Generation > maxGeneration) { return; } // keep track of children var curChildCount = 0; var children = new PerishableCollection <Ball>(); children .CurrentAndFutureItems() .ObserveNonPerishedCount(completeWhenSourceCompletes: true) .Subscribe(e => curChildCount = e, ball.Lifetime); // spawn children periodically at random game.StochasticRate( expectedPerBallPerSecond, ball.Lifetime, () => { if (curChildCount >= maxChildrenPerBall) { return; } var child = game.SpawnBall(parent: ball.Value); game.Connectors.Add(new Connector { Child = child, Parent = ball.Value }, child.Life.Lifetime); children.Add(child, child.Life.Lifetime); }); }, game.Life); }
private void SetupAndRunGame(Game game, bool initial) { // controls added to this collection should be displayed on the canvas until they perish var controls = new PerishableCollection <UIElement>(); controls.CurrentAndFutureItems().Subscribe( e => { canvas.Children.Add(e.Value); e.Lifetime.WhenDead(() => canvas.Children.Remove(e.Value)); }, game.Life); // balls should move and bounce off borders game.SetupMoveAndBounceBalls( playArea: () => new Rect(0, 0, canvas.ActualWidth, canvas.ActualHeight)); // connected balls should be be gently tugged towards each other game.SetupAttractBalls( deadRadius: 50, accellerationPerSecondChild: 10, accellerationPerSecondParent: 5); // balls should periodically spawn dependent children game.SetupPeriodicChildSpawning( expectedPerBallPerSecond: 0.2, maxChildrenPerBall: 2, maxGeneration: 5); // balls should be drawn using ellipse controls and have death animations game.SetupDrawBallsAsControls( controls, deathFadeOutDuration: 800.Milliseconds(), deathFinalRadiusFactor: 3); // ball connectors should be drawn using line controls and have cut and death animations game.SetupDrawConnectorsAsControls( controls, deathFadeDuration: 800.Milliseconds(), deathFinalThicknessFactor: 6, propagateBangColor: Colors.Green, propagateBangDuration: 400.Milliseconds(), propagateBangRotationsPerSecond: 3, propagateBangMaxRadius: 10, cutBangColor: Colors.Red, cutBangDuration: 400.Milliseconds(), cutBangMaxRadius: 15); // connectors that touch the cursor should die SetupMouseCutter(game, controls); // text displays of game state should track that state if (!initial) { SetupEnergyAndTime( game, energyLossForCutting: 2.5, energyGainPerConnectorBroken: 1); } // there should be a few root balls to start with foreach (var repeat in 5.Range()) { game.SpawnBall(parent: new Ball { Pos = new Point(game.Rng.NextDouble() * canvas.ActualWidth, game.Rng.NextDouble() * canvas.ActualHeight), Radius = 10, Life = new LifetimeSource(), Hue = game.Rng.NextDouble() * 3 }); } // run the game loop until the game is over game.Loop().ContinueWith(e => { // exceptions? }); }
private void SetupAndRunGame(Game game, bool initial) { // controls added to this collection should be displayed on the canvas until they perish var controls = new PerishableCollection<UIElement>(); controls.CurrentAndFutureItems().Subscribe( e => { canvas.Children.Add(e.Value); e.Lifetime.WhenDead(() => canvas.Children.Remove(e.Value)); }, game.Life); // balls should move and bounce off borders game.SetupMoveAndBounceBalls( playArea: () => new Rect(0, 0, canvas.ActualWidth, canvas.ActualHeight)); // connected balls should be be gently tugged towards each other game.SetupAttractBalls( deadRadius: 50, accellerationPerSecondChild: 10, accellerationPerSecondParent: 5); // balls should periodically spawn dependent children game.SetupPeriodicChildSpawning( expectedPerBallPerSecond: 0.2, maxChildrenPerBall: 2, maxGeneration: 5); // balls should be drawn using ellipse controls and have death animations game.SetupDrawBallsAsControls( controls, deathFadeOutDuration: 800.Milliseconds(), deathFinalRadiusFactor: 3); // ball connectors should be drawn using line controls and have cut and death animations game.SetupDrawConnectorsAsControls( controls, deathFadeDuration: 800.Milliseconds(), deathFinalThicknessFactor: 6, propagateBangColor: Colors.Green, propagateBangDuration: 400.Milliseconds(), propagateBangRotationsPerSecond: 3, propagateBangMaxRadius: 10, cutBangColor: Colors.Red, cutBangDuration: 400.Milliseconds(), cutBangMaxRadius: 15); // connectors that touch the cursor should die SetupMouseCutter(game, controls); // text displays of game state should track that state if (!initial) SetupEnergyAndTime( game, energyLossForCutting: 2.5, energyGainPerConnectorBroken: 1); // there should be a few root balls to start with foreach (var repeat in 5.Range()) { game.SpawnBall(parent: new Ball { Pos = new Point(game.Rng.NextDouble()*canvas.ActualWidth, game.Rng.NextDouble()*canvas.ActualHeight), Radius = 10, Life = new LifetimeSource(), Hue = game.Rng.NextDouble()*3 }); } // run the game loop until the game is over game.Loop().ContinueWith(e => { // exceptions? }); }