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
Thanks, Viktor
#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
oh yah, and the methods which I convert screen coordinates to world coordinates:
Appreciate all the advices given. Hope these will help those who face similar problems as me.
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.
Torque Owner Dan Maruschak