|
|
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic;
namespace SemiColinGames { class IdleState : IState<Object> { private readonly NPC npc; private float timeInState = 0;
public IdleState(NPC npc) { this.npc = npc; }
public void Enter() { timeInState = 0; }
public string Update(float modelTime, SneakWorld world, Object _) { timeInState += modelTime; if (timeInState > 1.0f) { npc.Facing *= -1; return "run"; } return null; } }
class RunState : IState<Object> { private readonly NPC npc;
public RunState(NPC npc) { this.npc = npc; }
public void Enter() {}
public string Update(float modelTime, SneakWorld world, Object _) { float moveSpeed = 120; float desiredX = npc.Position.X + moveSpeed * npc.Facing * modelTime; float testPoint = desiredX + npc.Box.HalfSize.X * npc.Facing; AABB npcBox = new AABB( new Vector2(testPoint, npc.Position.Y + 1), new Vector2(1, npc.Box.HalfSize.Y)); 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 readonly Sprite sprite; private readonly Vector2 spriteCenter; private readonly Vector2 eyeOffset = new Vector2(4, -9);
private readonly FSM<Object> fsm; private readonly Vector2 halfSize = new Vector2(11, 24);
public NPC(Vector2 position, int facing) { sprite = Sprites.Executioner; spriteCenter = new Vector2( sprite.Width / 2, sprite.Height - halfSize.Y - sprite.GroundPadding);
Position = position; Box = new AABB(Position, halfSize); Facing = facing;
fsm = new FSM<Object>("run", new Dictionary<string, IState<Object>> { { "idle", new IdleState(this) }, { "run", new RunState(this) } }); }
public int Facing; public Vector2 Position; public AABB Box { get; private set; }
public Vector2 EyePosition { get { return Vector2.Add(Position, 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, SneakWorld world) { fsm.Update(modelTime, world, null); Box = new AABB(Position, halfSize); Debug.AddRect(Box, Color.White); }
public void Draw(SpriteBatch spriteBatch) { Rectangle textureSource = sprite.GetTextureSource(fsm.StateName, Clock.ModelTime.TotalSeconds); SpriteEffects effect = Facing == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; Color color = Color.White; spriteBatch.Draw(Textures.Executioner.Get, Vector2.Round(Position), textureSource, color, 0f, spriteCenter, Vector2.One, effect, 0f); } } }
|