void cMovingSprite :: Check_on_Ground( void ) { // can't be on ground if( !m_can_be_on_ground ) { return; } if( m_type != TYPE_PLAYER && m_sprite_array != ARRAY_ENEMY && m_sprite_array != ARRAY_ACTIVE ) { return; } // if ground object if( m_ground_object ) { GL_rect rect2( m_col_rect.m_x, m_col_rect.m_y + m_col_rect.m_h, m_col_rect.m_w, 1.0f ); // if on ground object if( m_ground_object->m_col_rect.Intersects( rect2 ) && m_ground_object->m_can_be_ground ) { return; } } // don't check if flying or linked if( m_state == STA_FLY || m_state == STA_OBJ_LINKED ) { return; } // new onground check cObjectCollisionType *col_list = Collision_Check_Relative( 0.0f, m_col_rect.m_h, 0.0f, 1.0f, COLLIDE_ONLY_BLOCKING ); Reset_On_Ground(); // possible ground objects for( cObjectCollision_List::iterator itr = col_list->objects.begin(), itr_end = col_list->objects.end(); itr != itr_end; ++itr ) { cObjectCollision *col = (*itr); // ground collision found if( col->direction == DIR_BOTTOM ) { if( Set_On_Ground( col->obj ) ) { // send collision ( needed for falling platform ) Send_Collision( col ); break; } } } delete col_list; }
void cBaseBox::Check_Collision(ObjectDirection cdirection) { float check_x = 0.0f; float check_y = 0.0f; if (cdirection == DIR_BOTTOM) { check_y -= 10.0f; } else if (cdirection == DIR_TOP) { check_y += 10.0f; } else if (cdirection == DIR_LEFT) { check_x += 5.0f; } else if (cdirection == DIR_RIGHT) { check_x -= 5.0f; } cObjectCollisionType* col_list = Collision_Check_Relative(check_x, check_y, m_col_rect.m_w - (check_x * 0.5f), m_col_rect.m_h - (check_y * 0.5f)); for (cObjectCollision_List::iterator itr = col_list->objects.begin(), itr_end = col_list->objects.end(); itr != itr_end; ++itr) { cObjectCollision* col_obj = (*itr); col_obj->obj->Handle_Collision_Box(Get_Opposite_Direction(col_obj->direction), &m_col_rect); if (col_obj->m_array == ARRAY_ENEMY) { Col_Enemy(col_obj->obj); } } delete col_list; }
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; }