From 02b1dd487409b260172b2516fc8efb379175270c Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Fri, 28 Feb 2020 17:08:34 -0500 Subject: [PATCH] Add simple NPC. GitOrigin-RevId: 47cd7abaf80d7ced14d0b4b92390c8c0edddae1c --- Shared/Input.cs | 2 +- Shared/NPC.cs | 46 +++++++++++++++++++++++++++++++++++++++++ Shared/Player.cs | 2 +- Shared/Shared.projitems | 1 + Shared/SneakGame.cs | 1 + Shared/Textures.cs | 1 + Shared/World.cs | 12 +++++++++++ 7 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 Shared/NPC.cs diff --git a/Shared/Input.cs b/Shared/Input.cs index ad33188..4afeb6a 100644 --- a/Shared/Input.cs +++ b/Shared/Input.cs @@ -42,7 +42,7 @@ namespace SemiColinGames { keyboard.IsKeyDown(Keys.K); Debug = gamePad.IsButtonDown(Buttons.Back) || keyboard.IsKeyDown(Keys.OemMinus); - Pause = gamePad.IsButtonDown(Buttons.Start) || keyboard.IsKeyDown(Keys.Pause); + Pause = gamePad.IsButtonDown(Buttons.Start) || keyboard.IsKeyDown(Keys.P); // Then potential motion directions. If the player attempts to input opposite directions at // once (up & down or left & right), those inputs cancel out, resulting in no motion. diff --git a/Shared/NPC.cs b/Shared/NPC.cs new file mode 100644 index 0000000..0d5a254 --- /dev/null +++ b/Shared/NPC.cs @@ -0,0 +1,46 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; + +namespace SemiColinGames { + class NPC { + private Point position; + + private const int spriteWidth = 96; + private const int spriteHeight = 81; + private const int spriteCenterYOffset = 3; + + public NPC(Point position) { + this.position = position; + } + + public int Facing { get; private set; } = 1; + + public void Update(float modelTime) { + if (Facing == 1 && position.X > 16 * 39) { + Facing = -1; + } + if (Facing == -1 && position.X < 16 * 24) { + Facing = 1; + } + position.X += (int) (120 * Facing * modelTime); + } + + private int SpriteIndex() { + int frameNum = (int) Clock.ModelTime.TotalMilliseconds / 125 % 4; + return 35 + frameNum; + } + + public void Draw(SpriteBatch spriteBatch) { + int index = SpriteIndex(); + Rectangle textureSource = new Rectangle(index * spriteWidth, 0, spriteWidth, spriteHeight); + Vector2 spriteCenter = new Vector2(spriteWidth / 2, spriteHeight / 2 + spriteCenterYOffset); + SpriteEffects effect = Facing == 1 ? + SpriteEffects.None : SpriteEffects.FlipHorizontally; + Color color = Color.White; + spriteBatch.Draw(Textures.Executioner.Get, position.ToVector2(), textureSource, color, 0f, + spriteCenter, Vector2.One, effect, 0f); + } + } +} diff --git a/Shared/Player.cs b/Shared/Player.cs index 78483f2..ef61401 100644 --- a/Shared/Player.cs +++ b/Shared/Player.cs @@ -263,7 +263,7 @@ namespace SemiColinGames { Rectangle textureSource = new Rectangle(index * spriteWidth, 0, spriteWidth, spriteHeight); Vector2 spriteCenter = new Vector2(spriteWidth / 2, spriteHeight / 2 + spriteCenterYOffset); SpriteEffects effect = Facing == 1 ? - SpriteEffects.FlipHorizontally : SpriteEffects.None; + SpriteEffects.None : SpriteEffects.FlipHorizontally; Color color = Color.White; if (invincibilityTime > 0 && invincibilityTime % 0.2f > 0.1f) { color = new Color(0.5f, 0.5f, 0.5f, 0.5f); diff --git a/Shared/Shared.projitems b/Shared/Shared.projitems index 7e3ef15..a7c8d9b 100644 --- a/Shared/Shared.projitems +++ b/Shared/Shared.projitems @@ -11,6 +11,7 @@ + diff --git a/Shared/SneakGame.cs b/Shared/SneakGame.cs index 192f921..72f6dfd 100644 --- a/Shared/SneakGame.cs +++ b/Shared/SneakGame.cs @@ -121,6 +121,7 @@ namespace SemiColinGames { float modelTime = (float) gameTime.ElapsedGameTime.TotalSeconds; Clock.AddModelTime(modelTime); player.Update(modelTime, input, world.CollisionTargets); + world.Update(modelTime); linesOfSight.Update(player, world.CollisionTargets); camera.Update(player.Position, world.Width); if (player.Health <= 0) { diff --git a/Shared/Textures.cs b/Shared/Textures.cs index 0b7ec64..f5b9cb8 100644 --- a/Shared/Textures.cs +++ b/Shared/Textures.cs @@ -34,6 +34,7 @@ namespace SemiColinGames { public static SpriteFont BannerFont; public static TextureRef Player = new TextureRef("sprites/ccg/ninja_female"); + public static TextureRef Executioner = new TextureRef("sprites/ccg/executioner_female"); public static TextureRef Heart = new TextureRef("sprites/semicolin/heart"); // Backgrounds are indexed by draw order; the first element should be drawn furthest back. diff --git a/Shared/World.cs b/Shared/World.cs index f3ac30c..6e20cdc 100644 --- a/Shared/World.cs +++ b/Shared/World.cs @@ -91,6 +91,8 @@ namespace SemiColinGames { readonly Tile[] tiles; readonly Tile[] decorations; + readonly NPC[] npcs = new NPC[1]; + // Size of World in terms of tile grid. private readonly int tileWidth; private readonly int tileHeight; @@ -105,6 +107,7 @@ namespace SemiColinGames { } public World(string levelSpecification) { + npcs[0] = new NPC(new Point(16 * 38, 16 * 12)); var tilesList = new List(); var decorationsList = new List(); string[] worldDesc = levelSpecification.Substring(1).Split('\n'); @@ -152,10 +155,19 @@ namespace SemiColinGames { new Vector2(Width + 1, 0), new Vector2(1, float.MaxValue)); } + public void Update(float modelTime) { + foreach (NPC npc in npcs) { + npc.Update(modelTime); + } + } + public void DrawBackground(SpriteBatch spriteBatch) { foreach (Tile t in decorations) { t.Draw(spriteBatch); } + foreach (NPC npc in npcs) { + npc.Draw(spriteBatch); + } } public void DrawForeground(SpriteBatch spriteBatch) {