天行健 君子当自强而不息

Working with Maps and Levels(9)

Blocking the Path with Barriers

You know—detecting when your character is walking around the map bumping into walls or standing
on solid ground. What about objects such as doors blocking your character’s way?
Because a door is not part of the terrain, I didn’t include a door when I constructed
the collision detection code. Now is the time to remedy that situation.

Anything that bars clear passage of a character’s movement is called a barrier.
Barriers can exist in two states—open (disabled) or closed (enabled). Characters
are allowed to pass through a barrier when it is open, but they cannot pass through
when the barrier is closed.

You can treat barriers much as you do triggers. You can define a barrier similar to
the way you define a trigger on a map. You can define barriers as spheres, boxes,
cylinders, and triangles. Barriers can also have an enabled state, with true meaning
that the barrier is blocking the character’s passage and false meaning that the way
through the barrier is clear.

The big difference between barriers and triggers is that barriers can have meshes
and animation assigned to them. This relieves you of the burden of drawing the
barrier and gives the job to the barrier engine. All you have to do is assign the
meshes and animations.

You start off using barriers with the barrier class declaration,
which looks very similar to the trigger class declaration. Notice that I also
define an enum list and structure (sBarrier) used to contain each barrier’s data:

enum BarrierType
{
    BARRIER_SPHERE = 0, BARRIER_BOX, BARRIER_CYLINDER, BARRIER_TRIANGLE
};

/********************************************************************************************/

typedef 
struct sBarrier
{
    
long    type;  // BARRIER_SPHERE, BARRIER_BOX, etc.
    long    id;
    
bool    enabled;

    
float   x_pos, y_pos, z_pos;
    
float   x_rot, y_rot, z_rot;

    
float   x1, y1, z1;
    
float   x2, y2, z2;
    
float   x3, z3;

    
float   radius;

    cObject 
object;

    sBarrier*   prev;
    sBarrier*   next;

    
//////////////////////////////////////////////////////////////////////

    sBarrier()  
    { 
        prev = next = NULL; 
    }

    ~sBarrier() 
    { 
        delete next; next = NULL;  
    }
} *sBarrierPtr;

Here’s where the similarities between the triggers and barrier end. A barrier needs
a graphical representation (a 3-D mesh), so the code adds a Graphics
Core cObject object that is used to contain the barrier’s mesh and animation data.

Getting back to the similarities of the trigger and barrier classes, notice the pointers
that maintain the linked list as well as the sBarrier structure constructor and
destructor.

The similarities between triggers and barrier continue with the declaration of the
barrier class:

typedef class cBarrier
{
private:
    
long        m_num_barriers;
    sBarrier*   m_root_barrier;

    
//////////////////////////////////////////////////////////////////////

public:
    cBarrier()
    {
        m_num_barriers = 0;
        m_root_barrier = NULL;
    }
    
    ~cBarrier()
    {
        free();
    }

    
void free()
    {
        delete m_root_barrier;
        m_root_barrier = NULL;

        m_num_barriers = 0;
    }

    
long get_num_barriers()
    {
        
return m_num_barriers;
    }

    sBarrier* get_root_barrier()
    {
        
return m_root_barrier;
    }
 

Shift your focus for a moment to the arguments that the add_barrier function is taking.
Aside from the position in which to position the barrier (using the x_pos, y_pos,
and z_pos arguments), the add_barrier function takes the rotational values in which to
draw the barrier’s mesh (using the x_rot, y_rot, and z_rot arguments that represent the
X-, Y-, and Z-rotational values, in radians, respectively).

Notice that the addition of rotational values throughout the barrier class, as well as
the addition of an extra trio of coordinates that define the mesh’s position in the
world. As you come upon these additional values, I’ll be sure to point them out.

    sBarrier* add_barrier(long type, long id, bool enabled,
                          
float x_pos, float y_pos, float z_pos,
                          
float x_rot, float y_rot, float z_rot)
    {
        
// allocate a new barrier structure and link in

        sBarrier* bar = 
new sBarrier;

        bar->prev = NULL;
        bar->next = m_root_barrier;

        
if(m_root_barrier)
            m_root_barrier->prev = bar;

        m_root_barrier = bar;

        bar->type    = type;
        bar->id      = id;
        bar->enabled = enabled;
        bar->x_pos   = x_pos;
        bar->y_pos   = y_pos;
        bar->z_pos   = z_pos;
        bar->x_rot   = x_rot;
        bar->y_rot   = y_rot;
        bar->z_rot   = z_rot;

        m_num_barriers++;

        
return bar;
    }  

posted on 2007-12-10 13:50 lovedday 阅读(182) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论