About Store Forum Documentation Contact

Post Reply 
group move test script
Author Message
sivan Offline

Post: #1
group move test script

I just created a performance test for myself based on the tutorials, please let me know if someone is interested, and I will upload it with resources.

it includes:
- a group of 100 units in 10x10 formation
- one leader, the others are moving relatively to him, so obstacles are avoided, but not very smoothly
- a custom character mesh and animations converted from MTW2
- a custom map imported from L3DT (using heightmap and texture alpha maps), and some own textures
- the group can be moved together by mouse clicks on target position using the navmesh pathfinder
- free camera movements by arrows, rotate by mouse look

it's really a simple few line thingie, so do not expect intelligent behaviour, just a test. the group does not rotate due to its direction, and collisions are not handled.

[Image: esenthelscreenshot04.png]

probably there is a better approach for this task, but I'm really new in Esenthel engine. any idea welcome smile

#include "stdafx.h"

//#include <stdlib.h>
//#include <time.h>

   A group of custom mesh characters with own skeleton and own animation,
   and with custom animation and movement speeds, in a custom world.

Image skybox; // sky box texture

STRUCT(Player , Game::Chr) // extend character class by defining a player class based on the character
    virtual void create(Game::ObjParams &obj); // override default creation method to setup custom default animations after character creation
    virtual Bool update(); // here we'll update the player (please note that this is a virtual method)

    // formation data
    int row;
    int column;
    int arraynum;
#include "../../../../../data/enum/_enums.h"
void Player::create(Game::ObjParams &obj)
   super::create(obj); // call default creation
   sac.stand    = &cskel.getSkelAnim("obj/chr/sergeant/idle.anim");
   sac.run        = &cskel.getSkelAnim("obj/chr/sergeant/walk.anim");
   sac.walk        = &cskel.getSkelAnim("obj/chr/sergeant/walk.anim");

   speed        = 3;
   anim.speed    = 1;
Bool Player::update()
   // here we update character input according to mouse and keyboard
   // before we set the input, we need to check if the character isn't controlled by an automatic action
      // if it's controlled by an action we leave the input with no changes,
      // however we can optionally break that action, by pressing for example movement keys
      if(Kb.b(KB_W) || Kb.b(KB_S) || Kb.b(KB_A) || Kb.b(KB_D) || Kb.b(KB_Q) || Kb.b(KB_E))actionBreak();
   if(!action) // if the character isn't controlled by an automatic action, we can set the input
      // turn & move

      // dodge, crouch, walk, jump
      input.dodge = Kb.bd(KB_D)-Kb.bd(KB_A);
      input.crouch= Kb.b (KB_LSHIFT);
      input.walk  = Kb.b (KB_LCTRL );
      input.jump  =(Kb.bp(KB_SPACE) ? 3.5f : 0);

   return super::update(); // call Game::Chr::update on which Player is based on
Game::ObjMemx<Game::Static> Statics;    // container for static    objects
//Game::ObjMemx<Game::Chr  > Chrs;        // container for item      objects
Game::ObjMemx<        Player> Players;    // container for character objects
void InitPre()
   App.name("Group of Game Characters on Terrain");
   App.flag=APP_FULL_TOGGLE;            // APP_MS_EXCLUSIVE| to hide mouse

   D.full(true).hdr(false).viewRange(500).viewFov(DegToRad(60),FOV_Y);   // fullscreen, hdr on, range 500, camera arc 60 degree

   Cam.dist =10;
   Cam.yaw  =-PI_4;    // -45° DIRECTION

Bool Init()
   Physics.create(CSS_NONE, true, "../Installation/PhysX");
   // 1) skybox
   skybox.Import("../data/Env/Sky/scube03b_clearnoon+6.tga", IMAGE_B8G8R8A8, IMAGE_CUBE);  
   Sky.skybox     (skybox); // set sky from skybox

   // 2) atmospheric sky with fog
   Sky.atmosphericColor(Vec4(0.3f), Vec4(0.1f));    // horizon and sky colour

              .setObjType(Statics, OBJ_STATIC)        // set 'Statics' memory container for 'OBJ_STATIC' objects
              //.setObjType(Chrs  , OBJ_CHR  )        
              .setObjType(Players, OBJ_PLAYER);        

   // create the world by giving path to builded world
   // set water
   Water.images(Images("Env/Water/0.gfx"), Images("Env/Water/0.n.gfx"), Images("Env/Water/reflection.gfx")); // set water from textures
   Water.draw      =true;    // enable drawing
   Water.wave_scale=0.8f;    // adjust wave scales
   Water.validate();        // must be used after manual settings

   // original : from character.cpp
   Game::ObjParams obj; // set object parameters
   obj.mesh(true, Meshes.ptrRequire("obj/chr/sergeant/0.mesh"));    

   // modified : group of units
   int i;
        obj.matrix.setScalePos(1.8f, Vec(i%10*2-50, 10, -Int(i/10)*2-75));        // adjust height to terrain level
        player[i].create(obj); // create player from object parameters        
        // create skeleton here, not inside void create
        player[i].cskel.create(Skeletons("../data/obj/chr/sergeant/0.skel")); // create controlled skeleton from skel file, with default height
        // assign animation inside void Player::create
        // set speed and anim speed in void Player::create

        // set player properties used for group movement - first row created from left to right
        player[i].arraynum = i;
        player[i].column = i%10;
        player[i].row = Int(i/10);
   return true;
void Shut()
    // empty
Bool Update()
   if(Kb.bp(KB_ESC))return false;

   // update water waves movement - requires Water.validate()
   Water.update(Vec2(0.01f, 0.01f));

   // move leader of player group
   if(Ms.bp(0)) // on LMB pressed
      Vec     pos, dir; ScreenToPosDir(Ms.pos(), pos, dir); // convert screen mouse position to world position and direction
      PhysHit phys_hit;
      if(Physics.ray(pos, dir*D.viewRange(), &phys_hit)) // if ray-test hit something
          player[0].actionMoveTo(Vec(phys_hit.plane.pos.x, phys_hit.plane.pos.y, phys_hit.plane.pos.z)); // order character to move to that location      
   // player group movement
   Vec leaderpos = player[0].pos();
   int i;
   // entity update
   // free camera
   Cam.yaw  -=Ms.d().x;                         // modify yaw      according to mouse delta x
   Cam.pitch+=Ms.d().y;                         // modify pitch    according to mouse delta y
   Cam.roll +=(Kb.b(KB_Z)-Kb.b(KB_X))*Time.d(); // modify roll     according to Z and X keyboard buttons
   Cam.dist -=Ms.wheel()*0.4f;                  // modify distance according to mouse wheel
   Clamp(Cam.dist, 0.1f, 50);                   // clamp  distance to minimum and maximum values

   if(Kb.b(KB_LEFT ))Cam.at-=Cam.matrix.x*Time.d()*5; // move camera left  on left  arrow key
   if(Kb.b(KB_RIGHT))Cam.at+=Cam.matrix.x*Time.d()*5; // move camera right on right arrow key
   if(Kb.b(KB_UP   ))Cam.at+=Cam.matrix.z*Time.d()*5; // move camera fwd   on up    arrow key
   if(Kb.b(KB_DOWN ))Cam.at-=Cam.matrix.z*Time.d()*5; // move camera bckw  on down  arrow key
   if(Kb.b(KB_HOME ))Cam.at+=Cam.matrix.y*Time.d()*5; // move camera up    on Home key
   if(Kb.b(KB_END  ))Cam.at-=Cam.matrix.y*Time.d()*5; // move camera down  on End key

   Cam.setSpherical    (Cam.at, Cam.yaw, Cam.pitch, Cam.roll, Cam.dist); // set spherical camera with 'look at' position, angles and distance
   Cam.updateVelocities(                                              ); // after camera settings are up, we need to update camera velocities in order to achieve correct motion blur when enabled
   Cam.set             (                                              ); // set as active camera
   return true;
void Render()
    // world.cpp
    Game::World.draw(); // draw world (this is done outside of 'switch(Renderer())' because world automatically detects active rendering mode)
    int i;
      case RM_PREPARE:
      case RM_SHADOW:
void Draw()

   D.text(0, 0.9f, S+"Fps "+Time.fps());

Edit: I updated the screenshot, and the code too (shadows, water, sky settings)
(This post was last modified: 01-15-2013 11:14 AM by sivan.)
07-12-2012 11:11 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Post Reply