天行健 君子当自强而不息

Putting Together a Full Game(13)

 

Dealing with Maps

The sample game is divided into five maps (scenes). Each scene uses six bitmaps,
each of which is loaded as textures that are drawn to the display for each frame.
The game also uses an underlying simplified mesh for each scene. These simplified
meshes aid in properly drawing the 3D characters that inhabit each scene.

A total of four functions are contained within the application class that is used
to work with scenes. These functions are load_level, free_level, get_height_below, and
check_intersect. You use the get_height_below and check_intersect functions, which are
presented in Chapter 12, to check for mesh-to-mesh intersections. In the case of
the game, those mesh intersections are used to determine when characters intersect
with the simplified scene mesh.

float cApp::get_height_below(float x_pos, float y_pos, float z_pos)
{
    
// only one mesh in mesh level
    return closest_height_below(m_scene_mesh.get_root_mesh()->m_d3d_mesh, x_pos, y_pos, z_pos);
}

bool  cApp::check_intersect(float x_start, float y_start, float z_start,
                            
float x_end, float y_end, float z_end,
                            
float* dist)
{
    
// only one mesh in mesh level
    return is_ray_intersect_mesh(m_scene_mesh.get_root_mesh()->m_d3d_mesh,
                                 x_start, y_start, z_start,
                                 x_end, y_end, z_end,
                                 dist);
}

The load_level function loads the six scene textures and the simplified mesh and
executes the script associated with loading the scene. An external file, which you
see in just a moment, stores the position of the camera within each scene. Here is
the code for load_level:

bool cApp::load_level(int scene_index)
{
    m_scene_index = scene_index;

    free_level();

    
// load the backdrop textures

    
char filename[MAX_PATH];

    
for(int i = 0; i < 6; i++)
    {
        sprintf(filename, "..\\Data\\Scene%u%u.bmp", scene_index, i+1);
                
        
if(! load_texture_from_file(&m_scene_backdrops[i], filename, 0, D3DFMT_UNKNOWN))
            
return false;
    }

    
// load the scene mesh and configure object

    sprintf(filename, "..\\Data\\Scene%u.x", scene_index);

    
if(! m_scene_mesh.load(filename, "..\\Data"))
        
return FALSE;

    m_scene_object.create(&m_scene_mesh);

    
// load the camera data

    sprintf(filename, "..\\Data\\Cam%u.txt", scene_index);

    FILE* fp = fopen(filename, "rb");

    
if(fp == NULL)
        
return false;

    
float x_pos = get_next_float_2(fp);
    
float y_pos = get_next_float_2(fp);
    
float z_pos = get_next_float_2(fp);
    
float x_at  = get_next_float_2(fp);
    
float y_at  = get_next_float_2(fp);
    
float z_at  = get_next_float_2(fp);

    fclose(fp);

    m_camera.point(x_pos, y_pos, z_pos, x_at, y_at, z_at);
    set_display_camera(&m_camera);

    m_is_monster_last_frame = 
false;

    
// load script and execute it
    sprintf(filename, "..\\Data\\Scene%lu.mls", scene_index);
    m_game_script.execute(filename);

    
return true;
}

After you load the scene’s mesh and create the scene’s object, you are ready to
determine the placement of the camera used to render the 3-D graphics. You place
the camera in each scene by first creating a text file for each scene. Name these
files cam1.txt, cam2.txt, cam3.txt, cam4.txt, and cam5.txt—each named according
to its respective scene number (scenes being numbered 1 through 5).

Place a scene’s camera by opening the appropriate text file and reading in six numbers,
each of which is used to determine the camera’s orientation in the scene. The
first three numbers represent the position of the camera in the world, and the last
three numbers are the coordinates to which the camera is pointed.

After you load the six numbers and orient the camera, call the set_display_camera
function to inform Direct3D of the new view transformation being used by the camera.

After you position the camera in the file, the class clears a flag that determines
whether monsters are currently in the scene (for combat processing) and then
executes the script associated with the scene.

There's not much to do in load_level as you can see. The free_level function is rather
trouble-free as well. It frees the scene’s textures and simplified mesh, removes every
character from the character controller (except for the player, that is), and clears
all spells currently being processed. Here is the complete free_level function code:

void cApp::free_level()
{
    
for(int i = 0; i < 6; i++)
        release_com(m_scene_backdrops[i]);

    m_scene_mesh.free();
    m_barrier.free();
    m_trigger.free();
    m_game_spells.free();

    
// free all non-pc characters

    sCharacter* next_char;

    
for(sCharacter* char_ptr = m_game_chars.get_root_char(); char_ptr != NULL; char_ptr = next_char)
    {
        next_char = char_ptr->next;

        
if(char_ptr->type != CHAR_PC)
            m_game_chars.remove_char(char_ptr);
    }
}


posted on 2007-12-29 23:22 lovedday 阅读(248) 评论(0)  编辑 收藏 引用


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


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论