-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0962807
commit 3f71a70
Showing
27 changed files
with
769 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# SDL2 | ||
|
||
JamJar includes the [SDL2 library](https://github.com/libsdl-org/SDL) to handle user input, window management, and | ||
fullscreen functionality. There is a wrapper around the SDL2 APIs to make it integrate better with the JamJar | ||
architecture using entities, components, and systems. | ||
|
||
The `SDL2InputSystem` handles converting SDL2 user input into a JamJar ECS friendly format through messages. | ||
|
||
The `WindowSystem` makes use of SDL2 to help when calculating screen sizes for fullscreen. | ||
|
||
## Setting up the SDL2 Input System | ||
|
||
To set up a `SDL2InputSystem` you only need to provide a message bus: | ||
|
||
```c++ | ||
#include "standard/sdl2_input/sdl2_input_system.hpp" | ||
... | ||
new JamJar::Standard::SDL2InputSystem(messageBus); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Keyboard Input | ||
|
||
The `SDL2InputSystem` broadcasts keyboard events, which can be listened to and parsed to handle keyboard input. | ||
|
||
## Subscribing to Key Events | ||
|
||
There are two keyboard events that can be subscribed to, `MESSAGE_KEY_DOWN_EVENT` and `MESSAGE_KEY_UP_EVENT`. | ||
|
||
```c++ | ||
#include "standard/sdl2_input/sdl2_input_system.hpp" | ||
... | ||
YourSystem::YourSystem(JamJar::MessageBus *messageBus) : JamJar::System(messageBus) { | ||
this->messageBus->Subscribe(this, JamJar::Standard::SDL2InputSystem::MESSAGE_KEY_DOWN_EVENT); | ||
this->messageBus->Subscribe(this, JamJar::Standard::SDL2InputSystem::MESSAGE_KEY_UP_EVENT); | ||
} | ||
``` | ||
## Parsing Key Events | ||
Each key event message has a payload which is of type `SDL2KeyEvent` which contains some useful quick access | ||
information, alongside the raw `SDL_Event` that gives full advanced key event information. | ||
The quick access information in the `SDL2KeyEvent` is: | ||
- Key name as a character array. | ||
- The key event type, expressed as an `SDL2KeyEventType` enum. | ||
- If the key event is a repeat (holding down a key will generate multiple key down events, the duplicates are marked as | ||
repeat, this is useful for handling user text input). | ||
See the SDL2 documentation for a full reference of the raw [SDL_Event](https://wiki.libsdl.org/SDL_Event). | ||
```c++ | ||
#include "standard/sdl2_input/sdl2_input_system.hpp" | ||
... | ||
void YourSystem::OnMessage(JamJar::Message *message) { | ||
System::OnMessage(message); | ||
switch (message->type) { | ||
case JamJar::Standard::SDL2InputSystem::MESSAGE_KEY_DOWN_EVENT: { | ||
auto *eventMessage = static_cast<JamJar::MessagePayload<JamJar::Standard::SDL2KeyEvent> *>(message); | ||
auto event = eventMessage->payload; | ||
if (event.repeat) { | ||
// Ignore repeat keypresses | ||
break; | ||
} | ||
std::cout << "listener got key down: " << event.key << std::endl; | ||
break; | ||
} | ||
case JamJar::Standard::SDL2InputSystem::MESSAGE_KEY_UP_EVENT: { | ||
auto *eventMessage = static_cast<JamJar::MessagePayload<JamJar::Standard::SDL2KeyEvent> *>(message); | ||
auto event = eventMessage->payload; | ||
if (event.repeat) { | ||
break; | ||
} | ||
std::cout << "listener got key up: " << event.key << std::endl; | ||
break; | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# Mouse Input | ||
|
||
The `SDL2InputSystem` broadcasts mouse events, which can be listened to and parsed to handle mouse input. | ||
|
||
## Subscribing to Mouse Events | ||
|
||
There are four mouse events that can be subscribed to, `MESSAGE_MOUSE_BUTTON_UP_EVENT`, | ||
`MESSAGE_MOUSE_BUTTON_DOWN_EVENT`, `MESSAGE_MOUSE_MOTION_EVENT`, and `MESSAGE_MOUSE_WHEEL_EVENT`. | ||
|
||
```c++ | ||
#include "standard/sdl2_input/sdl2_input_system.hpp" | ||
... | ||
YourSystem::YourSystem(JamJar::MessageBus *messageBus) : JamJar::System(messageBus) { | ||
this->messageBus->Subscribe(this, JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_BUTTON_UP_EVENT); | ||
this->messageBus->Subscribe(this, JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_BUTTON_DOWN_EVENT); | ||
this->messageBus->Subscribe(this, JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_MOTION_EVENT); | ||
this->messageBus->Subscribe(this, JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_WHEEL_EVENT); | ||
} | ||
``` | ||
## Parsing Mouse Events | ||
Each mouse event message has a payload which is of type `SDL2MouseEvent` which contains some useful quick access | ||
information, alongside the raw `SDL_Event` that gives full advanced key event information. | ||
The quick access information in the `SDL2MouseEvent` is: | ||
- The mouse event type, expressed as an `SDL2MouseEventType` enum. | ||
- An optional value containing the mouse button used, expressed as an optional `SDL2MouseButton` (this is not present | ||
for mouse motion or mouse wheel events). | ||
- The position of the mouse during the event expressed in terms of the canvas (top left canvas is `x:0, y:0`). | ||
See the SDL2 documentation for a full reference of the raw [SDL_Event](https://wiki.libsdl.org/SDL_Event). | ||
```c++ | ||
#include "standard/sdl2_input/sdl2_input_system.hpp" | ||
... | ||
void YourSystem::OnMessage(JamJar::Message *message) { | ||
System::OnMessage(message); | ||
switch (message->type) { | ||
case JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_BUTTON_DOWN_EVENT: { | ||
auto *eventMessage = static_cast<JamJar::MessagePayload<JamJar::Standard::SDL2MouseEvent> *>(message); | ||
auto event = eventMessage->payload; | ||
if (event.button == JamJar::Standard::SDL2MouseButton::LEFT) { | ||
std::cout << "listener got left mouse button down" << std::endl; | ||
} else if (event.button == JamJar::Standard::SDL2MouseButton::RIGHT) { | ||
std::cout << "listener got right mouse button down" << std::endl; | ||
} else { | ||
std::cout << "listener got a different mouse button down" << std::endl; | ||
} | ||
break; | ||
} | ||
case JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_BUTTON_UP_EVENT: { | ||
auto *eventMessage = static_cast<JamJar::MessagePayload<JamJar::Standard::SDL2MouseEvent> *>(message); | ||
auto event = eventMessage->payload; | ||
if (event.button == JamJar::Standard::SDL2MouseButton::LEFT) { | ||
std::cout << "listener got left mouse button up" << std::endl; | ||
} else if (event.button == JamJar::Standard::SDL2MouseButton::RIGHT) { | ||
std::cout << "listener got right mouse button up" << std::endl; | ||
} else { | ||
std::cout << "listener got a different mouse button up" << std::endl; | ||
} | ||
break; | ||
} | ||
case JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_WHEEL_EVENT: { | ||
auto *eventMessage = static_cast<JamJar::MessagePayload<JamJar::Standard::SDL2MouseEvent> *>(message); | ||
auto event = eventMessage->payload; | ||
if (event.event.wheel.y > 0) { | ||
std::cout << "mouse wheel up" << std::endl; | ||
} else if (event.event.wheel.y < 0) { | ||
std::cout << "mouse wheel down" << std::endl; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Getting the World Position of a Mouse Event | ||
|
||
You can convert the mouse canvas position included in the event information to a world event if you have the camera | ||
that the click occurred in and the SDL2 window of the game canvas. | ||
|
||
There are three utility functions provided to calculate the world position: | ||
|
||
- `MousePositionToCanvasPosition` | ||
- `CanvasPositionToWorldPosition` | ||
- `MousePositionToWorldPosition` | ||
|
||
They exist in the same import as the `Camera` component. | ||
|
||
```c++ | ||
#include "standard/sdl2_input/sdl2_input_system.hpp" | ||
#include "standard/2d/camera/camera.hpp" | ||
#include "standard/2d/transform/transform.hpp" | ||
#include <SDL2/SDL.h> | ||
... | ||
void YourSystem::OnMessage(JamJar::Message *message) { | ||
MapSystem::OnMessage(message); | ||
switch (message->type) { | ||
case JamJar::Standard::SDL2InputSystem::MESSAGE_MOUSE_BUTTON_DOWN_EVENT: { | ||
auto *eventMessage = static_cast<JamJar::MessagePayload<JamJar::Standard::SDL2MouseEvent> *>(message); | ||
auto event = eventMessage->payload; | ||
|
||
if (this->entities.size() <= 0) { | ||
break; | ||
} | ||
|
||
// Get the first camera that is registered, assume that it is the one that is clicked (this holds true if | ||
// you only have one camera, if you have multiple more complex logic is required) | ||
auto cameraEntity = this->entities.begin()->second; | ||
auto transform = | ||
static_cast<JamJar::Standard::_2D::Transform *>(cameraEntity.Get(JamJar::Standard::_2D::Transform::KEY)); | ||
auto camera = | ||
static_cast<JamJar::Standard::_2D::Camera *>(cameraEntity.Get(JamJar::Standard::_2D::Camera::KEY)); | ||
|
||
// In this instance the SDL2_Window is stored in the YourSystem object as a member variable, allowing it to | ||
// be accessed. The SDL2_Window is not normally stored in a System and this needs to be set up by providing it | ||
// to the constructor. | ||
auto worldPos = JamJar::Standard::_2D::MousePositionToWorldPosition(event.position, transform->position, camera, | ||
this->window); | ||
|
||
std::cout << "listener got mouse down on world position x: " << worldPos.x << ", y:" << worldPos.y << std::endl; | ||
break; | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
cmake_minimum_required(VERSION 3.14) | ||
|
||
project(MouseInput VERSION 0.0.0) | ||
|
||
### ===== dependencies ===== ### | ||
|
||
# We don't need to compile the unit tests to use the library | ||
set(JAMJAR_COMPILE_UNIT_TESTS OFF CACHE BOOL "Compile JamJar unit tests") | ||
|
||
include(FetchContent) | ||
|
||
# This example relies directly on the latest code in the parent directory, if using the library externally instead | ||
# this should be fetched from over the internet, e.g.: | ||
# FetchContent_Declare(JamJar | ||
# GIT_REPOSITORY "git@github.com:jamjarlabs/JamJar.git" | ||
# GIT_TAG "<library version>" | ||
# ) | ||
|
||
set(JAMJAR_NATIVE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../") | ||
|
||
FetchContent_Declare(JamJar | ||
SOURCE_DIR ${JAMJAR_NATIVE_SOURCE_DIR} | ||
) | ||
|
||
FetchContent_MakeAvailable(JamJar) | ||
|
||
### ===== core ===== ### | ||
|
||
set(CMAKE_CXX_FLAGS "-s USE_SDL=2 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 --preload-file ${PROJECT_SOURCE_DIR}/assets@/assets") | ||
SET(CMAKE_EXE_LINKER_FLAGS "-s LLD_REPORT_UNDEFINED") | ||
|
||
set(EXE_SOURCES | ||
src/main.cpp | ||
src/mouse_input.cpp | ||
src/input_controller.cpp | ||
) | ||
|
||
add_executable(MouseInput ${EXE_SOURCES}) | ||
|
||
target_include_directories(MouseInput | ||
PRIVATE | ||
src | ||
) | ||
|
||
target_link_libraries(MouseInput PRIVATE JamJar) | ||
|
||
configure_file(${PROJECT_SOURCE_DIR}/index.html ${PROJECT_BINARY_DIR}/index.html COPYONLY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Mouse Input | ||
|
||
This is an example that demonstrates how to | ||
|
||
The code is designed to be simple and easy to follow. | ||
|
||
## Overview | ||
|
||
This example allows left clicking to place a smiley face sprite on the position you have clicked. | ||
|
||
## Dependencies | ||
|
||
See the dependencies for [JamJar here](../../README.md#Dependencies). | ||
|
||
## Running this example | ||
|
||
1. Clone down the JamJar project: | ||
|
||
```bash | ||
git clone git@github.com:jamjarlabs/JamJar.git | ||
``` | ||
|
||
2. Navigate the cloned directory: | ||
|
||
```bash | ||
cd JamJar | ||
``` | ||
|
||
3. Use `cmake` to generate the build system and pull down any dependencies: | ||
|
||
```bash | ||
emcmake cmake -D CMAKE_EXPORT_COMPILE_COMMANDS=ON . -B build | ||
``` | ||
|
||
4. Navigate to the generated example build directory: | ||
|
||
```bash | ||
cd build/examples/MouseInput | ||
``` | ||
|
||
5. Build the project: | ||
|
||
```bash | ||
emmake make | ||
``` | ||
|
||
6. If you want to view the example, you can now access the generated HTML, if you have Python 3 installed a handy way | ||
to do this is to run: | ||
|
||
```bash | ||
python -m http.server | ||
``` | ||
|
||
Then you should be able to access the game at <http://127.0.0.1:8000/>. |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.