XNA 4.0 Behavior-driven Development, Chapter 9

5 views
Skip to first unread message

David Wallace

unread,
Dec 27, 2011, 8:41:25 AM12/27/11
to bost...@googlegroups.com
Chapter 9: Welcome to the Director's chair

These actions operate on actors, and therefore rely on the subject in the arguments.

    public class AimAct : ActBase
    {
        float angle;
        bool isAngle;

        public override void Act(BehaviorArgs args)
        {
            if (isAngle)
                args.Subject.Transform.Angle = angle;
            else
            {
                if (args.Other == null) return;
                var aim = args.Other.Position2D - args.Subject.Position2D;
                args.Subject.Transform.Angle = aim.Angle();
            }
        }

        public AimAct(string data)
        {
            if (!string.IsNullOrWhiteSpace(data))
            {
                data.Parse(out angle);
                isAngle = true;
            }
        }

        public static ActBase Build(ContentService service, string source)
        {
            return new AimAct(source);
        }
    }

This one simply points the object in a specific direction if passed an angle, otherwise it tries to point at the "other" object.

    public class AnimAct : ActBase
    {
        int anim;

        public override void Act(BehaviorArgs args)
        {
            if (args.Subject != null)
                args.Subject.Animations.Move(anim);
            else
            {
                var control = args.Control as AnimButtonControl;
                if (control == null) return;
                control.Animations.Move(anim);
            }

        }

        public AnimAct(int data)
        {
            anim = data;
        }

        public static ActBase Build(ContentService service, string source)
        {
            if (string.IsNullOrWhiteSpace(source)) throw new ArgumentNullException
                ("AnimAct requires a parameter.");
            int result;
            if (!source.Parse(out result)) throw new ArgumentException
                ("AnimAct requires an integer.");
            return new AnimAct(result);
        }
    }

AnimAct changes the animation of an actor or control.  GameControl objects can leave the subject null and reference themselves in the argument's Control property.

    public class MeanderAct : ActBase
    {
        Random rnd;
        float spread;
        int octaves;

        public override void Act(BehaviorArgs args)
        {
            var shift = (float)(rnd.Gauss(octaves) - 0.5)*spread;
            var target = args.Subject.Transform.Direction + shift;
            while (shift < 0) shift += 360;
            while (shift > 360) shift -= 360;
            args.Subject.Transform.Direction = shift;
        }

        public MeanderAct(ContentService service, string[] data)
        {
            rnd = service.Serve<RandomService>().New;
            data[0].Parse(out spread);
            if (data.Count() < 2)
                data[1].Parse(out octaves);
            else
                octaves = 1;
        }

        public MeanderAct(ContentService service)
        {
            rnd = service.Serve<RandomService>().New;
            spread = 360;
            octaves = 1;
        }

        public static ActBase Build(ContentService service, string source)
        {
            if (string.IsNullOrWhiteSpace(source))
                return new MeanderAct(service);
            var sources = source.Split(',');
            return new MeanderAct(service, sources);
        }
    }

MeanderAct points the subject in a random direction relative to its current direction.  The optional parameters control the degree of randomness.

    public class MoveAct : ActBase
    {
        Vector2 pos;
        float angle;

        public override void Act(BehaviorArgs args)
        {
            args.Subject.Transform.MoveTo(pos);
            if (angle >= 0) args.Subject.Transform.Angle = angle;
        }

        public MoveAct(string[] data)
        {
            float vx, vy;
            data[0].Parse(out vx);
            data[1].Parse(out vy);
            pos = new Vector2(vx, vy);
            angle = -1;
            if (data.Count() < 3) return;
            data[2].Parse(out angle);
        }

        public static ActBase Build(ContentService service, string source)
        {
            var sources = source.Split(',');
            if (sources.Count() < 2) throw new Exception(
                  "MoveAct requires at least 2 parameters.");
            return new MoveAct(sources);
        }
    }

MoveAct positions an object and optionally sets its direction.  This is often used to initialize objects on the map.

    public class PushAct : ActBase
    {
        float angle, strength;
        bool isAngle;

        public override void Act(BehaviorArgs args)
        {
            var bipush = strength;
            if (!isAngle)
            {
                if (args.Other == null) return;
                angle = (args.Other.Position2D - args.Subject.Position2D).Angle();
                if (args.Other is Actor)
                {
                    bipush *= 0.5f;
                    args.Other.Transform.Push(angle, bipush);
                }
            }
            args.Subject.Transform.Push(angle, bipush);
        }

        public PushAct(string[] data)
        {
            data[0].Parse(out strength);
            if (data.Length > 1)
            {
                data[1].Parse(out angle);
                isAngle = true;
            }
        }

        public static ActBase Build(ContentService service, string source)
        {
            var sources = source.Split(',');
            if (sources.Count() == 0) throw new Exception(
                  "PushAct requires at least 1 parameter.");
            return new PushAct(sources);
        }
    }

PushAct is a gentler way of redirecting an object by applying a force as opposed to simply rotating it.  It can work in a direction or operate, perhaps mutually, on args.Other.

Reply all
Reply to author
Forward
0 new messages