diff options
| author | JAROWMR <jarorutjes07@gmail.com> | 2024-12-05 21:10:07 +0100 | 
|---|---|---|
| committer | JAROWMR <jarorutjes07@gmail.com> | 2024-12-05 21:10:07 +0100 | 
| commit | 9604616001ac273f2c966c3c829638e905def7bf (patch) | |
| tree | 7e958c2b658a4dbc9e79068d7309513efa928937 /src/crepe/system/InputSystem.cpp | |
| parent | 018a451051669506be447aa925ecb6a9f5aaf418 (diff) | |
| parent | 1f4e961d7f9d6887c807cac1a362f2d178b0860b (diff) | |
merge with master and keypressed added to game
Diffstat (limited to 'src/crepe/system/InputSystem.cpp')
| -rw-r--r-- | src/crepe/system/InputSystem.cpp | 187 | 
1 files changed, 187 insertions, 0 deletions
diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp new file mode 100644 index 0000000..7cc8d30 --- /dev/null +++ b/src/crepe/system/InputSystem.cpp @@ -0,0 +1,187 @@ +#include "../api/Button.h" +#include "../manager/ComponentManager.h" +#include "../manager/EventManager.h" + +#include "InputSystem.h" + +using namespace crepe; + +void InputSystem::update() { +	ComponentManager & mgr = this->mediator.component_manager; +	EventManager & event_mgr = this->mediator.event_manager; +	std::vector<SDLContext::EventData> event_list = SDLContext::get_instance().get_events(); +	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); +	RefVector<Camera> cameras = mgr.get_components_by_type<Camera>(); +	OptionalRef<Camera> curr_cam_ref; +	// Find the active camera +	for (Camera & cam : cameras) { +		if (!cam.active) continue; +		curr_cam_ref = cam; +		break; +	} +	if (!curr_cam_ref) return; +	Camera & current_cam = curr_cam_ref; +	RefVector<Transform> transform_vec +		= mgr.get_components_by_id<Transform>(current_cam.game_object_id); +	Transform & cam_transform = transform_vec.front().get(); +	int camera_origin_x +		= cam_transform.position.x + current_cam.offset.x - (current_cam.viewport_size.x / 2); +	int camera_origin_y +		= cam_transform.position.y + current_cam.offset.y - (current_cam.viewport_size.y / 2); + +	for (const SDLContext::EventData & event : event_list) { +		int world_mouse_x = event.mouse_position.x + camera_origin_x; +		int world_mouse_y = event.mouse_position.y + camera_origin_y; +		// check if the mouse is within the viewport +		bool mouse_in_viewport +			= !(world_mouse_x < camera_origin_x +				|| world_mouse_x > camera_origin_x + current_cam.viewport_size.x +				|| world_mouse_y < camera_origin_y +				|| world_mouse_y > camera_origin_y + current_cam.viewport_size.y); + +		switch (event.event_type) { +			case SDLContext::EventType::KEYDOWN: +				event_mgr.queue_event<KeyPressEvent>(KeyPressEvent{ +					.repeat = event.key_repeat, +					.key = event.key, +				}); +				break; +			case SDLContext::EventType::KEYUP: +				event_mgr.queue_event<KeyReleaseEvent>(KeyReleaseEvent{ +					.key = event.key, +				}); +				break; +			case SDLContext::EventType::MOUSEDOWN: +				if (!mouse_in_viewport) { +					break; +				} +				event_mgr.queue_event<MousePressEvent>(MousePressEvent{ +					.mouse_x = world_mouse_x, +					.mouse_y = world_mouse_y, +					.button = event.mouse_button, +				}); +				this->last_mouse_down_position = {world_mouse_x, world_mouse_y}; +				this->last_mouse_button = event.mouse_button; +				break; +			case SDLContext::EventType::MOUSEUP: { +				if (!mouse_in_viewport) { +					break; +				} +				event_mgr.queue_event<MouseReleaseEvent>(MouseReleaseEvent{ +					.mouse_x = world_mouse_x, +					.mouse_y = world_mouse_y, +					.button = event.mouse_button, +				}); +				//check if its a click by checking the last button down +				int delta_x = world_mouse_x - this->last_mouse_down_position.x; +				int delta_y = world_mouse_y - this->last_mouse_down_position.y; + +				if (this->last_mouse_button == event.mouse_button +					&& std::abs(delta_x) <= click_tolerance +					&& std::abs(delta_y) <= click_tolerance) { +					event_mgr.queue_event<MouseClickEvent>(MouseClickEvent{ +						.mouse_x = world_mouse_x, +						.mouse_y = world_mouse_y, +						.button = event.mouse_button, +					}); + +					this->handle_click(event.mouse_button, world_mouse_x, world_mouse_y); +				} +			} break; +			case SDLContext::EventType::MOUSEMOVE: +				if (!mouse_in_viewport) { +					break; +				} +				event_mgr.queue_event<MouseMoveEvent>(MouseMoveEvent{ +					.mouse_x = world_mouse_x, +					.mouse_y = world_mouse_y, +					.delta_x = event.rel_mouse_move.x, +					.delta_y = event.rel_mouse_move.y, +				}); +				this->handle_move(event, world_mouse_x, world_mouse_y); +				break; +			case SDLContext::EventType::MOUSEWHEEL: +				event_mgr.queue_event<MouseScrollEvent>(MouseScrollEvent{ +					.mouse_x = world_mouse_x, +					.mouse_y = world_mouse_y, +					.scroll_direction = event.scroll_direction, +					.scroll_delta = event.scroll_delta, +				}); +				break; +			case SDLContext::EventType::SHUTDOWN: +				event_mgr.queue_event<ShutDownEvent>(ShutDownEvent{}); +				break; +			default: +				break; +		} +	} +} +void InputSystem::handle_move(const SDLContext::EventData & event_data, +							  const int world_mouse_x, const int world_mouse_y) { +	ComponentManager & mgr = this->mediator.component_manager; + +	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); + +	for (Button & button : buttons) { +		RefVector<Transform> transform_vec +			= mgr.get_components_by_id<Transform>(button.game_object_id); +		Transform & transform(transform_vec.front().get()); + +		bool was_hovering = button.hover; +		if (button.active +			&& this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { +			button.hover = true; +			if (!was_hovering && button.on_mouse_enter) { +				button.on_mouse_enter(); +			} +		} else { +			button.hover = false; +			// Trigger the on_exit callback if the hover state just changed to false +			if (was_hovering && button.on_mouse_exit) { +				button.on_mouse_exit(); +			} +		} +	} +} + +void InputSystem::handle_click(const MouseButton & mouse_button, const int world_mouse_x, +							   const int world_mouse_y) { +	ComponentManager & mgr = this->mediator.component_manager; + +	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); + +	for (Button & button : buttons) { +		RefVector<Transform> transform_vec +			= mgr.get_components_by_id<Transform>(button.game_object_id); +		Transform & transform = transform_vec.front().get(); + +		if (button.active +			&& this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { +			this->handle_button_press(button); +		} +	} +} + +bool InputSystem::is_mouse_inside_button(const int mouse_x, const int mouse_y, +										 const Button & button, const Transform & transform) { +	int actual_x = transform.position.x + button.offset.x; +	int actual_y = transform.position.y + button.offset.y; + +	int half_width = button.dimensions.x / 2; +	int half_height = button.dimensions.y / 2; + +	// Check if the mouse is within the button's boundaries +	return mouse_x >= actual_x - half_width && mouse_x <= actual_x + half_width +		   && mouse_y >= actual_y - half_height && mouse_y <= actual_y + half_height; +} + +void InputSystem::handle_button_press(Button & button) { +	if (button.is_toggle) { +		if (!button.is_pressed && button.on_click) { +			button.on_click(); +		} +		button.is_pressed = !button.is_pressed; +	} else if (button.on_click) { +		button.on_click(); +	} +}  |