cLayer_Line_Point :: cLayer_Line_Point( cSprite_Manager *sprite_manager, cOverworld *overworld, SpriteType new_type ) : cSprite( sprite_manager ) { m_sprite_array = ARRAY_PASSIVE; m_type = new_type; m_massive_type = MASS_PASSIVE; m_pos_z = 0.087f; m_overworld = overworld; m_linked_point = NULL; if( m_type == TYPE_OW_LINE_START ) { m_pos_z += 0.001f; m_color = orange; m_name = _("Line Start Point"); } else { m_color = red; m_name = _("Line End Point"); } m_rect.m_w = 4; m_rect.m_h = 4; m_col_rect.m_w = m_rect.m_w; m_col_rect.m_h = m_rect.m_h; m_start_rect.m_w = m_rect.m_w; m_start_rect.m_h = m_rect.m_h; Update_Position_Rect(); m_camera_range = 0; }
void cMovingSprite :: Col_Move( float move_x, float move_y, bool real /* = 0 */, bool force /* = 0 */, bool check_on_ground /* = 1 */ ) { // no need to move if( Is_Float_Equal( move_x, 0.0f ) && Is_Float_Equal( move_y, 0.0f ) ) { return; } // invalid collision rect if( Is_Float_Equal( m_col_rect.m_w, 0.0f ) || Is_Float_Equal( m_col_rect.m_h, 0.0f ) ) { return; } // use speedfactor if( !real ) { move_x *= pFramerate->m_speed_factor; move_y *= pFramerate->m_speed_factor; } // check for collisions if( !force ) { // get all possible colliding items GL_rect complete_rect = m_col_rect; if( move_x > 0.0f ) { complete_rect.m_w += move_x; } else { complete_rect.m_x += move_x; complete_rect.m_w -= move_x; } if( move_y > 0.0f ) { complete_rect.m_h += move_y; } else { complete_rect.m_y += move_y; complete_rect.m_h -= move_y; } cSprite_List sprite_list; pActive_Sprite_Manager->Get_Colliding_Objects( sprite_list, complete_rect, 1, this ); // step size float step_size_x = move_x; float step_size_y = move_y; // check if object collision rect is smaller as the position check size if( step_size_x > m_col_rect.m_w ) { step_size_x = m_col_rect.m_w; } else if( step_size_x < -m_col_rect.m_w ) { step_size_x = -m_col_rect.m_w; } if( step_size_y > m_col_rect.m_h ) { step_size_y = m_col_rect.m_h; } else if( step_size_y < -m_col_rect.m_h ) { step_size_y = -m_col_rect.m_h; } float final_pos_x = m_pos_x + move_x; float final_pos_y = m_pos_y + move_y; // move in big steps cObjectCollisionType *col_list = Col_Move_in_Steps( move_x, move_y, step_size_x, step_size_y, final_pos_x, final_pos_y, sprite_list, 1 ); // if a collision is found enter pixel checking if( col_list && col_list->size() ) { // change to pixel checking if( step_size_x < -1.0f ) { step_size_x = -1.0f; } else if( step_size_x > 1.0f ) { step_size_x = 1.0f; } if( step_size_y < -1.0f ) { step_size_y = -1.0f; } else if( step_size_y > 1.0f ) { step_size_y = 1.0f; } delete col_list; col_list = Col_Move_in_Steps( move_x, move_y, step_size_x, step_size_y, final_pos_x, final_pos_y, sprite_list ); Add_Collisions( col_list, 1 ); } if( col_list ) { delete col_list; } } // don't check for collisions else { m_pos_x += move_x; m_pos_y += move_y; Update_Position_Rect(); } // if check on ground if( check_on_ground ) { Check_on_Ground(); } // check/handle if moved out of level rect Check_Out_Of_Level_Hor( move_x, 1 ); Check_Out_Of_Level_Ver( move_y, 1 ); }
cObjectCollisionType *cMovingSprite :: Col_Move_in_Steps( float move_x, float move_y, float step_size_x, float step_size_y, float final_pos_x, float final_pos_y, cSprite_List sprite_list, bool stop_on_internal /* = 0 */ ) { if( sprite_list.empty() ) { cSprite::Move( final_pos_x - m_pos_x, final_pos_y - m_pos_y, 1 ); return NULL; } // collision list cObjectCollisionType *col_list = new cObjectCollisionType(); bool move_x_valid = 1; bool move_y_valid = 1; /* Checks in both directions simultaneously * if a collision occurs it saves the direction */ while( move_x_valid || move_y_valid ) { if( move_x_valid ) { // nothing to do if( Is_Float_Equal( step_size_x, 0.0f ) ) { move_x_valid = 0; continue; } // collision check cObjectCollisionType *col_list_temp = Collision_Check_Relative( step_size_x, 0.0f, 0.0f, 0.0f, COLLIDE_COMPLETE, &sprite_list ); bool collision_found = 0; // stop on everything if( stop_on_internal ) { if( col_list_temp->size() ) { collision_found = 1; } } // stop only on blocking else { if( col_list_temp->Is_Included( COL_VTYPE_BLOCKING ) ) { collision_found = 1; } // remove internal collision from further checks else if( col_list_temp->objects.size() ) { for( cObjectCollision_List::iterator itr = col_list_temp->objects.begin(), itr_end = col_list_temp->objects.end(); itr != itr_end; ++itr ) { cObjectCollision *col = (*itr); if( col->valid_type != COL_VTYPE_INTERNAL ) { continue; } // find in sprite list cSprite_List::iterator sprite_itr = std::find( sprite_list.begin(), sprite_list.end(), col->obj ); // not found if( sprite_itr == sprite_list.end() ) { continue; } sprite_list.erase( sprite_itr ); } // if no objects left if( sprite_list.empty() ) { // move to final position m_pos_x = final_pos_x; } } } if( col_list_temp->size() ) { col_list->objects.insert( col_list->objects.end(), col_list_temp->objects.begin(), col_list_temp->objects.end() ); col_list_temp->objects.clear(); } delete col_list_temp; if( !collision_found ) { m_pos_x += step_size_x; if( ( step_size_x > 0.0f && final_pos_x <= m_pos_x ) || ( step_size_x < 0.0f && final_pos_x >= m_pos_x ) ) { m_pos_x = final_pos_x; move_x_valid = 0; step_size_x = 0.0f; } // update collision rects Update_Position_Rect(); } // collision found else { step_size_x = 0.0f; move_x_valid = 0; } } if( move_y_valid ) { // nothing to do if( Is_Float_Equal( step_size_y, 0.0f ) ) { move_y_valid = 0; continue; } // collision check cObjectCollisionType *col_list_temp = Collision_Check_Relative( 0.0f, step_size_y, 0.0f, 0.0f, COLLIDE_COMPLETE, &sprite_list ); bool collision_found = 0; // stop on everything if( stop_on_internal ) { if( col_list_temp->size() ) { collision_found = 1; } } // stop only on blocking else { if( col_list_temp->Is_Included( COL_VTYPE_BLOCKING ) ) { collision_found = 1; } // remove internal collision from further checks else if( col_list_temp->objects.size() ) { for( cObjectCollision_List::iterator itr = col_list_temp->objects.begin(), itr_end = col_list_temp->objects.end(); itr != itr_end; ++itr ) { cObjectCollision *col = (*itr); if( col->valid_type != COL_VTYPE_INTERNAL ) { continue; } // find in sprite list cSprite_List::iterator sprite_itr = std::find( sprite_list.begin(), sprite_list.end(), col->obj ); // not found if( sprite_itr == sprite_list.end() ) { continue; } sprite_list.erase( sprite_itr ); // if no objects left if( sprite_list.empty() ) { // move to final position m_pos_y = final_pos_y; } } } } if( col_list_temp->size() ) { col_list->objects.insert( col_list->objects.end(), col_list_temp->objects.begin(), col_list_temp->objects.end() ); col_list_temp->objects.clear(); } delete col_list_temp; if( !collision_found ) { m_pos_y += step_size_y; if( ( step_size_y > 0.0f && final_pos_y <= m_pos_y ) || ( step_size_y < 0.0f && final_pos_y >= m_pos_y ) ) { m_pos_y = final_pos_y; move_y_valid = 0; step_size_y = 0.0f; } // update collision rects Update_Position_Rect(); } // collision found else { step_size_y = 0.0f; move_y_valid = 0; } } } return col_list; }