Hi All
i have add new feature for this class.
you could specify a path for your enemy , so that the enemy will move
in the path while it scan the area.
suppose you have a gate in your game and want to protect it with
an enemy, so you could specify a path near to that gate and while the
enemy walk in path he scan the area if he found the player then he
will move froward to the player and start to attack the player.
this idea could be implemented by my class.
here is the code of TMove class
Code: Select all
enum MStatue
{
scan,
found
};
class TMove
{
bool flag;
vector3df Curforward;
f32 RotSpeed;
ISceneNode* ScnNode;
ISceneManager* SceneMgr;
ITriangleSelector* Selector;
array<triangle3df> Triangles;
array<vector3df> Path;
s32 indx;
f32 fctr;
f32 MovSpeed;
MStatue statue;
public:
TMove(ISceneNode* node,ISceneManager* ScnMgr)
{
ScnNode = node;
SceneMgr = ScnMgr;
RotSpeed = 0.1;
flag = TRUE;
Selector = NULL;
indx = 0;
MovSpeed = 0.0001;
fctr = 0.0;
statue = scan;
}
~TMove() {}
void Disable() { flag = FALSE; }
void Enable() { flag = TRUE; }
void setRotationSpeed(f32 RotSpd) { RotSpeed = RotSpd; }
void setMoveSpeed(f32 MovSpd) { MovSpeed = MovSpd; }
void setTriangleSelector(ITriangleSelector* Sel) { Selector = Sel; }
void addPathPoint(vector3df& point) { Path.push_back( point ); }
bool ScanArea(ISceneNode* trgt,f32 redus = 100000.f,f32 startAngl=0,f32 endAngl=360)
{
if (flag)
{
if (statue == scan)
{
vector3df p = Path[indx+1].getInterpolated(Path[indx],fctr);
fctr += MovSpeed;
if (fctr >= 1.0) {indx++; fctr = 0.0;}
if (indx >= Path.size()-1) indx = 0;
ScnNode->setPosition(p);
}
vector3df CurRot;
CurRot = ScnNode->getRotation();
if (CurRot.Y > 360) CurRot.Y -= 360;
if (CurRot.Y >= startAngl) RotSpeed *= -1;
if (CurRot.Y <= endAngl) RotSpeed *= -1;
CurRot.Y += RotSpeed;
ScnNode->setRotation(CurRot);
Curforward.set(1,0,0);
ScnNode->getAbsoluteTransformation().rotateVect(Curforward);
line3d<f32> lin;
lin.start = ScnNode->getPosition();
lin.end = lin.start + Curforward * redus;
if (trgt->getTransformedBoundingBox().intersectsWithLine(lin))
{
if (Selector)
{
s32 count;
vector3df intersection;
s32 totalcnt = Selector->getTriangleCount();
Triangles.set_used(totalcnt);
Selector->getTriangles(Triangles.pointer(),totalcnt,count,lin);
for(int i =0; i < count; i++)
{
if (Triangles[i].getIntersectionWithLimitedLine(lin,intersection))
{
f64 L1 = ScnNode->getPosition().getDistanceFrom(trgt->getPosition());
f64 L2 = ScnNode->getPosition().getDistanceFrom(intersection);
if (L1 < L2) goto pass;
statue = scan;
return FALSE;
}
}
}
pass:
RotSpeed /= 2;
if (RotSpeed < 0.001)
{
ScnNode->setRotation(getTargetAngle(trgt));
statue = found;
}
return TRUE;
}
}
}
void MoveForward(f32 speed)
{
vector3df newPos= ScnNode->getPosition() + (Curforward * speed);
ScnNode->setPosition(newPos);
}
f64 GetDistance(ISceneNode* trgt)
{
vector3df pos = ScnNode->getPosition();
return pos.getDistanceFrom(trgt->getPosition());
}
vector3df getTargetAngle(ISceneNode* trgt)
{
vector3df v = ScnNode->getPosition();
vector3df r = trgt->getPosition();
vector3df angle;
float x,y,z;
x = r.X - v.X;
y = r.Y - v.Y;
z = r.Z - v.Z;
angle.Y = atan2 (x, z);
angle.Y *= (180 / PI);
angle.Y-=90;
if(angle.Y < 0) angle.Y += 360;
if(angle.Y >= 360) angle.Y -= 360;
float z1 = sqrt(x*x + z*z);
angle.X = atan2 (z1, y);
angle.X *= (180 / PI);
angle.X -= 90;
if(angle.X < 0) angle.X += 360;
if(angle.X >= 360) angle.X -= 360;
return angle;
}
};
and here is how you could use it
Code: Select all
//creating new instance of our class
// and attach it to EnemyNode
TMove* MyNode = new TMove(EnemyNode,irrSceneMgr);
//here our enemy will no seeing through the room walls
MyNode->setTriangleSelector(room->getTriangleSelector());
//here we set our path that must consistes of more than
// 2 points,so enemy will Interpolate between the points of path
MyNode->addPathPoint(vector3df(100,0,30)); //point 0
MyNode->addPathPoint(vector3df(100,0,-130)); //point 1
MyNode->addPathPoint(vector3df(0,0,-130)); //point 2
// here we specify the rotation speed and movment speed
MyNode->setRotationSpeed(0.3);
MyNode->setMoveSpeed(0.0001);
//and here is the main loop of our game
While irrDevice->run()
{
irrVideo->beginScene(true, true, SColor(0,200,200,200))
//scan our area
if (MyNode->ScanArea(node2,500))
{
f32 Mx;
// if enemy far from player start to move forarard to player
if (MyNode->GetDistance(node2) < 500) Mx = 0.1;
// if enamy is near of player stop moveing and start to attack
if (MyNode->GetDistance(node2) < 10) Mx = 0;
MyNode->MoveForward(Mx);
}
....
.....
}
hope that this class will be useful for someone how want to creating a game
feel free to improve and optimize the class,and let me know if you did it