Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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 );
}
Ejemplo n.º 3
0
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;
}