• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            Controlling Players and Characters(41)

             

            download source and solution

             

            Demonstrating Characters with the Chars Demo

            All your hard work is about to pay off with a demonstration of the character and
            spell controllers seen in this chapter.

            Upon executing the program, you see the scene shown in following snap.

            In the Chars demo, you take control of the PC, using the arrow keys to turn and
            move him. The controls are straightforward—use the space bar to interact with the
            closest character (either to speak to an NPC or to attack a monster). Pressing the
            number keys 1 through 3 casts a few spells at the closest monster.

            Each character in the game demonstrates a single artificial intelligence. Speaking
            to another character conveys which artificial intelligence a particular character uses
            (except for monsters, which either stand still or follow the player character). It’s
            best to quickly dispatch the monsters before they take your player character out.

            Everything in the Chars demo has been explained in this chapter. A script class
            determines which characters to place in the map during startup (as detailed in the
            startup script) and what each character does or says when spoken to.

            The demo’s action template, default.mla, contains a number of script actions that
            directly modify a character’s type, artificial intelligence, position, and direction.
            Adding characters to the world is as easy as using an add character script action,
            and from there, you modify the character’s attributes accordingly.

            As for the main application, the system core’s cApp class is being used to
            control the flow of the demo; each frame update is regulated to 33-millisecond
            lapses, giving a 30-frames-per-second update rate. At each and every frame, keyboard
            input is read in and stored, waiting to be used during the PC update function.
            A fixed camera renders out the action, with each character fully animated
            inside a single level (both characters and the level represented by meshes).

            The code to the demo is well commented, so enjoy exploring it, and find out how
            quickly you can create characters running around in your game project. Be sure to
            check out the scripts and script action template using the Mad Lib Script editor, as
            well as the items and character definitions using the MIL and MCL Editors.

             

            Main Routine Source:

            WinMain.h:

            #ifndef WIMMAIN_H
            #define WINMAIN_H

            #include "core_framework.h"
            #include "core_input.h"
            #include "text_window.h"
            #include "char_ics.h"
            #include "char.h"
            #include "script.h"
            #include "spell.h"

            class cApp;

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

            class cGameCharController : public cCharController
            {
            private:
                cApp*   m_app;

            private:    
                
            virtual void pc_update(sCharacter* character, long elapsed,
                                       
            float* x_move, float* y_move, float* z_move);

                
            virtual bool validate_move(sCharacter* character, 
                                           
            float* x_move, float* y_move, float* z_move);

            public:
                
            void set_data(cApp* app)
                {
                    m_app = app;
                }
            };

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

            class cGameScript : public cScript
            {
                friend cApp;

            private:
                BOOL                    m_flags[256];

                cApp*                   m_app;

                cInputDevice*           m_keyboard;    
                cGameCharController*    m_gc_controller;
                
                
            long                    m_num_route_points;
                sRoutePoint*            m_route;

                cTextWindow             m_text_window;

                ID3DXFont*              m_font;

                
            //////////////////////////////////////////////////////////////////////////////////
                
            public:
                cGameScript()
                {
                    m_app           = NULL;
                    m_keyboard      = NULL;        
                    m_gc_controller = NULL;
                    m_route         = NULL;
                    m_font          = NULL;

                    ZeroMemory(m_flags, 
            sizeof(m_flags));
                }

                ~cGameScript()
                {
                    delete[] m_route;
                }

                
            void set_data(cApp* app, cInputDevice* keyboard, cGameCharController* gc_controller, ID3DXFont* font)
                {
                    m_app           = app;
                    m_keyboard      = keyboard;
                    m_gc_controller = gc_controller;
                    m_font          = font;

                    m_text_window.create(m_font);
                }

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

            private:
                
            virtual void release()
                {
                    delete[] m_route;
                    m_route = NULL;

                    m_num_route_points = 0;
                }

                
            virtual sScriptInfo* process(sScriptInfo* info)
                {
                    
            switch(info->action_index)
                    {
                    
            case 0:  return script_end(info);
                    
            case 1:  return script_if_flag_then(info);
                    
            case 2:  return script_else(info);
                    
            case 3:  return script_endif(info);
                    
            case 4:  return script_set_flag(info);
                    
            case 5:  return script_show_msg(info);
                    
            case 6:  return script_add_char(info);
                    
            case 7:  return script_remove_char(info);
                    
            case 8:  return script_show_char_msg(info);
                    
            case 9:  return script_set_char_type(info);
                    
            case 10: return script_set_char_ai(info);
                    
            case 11: return script_set_char_distance(info);
                    
            case 12: return script_set_char_bound(info);
                    
            case 13: return script_set_target_char(info);
                    
            case 14: return script_set_no_target(info);
                    
            case 15: return script_create_route(info);
                    
            case 16: return script_add_point(info);
                    
            case 17: return script_assign_route(info);
                    
            case 18: return script_move_char(info);
                    
            case 19: return script_set_char_script(info);
                    }

                    
            return NULL;    // error executing
                }

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

            private:

                sScriptInfo* script_end(sScriptInfo* info)
                {
                    
            return NULL;    // force end of processing
                }

                sScriptInfo* script_else(sScriptInfo* info)
                {
                    
            return info->next;
                }

                sScriptInfo* script_endif(sScriptInfo* info)
                {
                    
            return info->next;
                }

                sScriptInfo* script_set_flag(sScriptInfo* info)
                {
                    m_flags[info->entries[0].long_value % 256] = info->entries[1].bool_value;

                    
            return info->next;
                }

                sScriptInfo* script_add_char(sScriptInfo* info)
                {
                    m_gc_controller->add_char(info->entries[0].long_value,
                                              info->entries[1].long_value,
                                              info->entries[2].selection,
                                              info->entries[3].selection,
                                              info->entries[4].float_value,
                                              info->entries[5].float_value,
                                              info->entries[6].float_value,
                                              info->entries[7].float_value);

                    
            return info->next;
                }

                sScriptInfo* script_remove_char(sScriptInfo* info)
                {
                    m_gc_controller->remove(info->entries[0].long_value);

                    
            return info->next;
                }

                sScriptInfo* script_set_char_type(sScriptInfo* info)
                {
                    m_gc_controller->set_char_type(info->entries[0].long_value, info->entries[1].selection);

                    
            return info->next;
                }

                sScriptInfo* script_set_char_ai(sScriptInfo* info)
                {
                    m_gc_controller->set_char_ai(info->entries[0].long_value, info->entries[1].selection);

                    
            return info->next;
                }

                sScriptInfo* script_set_char_distance(sScriptInfo* info)
                {
                    m_gc_controller->set_char_distance(info->entries[0].long_value, info->entries[1].float_value);

                    
            return info->next;
                }

                sScriptInfo* script_set_char_bound(sScriptInfo* info)
                {
                    m_gc_controller->set_char_bound(info->entries[0].long_value,
                                                    info->entries[1].float_value,
                                                    info->entries[2].float_value,
                                                    info->entries[3].float_value,
                                                    info->entries[4].float_value,
                                                    info->entries[5].float_value,
                                                    info->entries[6].float_value);

                    
            return info->next;
                }

                sScriptInfo* script_set_target_char(sScriptInfo* info)
                {
                    m_gc_controller->set_target_char(info->entries[0].long_value, info->entries[1].long_value);

                    
            return info->next;
                }

                sScriptInfo* script_set_no_target(sScriptInfo* info)
                {
                    m_gc_controller->set_target_char(info->entries[0].long_value, -1);

                    
            return info->next;
                }

                sScriptInfo* script_create_route(sScriptInfo* info)
                {
                    delete[] m_route;
                    m_route = NULL;

                    m_num_route_points = 0;

                    m_num_route_points = info->entries[0].long_value;
                    m_route = 
            new sRoutePoint[m_num_route_points];

                    
            return info->next;
                }

                sScriptInfo* script_add_point(sScriptInfo* info)
                {
                    
            long route_index = info->entries[0].long_value;

                    m_route[route_index].pos_x = info->entries[1].float_value;
                    m_route[route_index].pos_y = info->entries[2].float_value;
                    m_route[route_index].pos_z = info->entries[3].float_value;

                    
            return info->next;
                }

                sScriptInfo* script_assign_route(sScriptInfo* info)
                {
                    m_gc_controller->set_char_route(info->entries[0].long_value, m_num_route_points, m_route);

                    
            return info->next;
                }

                sScriptInfo* script_move_char(sScriptInfo* info)
                {
                    m_gc_controller->move_char(info->entries[0].long_value,
                                               info->entries[1].float_value,
                                               info->entries[2].float_value,
                                               info->entries[3].float_value);

                    
            return info->next;
                }

                sScriptInfo* script_set_char_script(sScriptInfo* info)
                {
                    m_gc_controller->set_char_script(info->entries[0].long_value, info->entries[1].text);

                    
            return info->next;
                }
                
                
            //////////////////////////////////////////////////////////////////////////////////

            private:
                sScriptInfo* script_if_flag_then(sScriptInfo* info);
                sScriptInfo* script_show_msg(sScriptInfo* info);
                sScriptInfo* script_show_char_msg(sScriptInfo* info);

                
            void render_scene_and_msg();
            };

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

            class cApp : public cFramework
            {
                friend 
            class cGameScript;
                friend 
            class cGameCharController;

            private:
                cCamera             m_camera;

                cInput              m_input;
                cInputDevice        m_keyboard;
                cInputDevice        m_mouse;

                cMesh               m_terrain_mesh;
                cObject             m_terrain_object;

                cGameCharController m_gc_controller;
                cSpellController    m_spell_controller;

                cGameScript         m_game_script;

                sItem               m_mil[1024];

                ID3DXFont*          m_font;

            public:
                
            bool init();
                
            bool frame();

                
            long get_input();

                
            bool check_intersect(float x_start, float y_start, float z_start,
                                     
            float x_end,   float y_end,   float z_end);
            };


            #endif
             

            WinMain.cpp:

            #include "core_common.h"
            #include "core_graphics.h"
            #include "char.h"
            #include "script.h"
            #include "text_window.h"
            #include "tool.h"
            #include "WinMain.h"

            #define PRESS_UP        1
            #define PRESS_RIGHT     2
            #define PRESS_DOWN      4
            #define PRESS_LEFT      8
            #define PRESS_SPACE     16
            #define PRESS_1         32
            #define PRESS_2         64
            #define PRESS_3         128

            #define CLIENT_WIDTH    800
            #define CLIENT_HEIGHT   600

            cApp g_app;

            // Global names of character meshes
            PCSTR g_char_mesh_names[] = {
                "..\\Data\\Warrior.x",  
            // Mesh # 0
                "..\\Data\\Yodan.x"     // Mesh # 1
            };

            sCharAnimInfo g_char_anim_infos[] = {
                { "Idle",  
            true  },
                { "Walk",  
            true  },
                { "Swing", 
            false },
                { "Spell", 
            false },
                { "Swing", 
            false },
                { "Hurt",  
            false },
                { "Die",   
            false },
                { "Idle",  
            true  }
            };

            PCSTR g_spell_mesh_names[] = {
                "..\\Data\\Fireball.x",
                "..\\Data\\Explosion.x",
                "..\\Data\\Groundball.x",
                "..\\Data\\ice.x",
                "..\\Data\\bomb.x",
            };

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {        
                DWORD pos_x = (get_screen_width()  - CLIENT_WIDTH) / 2;
                DWORD pos_y = (get_screen_height() - CLIENT_HEIGHT) / 4;

                build_window(inst, "CharClass", "Characters Demo", 
                             WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
                             pos_x, pos_y, CLIENT_WIDTH, CLIENT_HEIGHT);
                
                g_app.run();

                
            return 0;
            }

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

            void cGameCharController::pc_update(sCharacter* character, long elapsed,
                                                
            float* x_move, float* y_move, float* z_move)
            {
                
            if(character->id != CHAR_PC)
                    
            return;

                
            float speed = elapsed/1000.0f * get_speed(character);

                
            // rotate character

                
            long action = m_app->get_input();    

                
            if(action & PRESS_RIGHT)
                {
                    character->direction += (elapsed/1000.0f * 8);
                    character->action = CHAR_MOVE;
                }

                
            if(action & PRESS_LEFT)
                {
                    character->direction -= (elapsed/1000.0f * 8);
                    character->action = CHAR_MOVE;
                }

                
            // walk forward
                if(action & PRESS_UP)
                {
                    *x_move = sin(character->direction) * speed;
                    *z_move = cos(character->direction) * speed;
                    
                    character->action = CHAR_MOVE;
                }

                sCharacter* char_ptr;
                
            float x_diff, y_diff, z_diff, dist;

                
            // attack a nearby monster or process NPC script
                if(action & PRESS_SPACE)
                {
                    
            for(char_ptr = get_root_char(); char_ptr != NULL; char_ptr = char_ptr->next)
                    {
                        
            // only check other characters
                        if(char_ptr->id == character->id)
                            
            continue;
                        
                        x_diff = fabs(char_ptr->pos_x - character->pos_x);
                        y_diff = fabs(char_ptr->pos_y - character->pos_y);
                        z_diff = fabs(char_ptr->pos_z - character->pos_z);

                        dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

                        
            // only check characters within 1000.0 units distance
                        if(dist > 10000.0f)
                            
            continue;
                        
                        
            if(char_ptr->script_filename[0])
                            m_app->m_game_script.execute(char_ptr->script_filename);
                        
            else
                        {
                            
            // turn toward victim
                            x_diff = char_ptr->pos_x - character->pos_x;
                            z_diff = char_ptr->pos_z - character->pos_z;

                            character->direction = atan2(x_diff, z_diff);

                            character->victim  = char_ptr;
                            char_ptr->attacker = character;

                            m_app->m_gc_controller.set_char_action(character, CHAR_ATTACK, 0);
                        }

                        
            break;
                    }
                }

                
            long spell_index = 0;

                
            // cast spells
                if(action & PRESS_1 || action & PRESS_2 || action & PRESS_3)
                {
                    
            // get spell index to cast
                    if(action & PRESS_1)    spell_index = 0;
                    
            if(action & PRESS_2)    spell_index = 1;
                    
            if(action & PRESS_3)    spell_index = 2;

                    
            float spell_max_dist = m_app->m_spell_controller.get_spell(spell_index)->max_dist;

                    
            // search for closest monster
                    for(char_ptr = get_root_char(); char_ptr != NULL; char_ptr = char_ptr->next)
                    {
                        
            if(char_ptr->type == CHAR_MONSTER)
                        {
                            x_diff = fabs(char_ptr->pos_x - character->pos_x);
                            y_diff = fabs(char_ptr->pos_y - character->pos_y);
                            z_diff = fabs(char_ptr->pos_z - character->pos_z);

                            dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

                            
            if(dist <= (spell_max_dist * spell_max_dist))
                            {
                                character->spell_index = spell_index;
                                character->target_type = CHAR_MONSTER;
                                character->target_x    = char_ptr->pos_x;
                                character->target_y    = char_ptr->pos_y;
                                character->target_z    = char_ptr->pos_z;

                                
            // turn toward victim
                                x_diff = char_ptr->pos_x - character->pos_x;
                                z_diff = char_ptr->pos_z - character->pos_z;
                                character->direction = atan2(x_diff, z_diff);

                                m_app->m_gc_controller.set_char_action(character, CHAR_SPELL, 0);
                                
            break;
                            }
                        }
                    }
                }
            }

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

            bool cGameCharController::validate_move(sCharacter* character, 
                                                    
            float* x_move, float* y_move, float* z_move)
            {
                
            // check against terrain mesh for collision
                
                
            return ! m_app->check_intersect(character->pos_x, character->pos_y + 2.0f, character->pos_z,
                    *x_move + character->pos_x, *y_move + character->pos_y + 2.0f, *z_move + character->pos_z);   
            }

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

            void cGameScript::render_scene_and_msg()
            {
                clear_display(0, 1.0);

                
            if(begin_display_scene())
                {
                    enable_zbuffer();            

                    g_app.m_terrain_object.render();
                    g_app.m_gc_controller.render(-1, NULL, 0);
                    g_app.m_spell_controller.render(NULL, 0);

                    m_text_window.render(NULL, 0);

                    end_display_scene();
                }

                present_display();
            }

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

            sScriptInfo* cGameScript::script_if_flag_then(sScriptInfo* info)
            {
                
            bool skip;

                
            // see if a flag matches second entry
                if(m_flags[info->entries[0].long_value % 256] == info->entries[1].bool_value)
                    skip = 
            false;
                
            else
                    skip = 
            true;

                
            // At this point, Skip states if the script actions need to be skipped due to a conditional 
                // if..then statement.
                // 
                // Actions are further processed if skip = false, looking for an else to flip the skip mode, 
                // or an endif to end the conditional block.
                
                info = info->next;

                
            while(info)
                {
                    
            if(info->action_index == 2)         // if else, flip skip mode.
                        skip = !skip;   
                    
            else if(info->action_index == 3)    // break on end if
                        return info->next;

                    
            // Process script function in conditional block, making sure to skip actions when condition not met.
                    if(skip)
                        info = info->next;
                    
            else
                    {
                        
            if((info = process(info)) == NULL)
                            
            return NULL;
                    }
                }

                
            return NULL;    // end of script reached
            }

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

            sScriptInfo* cGameScript::script_show_msg(sScriptInfo* info)
            {
                m_text_window.set_text(info->entries[0].text, COLOR_WHITE);
                m_text_window.move(10, 10, CLIENT_WIDTH-20, 0, -1, -1, COLOR_BLACK, COLOR_ARGENTINE);

                render_scene_and_msg();

                
            // wait for a key press

                m_keyboard->acquire();
                m_keyboard->m_locks[KEY_SPACE] = 
            true;
                m_keyboard->set_key_state(KEY_SPACE, 
            false);
                
                
            while(1)
                {
                    m_keyboard->read();

                    
            if(m_keyboard->get_key_state(KEY_SPACE))
                        
            break;
                }

                m_keyboard->m_locks[KEY_SPACE] = 
            true;
                m_keyboard->set_key_state(KEY_SPACE, 
            false);

                
            return info->next;
            }

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

            sScriptInfo* cGameScript::script_show_char_msg(sScriptInfo* info)
            {
                D3DXMATRIX mat_world, mat_view, mat_proj;

                D3DXMatrixIdentity(&mat_world);
                get_display_view_matrix(&mat_view);
                get_display_proj_matrix(&mat_proj);    

                D3DVIEWPORT9 viewport;
                get_display_viewport(&viewport);    

                
            // get the character's coordinates

                
            float max_y;
                sCharacter* character = m_gc_controller->get_char(info->entries[1].long_value);

                character->
            object.get_bounds(NULL, NULL, NULL, NULL, &max_y, NULL, NULL);

                
            // project the 3D coordinates in 2D coordinates

                D3DXVECTOR3 target_vec;
                D3DXVECTOR3 source_vec(character->pos_x, character->pos_y + max_y, character->pos_z);

                D3DXVec3Project(&target_vec, &source_vec, &viewport, &mat_proj, &mat_view, &mat_world);

                m_text_window.set_text(info->entries[0].text, D3DCOLOR_RGBA(255, 255, 0, 255));
                m_text_window.move(10, 10, CLIENT_WIDTH-20, 0, target_vec.x, target_vec.y, 
                                   D3DCOLOR_RGBA(0, 30, 60, 255), COLOR_ARGENTINE);

                
            // display the window while waiting for a keypress

                m_keyboard->acquire();
                m_keyboard->m_locks[KEY_SPACE] = 
            true;
                m_keyboard->set_key_state(KEY_SPACE, 
            false);
                
                
            while(1)
                {
                    m_keyboard->read();

                    
            if(m_keyboard->get_key_state(KEY_SPACE))
                        
            break;

                    render_scene_and_msg();
                }

                m_keyboard->m_locks[KEY_SPACE] = 
            true;
                m_keyboard->set_key_state(KEY_SPACE, 
            false);   

                
            return info->next;
            }

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

            bool cApp::init()
            {
                create_display(g_hwnd, CLIENT_WIDTH, CLIENT_HEIGHT, 16, 
            truetrue);
                set_perspective(D3DX_PI/4, 1.3333f, 1.0f, 10000.0f);

                create_font(&m_font, "Arial", 16, 
            truefalse);

                m_input.create(g_hwnd, get_window_inst());
                m_keyboard.create_keyboard(&m_input);
                m_mouse.create_mouse(&m_input, 
            true);

                m_terrain_mesh.load("..\\Data\\World.x", "..\\Data\\");
                m_terrain_object.create(&m_terrain_mesh);

                
            // load the master item list

                ZeroMemory(m_mil, 
            sizeof(m_mil));

                FILE* fp;
                
            if((fp = fopen("..\\Data\\Default.mil", "rb")) == NULL)
                    
            return false;

                fread(m_mil, 1, 
            sizeof(m_mil), fp);
                fclose(fp);

                m_spell_controller.init("..\\Data\\Default.msl",
                                        array_num(g_spell_mesh_names), g_spell_mesh_names,
                                        "..\\Data\\");

                m_gc_controller.init(m_font, "..\\Data\\Default.mcl",
                                     m_mil, m_spell_controller.get_spell_list(),
                                     array_num(g_char_mesh_names), g_char_mesh_names,
                                     "..\\Data\\", "..\\Data\\",
                                     array_num(g_char_anim_infos), g_char_anim_infos);

                m_spell_controller.attach(&m_gc_controller);
                m_gc_controller.attach(&m_spell_controller);

                m_gc_controller.set_data(
            this);

                
            // add the character player
                m_gc_controller.add_char(0, 0, CHAR_PC, CHAR_STAND, 0.0f, 0.0f, 0.0f, 3.14f);

                
            // process the startup script
                m_game_script.set_data(this, &m_keyboard, &m_gc_controller, m_font);
                m_game_script.execute("..\\Data\\Startup.mls");

                
            return true;
            }

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

            bool cApp::frame()
            {
                
            static DWORD update_counter = timeGetTime();

                
            // lock to 30fps
                if(timeGetTime() < update_counter + 33)
                    
            return true;

                update_counter = timeGetTime();

                m_keyboard.acquire();
                m_keyboard.read();

                
            // exit if ESC pressed
                if(m_keyboard.get_key_state(KEY_ESC))
                    
            return false;

                m_gc_controller.update(33);
                m_spell_controller.update(33);

                m_camera.point(0.0f, 700.0f, -700.0f, 0.0f, 0.0f, 0.0f);
                set_display_camera(&m_camera);
                
                clear_display(0, 1.0f);

                
            if(begin_display_scene())
                {
                    enable_zbuffer();

                    m_terrain_object.render();
                    m_gc_controller.render(-1, NULL, 0);
                    m_spell_controller.render(NULL, 0);

                    
            static sCharacter* character = m_gc_controller.get_char(0);

                    
            char stats[128];

                    sprintf(stats, "HP: %ld / %ld\r\nMP: %ld / %ld",
                            character->health_points, character->char_def.health_points,
                            character->mana_points, character->char_def.mana_points);

                    draw_font(m_font, stats, 2, 2, 0, 0, COLOR_WHITE, DT_LEFT);

                    end_display_scene();
                }

                present_display();

                
            return true;
            }

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

            long cApp::get_input()
            {
                
            long action = 0;

                
            if(m_keyboard.get_key_state(KEY_UP) || m_keyboard.get_key_state(KEY_W))
                    action |= PRESS_UP;

                
            if(m_keyboard.get_key_state(KEY_RIGHT) || m_keyboard.get_key_state(KEY_D))
                    action |= PRESS_RIGHT;

                
            if(m_keyboard.get_key_state(KEY_DOWN) || m_keyboard.get_key_state(KEY_S))
                    action |= PRESS_DOWN;

                
            if(m_keyboard.get_key_state(KEY_LEFT) || m_keyboard.get_key_state(KEY_A))
                    action |= PRESS_LEFT;

                
            if(m_keyboard.get_key_state(KEY_SPACE))
                {
                    action |= PRESS_SPACE;
                    m_keyboard.m_locks[KEY_SPACE] = 
            true;
                    m_keyboard.set_key_state(KEY_SPACE, 
            false);
                }

                
            if(m_keyboard.get_key_state(KEY_1))
                {
                    action |= PRESS_1;
                    m_keyboard.m_locks[KEY_1] = 
            true;
                    m_keyboard.set_key_state(KEY_1, 
            false);
                }

                
            if(m_keyboard.get_key_state(KEY_2))
                {
                    action |= PRESS_2;
                    m_keyboard.m_locks[KEY_2] = 
            true;
                    m_keyboard.set_key_state(KEY_2, 
            false);
                }
                
                
            if(m_keyboard.get_key_state(KEY_3))
                {
                    action |= PRESS_3;
                    m_keyboard.m_locks[KEY_3] = 
            true;
                    m_keyboard.set_key_state(KEY_3, 
            false);
                }

                
            return action;
            }

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

            bool cApp::check_intersect(float x_start, float y_start, float z_start,
                                       
            float x_end,   float y_end,   float z_end)
            {
                
            for(sMeshInfo* mesh_info = m_terrain_mesh.get_root_mesh(); mesh_info != NULL; mesh_info = mesh_info->m_next)
                {
                    
            if(is_ray_intersect_mesh(mesh_info->m_d3d_mesh, x_start, y_start, z_start, x_end, y_end, z_end, NULL))        
                        
            return true;        
                }
                
                
            return false;
            }

            posted on 2007-12-04 21:05 lovedday 閱讀(489) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            欧美激情精品久久久久| 国产精品久久久久久久午夜片| 日本福利片国产午夜久久| 中文字幕精品久久久久人妻| 99久久精品国内| 狠狠色婷婷久久一区二区| 久久强奷乱码老熟女| 国产福利电影一区二区三区,免费久久久久久久精 | 亚洲愉拍99热成人精品热久久| 亚洲国产精品婷婷久久| 久久香综合精品久久伊人| 精产国品久久一二三产区区别| 久久久国产精华液| 久久播电影网| 国内精品久久久久久久涩爱 | 久久国产成人午夜AV影院| 国产精品久久永久免费| 久久夜色精品国产欧美乱| 国产精品美女久久福利网站| 亚洲人成无码久久电影网站| 久久久久这里只有精品 | 久久综合综合久久97色| 国产成年无码久久久久毛片| 亚洲AV日韩AV天堂久久| 久久99精品久久久大学生| 国产免费久久精品99re丫y| 久久人妻无码中文字幕| 久久精品国产免费观看 | 久久久精品无码专区不卡| 久久久精品日本一区二区三区| 精品无码久久久久久久久久| 色偷偷888欧美精品久久久| 精品久久久久久无码中文野结衣| 国产精品久久久久一区二区三区| 精品久久久久国产免费| 人人狠狠综合久久亚洲高清| 伊人伊成久久人综合网777| 国产精品99久久久精品无码| 久久精品国产99久久久古代| 欧美大香线蕉线伊人久久| 精品免费tv久久久久久久|