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;
}
Exemple #2
0
 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;
}