Game Development Community

Simple Pathfinding

by Viktor Rumanuk · in Torque X 2D · 12/23/2007 (8:15 am) · 25 replies

All I need is a very simple way to get multiple enemies to follow the same path, I can make the paths pre-determined if I can find a way to place nodes. This would be used in a tower-defense based game. I was thinking of someway to make the enemies follow a certain color and store already traversed areas in an array, although I don't really know how to do this.

Thanks, Viktor
Page«First 1 2 Next»
#21
01/20/2008 (9:13 pm)
@Alexander - I would think that the threshold you want would be the distance you would travel in one tick, or (SceneObject.Physics.Velocity.Length() * dt) or (SceneObject.Physics.Velocity.Length() * 0.032, since by default there are 32 milliseconds per tick). However, 0.032 is less than 1/15, so if dividing by 15 isn't working, I'm not sure if a smaller number would work.
#22
01/20/2008 (9:31 pm)
Ok got this working:
public void ProcessTick(Move move, float elapsed)
        {
            threshold = (Veloc.X + Veloc.Y) / 2;
            if (Vector2.Distance(_sceneObject.Position,_target.Position) < threshold)
            {
                _sceneObject.Physics.Velocity = new Vector2(0, 0);
            }
            else
            {
                if (Veloc.X > Veloc.Y)
                {
                    _sceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(_sceneObject.Position, _target.Position, Veloc.X); 
                }
                else
                {
                    _sceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(_sceneObject.Position, _target.Position, Veloc.Y); 
                }
            }
            threshold = 0;
        }
Veloc is a public Vector2. I divided by 2 to make the change more visible. I made my target a white square in TXB to make the change even more visible. Hope this is of some help to you Alex.
#23
01/20/2008 (10:07 pm)
Ok thanks. Maybe I can post whole source code for those who are interested once it is done
#24
01/20/2008 (10:34 pm)
Ok..... I have tried Viktor's solution and apparently it doesn't stop well. Occasionally it will still not stop. So I tried Dan's suggestion to do a SceneObject.Physics.Velocity.Length() * 0.032 and it has not given me any problem yet. Here's the complete source code for this module, my first contribution to the Torque X community for helping me so much:

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using GarageGames.Torque.Core;
using GarageGames.Torque.Util;
using GarageGames.Torque.Sim;
using GarageGames.Torque.T2D;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.MathUtil;
using Microsoft.Xna.Framework.Input;
using GarageGames.Torque.Platform;


namespace StarterGame
{
    [TorqueXmlSchemaType]
    public class MoveToComponent : TorqueComponent, ITickObject
    {
        //======================================================
        #region Static methods, fields, constructors
        #endregion

        //======================================================
        #region Constructors
        #endregion

        //======================================================
        #region Public properties, operators, constants, and enums

        [TorqueXmlSchemaType(DefaultValue = "15")]
        public float Velocity
        {

            get
            {
                return velocity;
            }
            set
            {
                velocity = value;
            }
        }

        public float ThresHold
        {
            get
            {
                return SceneObject.Physics.Velocity.Length() * 0.032f;
            }
        }

        public T2DSceneObject SceneObject
        {
            get { return Owner as T2DSceneObject; }
        }

        #endregion

        //======================================================
        #region Public methods

        public virtual void ProcessTick(Move move, float dt)
        {
            // todo: perform processing for component here

            if (Vector2.Distance(SceneObject.Position, targetPos) < ThresHold)
            {

                SceneObject.Physics.Velocity = Vector2.Zero;
                
            }
 
        }

        public virtual void InterpolateTick(float k)
        {
            // todo: interpolate between ticks as needed here
        }

        public override void CopyTo(TorqueComponent obj)
        {
            base.CopyTo(obj);
        }

        public void onMouseClick(float val)
        {
            if (val == 0)
            {
                MouseState mouse = Mouse.GetState();
                targetPos = Utils.GetWorldCoordinates(new Vector2(mouse.X, mouse.Y));
                SceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(SceneObject.Position, targetPos, velocity);
               
            }
        }
        #endregion

        //======================================================
        #region Private, protected, internal methods

        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner) || !(owner is T2DSceneObject))
                return false;
            InputMap inputMap = PlayerManager.Instance.GetPlayer(0).InputMap;

            // todo: perform initialization for the component

            // todo: look up interfaces exposed by other components
            // E.g., 
            // _theirInterface = Owner.Components.GetInterface<ValueInterface<float>>("float", "their interface name");            
            int mouseid = InputManager.Instance.FindDevice("mouse");
            if (mouseid >= 0)
            {
                //clickTimes = 0;
                //tileobjs = new T2DTileObject[2];
                inputMap.BindAction(mouseid, (int)XMouseDevice.MouseObjects.LeftButton, onMouseClick);
                
            }
            ProcessList.Instance.AddTickCallback(Owner, this);
            return true;
        }

        protected override void _OnUnregister()
        {
            // todo: perform de-initialization for the component

            base._OnUnregister();
        }

        protected override void _RegisterInterfaces(TorqueObject owner)
        {
            base._RegisterInterfaces(owner);

            // todo: register interfaces to be accessed by other components
            // E.g.,
            // Owner.RegisterCachedInterface("float", "interface name", this, _ourInterface);
        }


        #endregion

        //======================================================
        #region Private, protected, internal fields
        private Vector2 targetPos;
        private float velocity;
        #endregion
    }
}

oh yah, and the methods which I convert screen coordinates to world coordinates:

public static Vector2 GetWorldCoordinates(Vector2 screenPosition)
        {
            T2DSceneCamera camera = T2DSceneGraph.Instance.Camera as T2DSceneCamera;
            Vector2 vect1 = new Vector2(GUICanvas.Instance.Size.X, GUICanvas.Instance.Size.Y);
            Vector2 vect2 = screenPosition / vect1;
            Vector2 vect3 = Vector2.Multiply(vect2, (camera.SceneMax - camera.SceneMin));
            Vector2 vect4 = vect3 + camera.SceneMin;
            return vect4;
        }

Appreciate all the advices given. Hope these will help those who face similar problems as me.
#25
01/21/2008 (6:20 am)
Glad you got it working Alex. I should have tested my solution more thoroughly.
Page«First 1 2 Next»