|
|
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System.Collections.Generic;
namespace SemiColinGames { class IdleState : IState<NPC> { float timeInState = 0;
public void Enter() { timeInState = 0; }
public string Update(NPC npc, float modelTime, World world) { timeInState += modelTime; if (timeInState > 1.0f) { npc.Facing *= -1; return "run"; } return null; } }
class RunState : IState<NPC> { public void Enter() {}
public string Update(NPC npc, float modelTime, World world) { int moveSpeed = 120; int desiredX = npc.Position.X + (int) (moveSpeed * npc.Facing * modelTime); int testPoint = desiredX + 12 * npc.Facing; // TODO: define the box modularly & correctly.
AABB npcBox = new AABB(new Vector2(testPoint, npc.Position.Y), new Vector2(1, 33)); Debug.AddRect(npcBox, Color.Cyan); bool foundBox = false; foreach (AABB box in world.CollisionTargets) { if (box.Intersect(npcBox) != null) { foundBox = true; break; } }
if (!foundBox) { return "idle"; } npc.Position.X = desiredX; return null; } }
public class NPC { private const int spriteWidth = 96; private const int spriteHeight = 81; private const int spriteCenterYOffset = 2; private readonly Vector2 eyeOffset = new Vector2(4, -3);
private FSM<NPC> fsm;
public NPC(Point position, int facing) { Position = position; Facing = facing; fsm = new FSM<NPC>(new Dictionary<string, IState<NPC>> { { "idle", new IdleState() }, { "run", new RunState() } }, "run"); }
public int Facing; public Point Position;
public Vector2 EyePosition { get { return Vector2.Add( Position.ToVector2(), new Vector2(eyeOffset.X * Facing, eyeOffset.Y)); } }
public float VisionRange { get { return 150; } }
public float FieldOfView { get { return FMath.DegToRad(120); } }
public Vector2 VisionRay { get { return new Vector2(VisionRange * Facing, 0); } }
public void Update(float modelTime, World world) { fsm.Update(this, modelTime, world); }
public void Draw(SpriteBatch spriteBatch) { Rectangle textureSource = Sprites.Executioner.GetTextureSource( fsm.StateName, Clock.ModelTime.TotalSeconds); // TODO: move this into Sprite metadata.
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); } } }
|