Example #1
0
		void ICmpUpdatable.OnUpdate()
		{

			// If the object we're controlling has been destroyed, forget about it
			if (this.controlObj != null && this.controlObj.Disposed)
				this.controlObj = null;
			
			// See what player inputs there are to handle
			if (this.input == null) this.input = new InputMapping();
			bool hasInputMethod = this.input.Method != InputMethod.Unknown;
			if (this.controlObj != null)
			{
				this.input.Update(this.controlObj.GameObj.Transform);
			}
			else
			{
				this.input.Update(null);
			}

			// Spawn the player object for the first time when input is detected
			if (this.controlObj != null && this.input.Method != InputMethod.Unknown && !hasInputMethod)
			{
				// Find an alive player or determine that no one has started playing yet
				bool gameAlreadyOver = false;
				Player alivePlayer = Player.AlivePlayers.FirstOrDefault();
				if (alivePlayer != null)
				{
					// Move near already alive player
					Vector3 alivePlayerPos = alivePlayer.controlObj.GameObj.Transform.Pos;
					this.controlObj.GameObj.Transform.Pos = alivePlayerPos;
				}
				else if (Player.AllPlayers.Any(p => p != this && p.IsPlaying))
				{
					// If we don't have an alive player, but do have playing players, the game must be already over.
					gameAlreadyOver = true;
				}
				else
				{
					// Move near initial spawn point
					this.controlObj.GameObj.Transform.Pos = SpawnPoint.SpawnPos;
				}

				// Spawn for the first time / enter the game
				if (!gameAlreadyOver)
				{
					this.controlObj.GameObj.Active = true;
				}
			}
			
			// Manage the object this player is supposed to control
			if (this.controlObj != null)
			{
				if (this.hasReachedGoal)
				{
					RigidBody body = this.controlObj.GameObj.GetComponent<RigidBody>();
					SpriteRenderer sprite = this.controlObj.GameObj.GetComponent<SpriteRenderer>();

					// If we've reached the goal, update the final animation and do nothing else
					float goalAnim = MathF.Clamp(((float)Time.GameTimer.TotalMilliseconds - this.goalReachTime) / 2000.0f, 0.0f, 1.0f);

					// Don't move
					body.LinearVelocity *= MathF.Pow(0.9f, Time.TimeMult);
					this.controlObj.TargetAngleRatio = 0.1f;
					this.controlObj.TargetThrust = Vector2.Zero;

					// Fade out
					if (sprite.CustomMaterial == null) sprite.CustomMaterial = new BatchInfo(sprite.SharedMaterial.Res);
					sprite.CustomMaterial.Technique = DrawTechnique.SharpAlpha;
					sprite.ColorTint = sprite.ColorTint.WithAlpha(1.0f - goalAnim);
					
					// Spawn a goal reached effect
					if (goalAnim > 0.2f && this.goalEffect != null && this.goalEffectInstance == null)
					{
						this.goalEffectInstance = this.goalEffect.Res.Instantiate(this.controlObj.GameObj.Transform.Pos);
						Scene.Current.AddObject(this.goalEffectInstance);
					}

					// Let the ship disappear
					if (goalAnim >= 1.0f)
					{
						this.controlObj.GameObj.Active = false;
					}
				}
				else if (this.controlObj.Active)
				{
					// Apply control inputs to the controlled object
					this.controlObj.TargetAngle = this.input.ControlLookAngle;
					this.controlObj.TargetAngleRatio = this.input.ControlLookSpeed;
					this.controlObj.TargetThrust = this.input.ControlMovement;
					if (this.input.ControlFireWeapon)
						this.controlObj.FireWeapon();
				}
				else if (hasInputMethod && Player.IsAnyPlayerAlive && !this.hasReachedGoal)
				{
					// Respawn when possible
					this.respawnTime += Time.MsPFMult * Time.TimeMult;
					if (this.respawnTime > RespawnDelay)
					{
						// Move near alive player
						Player alivePlayer = Player.AlivePlayers.FirstOrDefault(); 
						Vector3 alivePlayerPos = alivePlayer.controlObj.GameObj.Transform.Pos;
						this.controlObj.GameObj.Transform.Pos = alivePlayerPos;

						// Respawn
						this.respawnTime = 0.0f;
						this.controlObj.Revive();
					}
				}
			}

			// Quit the game when requested
			if (this.input.ControlQuit)
				DualityApp.Terminate();

			// If it's game over, allow to restart the game
			GameOverScreen gameOverScreen = Scene.Current.FindComponent<GameOverScreen>();
			if (gameOverScreen != null && gameOverScreen.HasGameEnded)
			{
				if (this.input.ControlStart)
					Scene.Reload();
			}
		}
Example #2
0
        void ICmpRenderer.Draw(IDrawDevice device)
        {
            // Create a buffer to cache and re-use vertices. Not required, but will boost performance.
            if (this.buffer == null)
            {
                this.buffer = new CanvasBuffer();
            }

            // Create a Canvas to auto-generate vertices from high-level drawing commands.
            Canvas canvas = new Canvas(device, this.buffer);

            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
            canvas.State.TextFont = this.font;

            // Retrieve players
            if (this.playerOne == null)
            {
                this.playerOne = Scene.Current.FindComponents <Player>().Where(p => p.Id == PlayerId.PlayerOne).FirstOrDefault();
            }
            if (this.playerTwo == null)
            {
                this.playerTwo = Scene.Current.FindComponents <Player>().Where(p => p.Id == PlayerId.PlayerTwo).FirstOrDefault();
            }

            // Is someone playing using mouse / keyboard? Display a mouse cursor then
            if (Player.AlivePlayers.Any(p => p.InputMethod == InputMethod.MouseAndKeyboard))
            {
                canvas.FillCircle(DualityApp.Mouse.X, DualityApp.Mouse.Y, 2.0f);
            }

            // Is any player alive? Keep that value in mind, won't change here anyway.
            bool isAnyPlayerAlive = Player.IsAnyPlayerAlive;

            // Draw health and info of player one
            if (this.IsPlayerActive(this.playerOne))
            {
                Ship playerShip = this.playerOne.ControlObject;

                if (playerShip.Active)
                {
                    // Draw a health bar when alive
                    float health = playerShip.Hitpoints;

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(12 - 1, device.TargetSize.Y - 10 - 198 - 1, 16 + 2, 196 + 2);

                    canvas.State.ColorTint = this.playerOne.Color;
                    canvas.DrawRect(10, device.TargetSize.Y - 10 - 200, 20, 200);
                    canvas.FillRect(12, device.TargetSize.Y - 10 - health * 198.0f, 16, health * 196.0f);
                }
                else if (isAnyPlayerAlive && !this.playerOne.HasReachedGoal)
                {
                    // Draw a respawn timer when dead
                    float   respawnPercentage = this.playerOne.RespawnTime / Player.RespawnDelay;
                    string  respawnText       = string.Format("Respawn in {0:F1}", (Player.RespawnDelay - this.playerOne.RespawnTime) / 1000.0f);
                    Vector2 textSize          = canvas.MeasureText(string.Format("Respawn in {0:F1}", 0.0f));

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(10 - 1, device.TargetSize.Y - 10 - textSize.Y - 2, textSize.X + 5, textSize.Y + 8);

                    canvas.State.ColorTint = this.playerOne.Color;
                    canvas.DrawText(respawnText, 10, device.TargetSize.Y - 10, 0.0f, Alignment.BottomLeft);
                    canvas.FillRect(10, device.TargetSize.Y - 10 - textSize.Y, textSize.X * respawnPercentage, 3);
                    canvas.FillRect(10, device.TargetSize.Y - 10, textSize.X * respawnPercentage, 3);
                }
            }

            // Draw health and info of player two
            if (this.IsPlayerActive(this.playerTwo))
            {
                Ship playerShip = this.playerTwo.ControlObject;

                if (playerShip.Active)
                {
                    // Draw a health bar when alive
                    float health = playerShip.Hitpoints;

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(device.TargetSize.X - 12 - 16 - 1, device.TargetSize.Y - 10 - 198 - 1, 16 + 2, 196 + 2);

                    canvas.State.ColorTint = this.playerTwo.Color;
                    canvas.DrawRect(device.TargetSize.X - 10 - 20, device.TargetSize.Y - 10 - 200, 20, 200);
                    canvas.FillRect(device.TargetSize.X - 12 - 16, device.TargetSize.Y - 10 - health * 198.0f, 16, health * 196.0f);
                }
                else if (isAnyPlayerAlive && !this.playerTwo.HasReachedGoal)
                {
                    // Draw a respawn timer when dead
                    float   respawnPercentage = this.playerTwo.RespawnTime / Player.RespawnDelay;
                    string  respawnText       = string.Format("{0:F1} to Respawn", (Player.RespawnDelay - this.playerTwo.RespawnTime) / 1000.0f);
                    Vector2 textSize          = canvas.MeasureText(string.Format("{0:F1} to Respawn", 0.0f));

                    canvas.State.ColorTint = ColorRgba.Black.WithAlpha(0.5f);
                    canvas.FillRect(device.TargetSize.X - 10 - textSize.X - 3, device.TargetSize.Y - 10 - textSize.Y - 2, textSize.X + 2, textSize.Y + 10);

                    canvas.State.ColorTint = this.playerTwo.Color;
                    canvas.DrawText(respawnText, device.TargetSize.X - 10, device.TargetSize.Y - 10, 0.0f, Alignment.BottomRight);
                    canvas.FillRect(device.TargetSize.X - 10 - textSize.X * respawnPercentage, device.TargetSize.Y - 10 - textSize.Y, textSize.X * respawnPercentage, 3);
                    canvas.FillRect(device.TargetSize.X - 10 - textSize.X * respawnPercentage, device.TargetSize.Y - 10, textSize.X * respawnPercentage, 3);
                }
            }
        }