Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/swordfish90/radialgamepad
A customizable Android library for creating virtual gamepads
https://github.com/swordfish90/radialgamepad
android android-library configurable games hacktoberfest touch-controls
Last synced: 4 months ago
JSON representation
A customizable Android library for creating virtual gamepads
- Host: GitHub
- URL: https://github.com/swordfish90/radialgamepad
- Owner: Swordfish90
- License: gpl-3.0
- Created: 2020-05-29T21:25:12.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2022-12-20T22:50:32.000Z (about 2 years ago)
- Last Synced: 2024-05-09T08:17:29.087Z (9 months ago)
- Topics: android, android-library, configurable, games, hacktoberfest, touch-controls
- Language: Kotlin
- Homepage:
- Size: 479 KB
- Stars: 18
- Watchers: 4
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RadialGamePad
RadialGamePad is an Android library for creating gamepads overlays. It has been designed with customization in mind and it's currently powering all the layouts you see in [Lemuroid](https://github.com/Swordfish90/Lemuroid).
|Screen 1|Screen 2|Screen 3|
|---|---|---|
|![Screen1](https://github.com/Swordfish90/RadialGamePad/blob/master/screenshots/screen0.png)|![Screen2](https://github.com/Swordfish90/RadialGamePad/blob/master/screenshots/screen1.png)|![Screen3](https://github.com/Swordfish90/RadialGamePad/blob/master/screenshots/screen2.png)|## Getting started
RadialGamePad is distributed through jitpack, modify your ```build.gradle``` file to include this:
```
repositories {
maven { url "https://jitpack.io" }
}dependencies {
implementation 'com.github.swordfish90:radialgamepad:$LAST_RELEASE'
// To handle the Flow of events from RadialGamePad
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
}
```## Usage
As the name suggests, RadialGamePad is built around the idea circular dials. There is a primary dial in the center which contains a primary control such as ```Cross```, ```Stick``` or ```PrimaryButtons```, surrounded by optional secondary dials.
To define the layout a ```RadialGamePadConfig``` object is passed to the constructor, and the library will take care of sizing and positioning controls to optimize the available space.
Events are returned as a Kotlin ```Flow``` and are composed of three different types:
* **Direction**: fired from Sticks and Crosses and indicates a direction through the two components xAxis and yAxis
* **Button**: indicates when a control has been pressed or released (```KeyEvent.ACTION_DOWN``` or ```KeyEvent.ACTION_UP```)
* **Gesture**: a higher level event such as tap, double tap or triple tapHere's a simple example which creates a remote control pad and handles its events:
```
class MainActivity : Activity() {
private lateinit var pad: RadialGamePadprivate val padConfig = RadialGamePadConfig(
sockets = 6,
primaryDial = PrimaryDialConfig.Cross(
CrossConfig(
id = 0,
useDiagonals = false
)
),
secondaryDials = listOf(
SecondaryDialConfig.SingleButton(
index = 1,
scale = 1f,
distance = 0f,
ButtonConfig(
id = KeyEvent.KEYCODE_BUTTON_SELECT,
iconId = R.drawable.ic_play
)
),
SecondaryDialConfig.SingleButton(
index = 2,
scale = 1f,
distance = 0f,
ButtonConfig(
id = KeyEvent.KEYCODE_BUTTON_L1,
iconId = R.drawable.ic_stop
)
),
SecondaryDialConfig.SingleButton(
index = 4,
scale = 1f,
distance = 0f,
ButtonConfig(
id = KeyEvent.KEYCODE_BUTTON_MODE,
iconId = R.drawable.ic_volume_down
)
),
SecondaryDialConfig.SingleButton(
index = 5,
scale = 1f,
distance = 0f,
ButtonConfig(
id = KeyEvent.KEYCODE_BUTTON_MODE,
iconId = R.drawable.ic_volume_up
)
)
)
)override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)setContentView(R.layout.main_activity)
// Create a pad with default theme and 8dp of margins
pad = RadialGamePad(padConfig, 8f, requireContext())findViewById(R.id.container).addView(pad)
// Collect the Flow of events to a handler
lifecycleScope.launch {
pad.events()
.flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED)
.collect {
handleEvent(it)
}
}
}private fun handleEvent(event: Event) {
// Do something with the event.
when (event) {
is Event.Button -> {
Log.d("Event", "Button event from control ${event.id}")
}
is Event.Gesture -> {
Log.d("Event", "Gesture event from control ${event.id}")
}
is Event.Direction -> {
Log.d("Event", "Direction event from control ${event.id}")
}
}
}
}
```### Advanced usage
Check the included app sample. If you want to see even more layouts check [Lemuroid](https://github.com/Swordfish90/Lemuroid).
### Random tips
* Do not put margins around RadialGamePad. If you need them use the margin variable, so that touch events will be still forwarded to the view
* If your gamepad is split into multiple views (very likely for games), consider using SecondaryDialConfig.Empty to enforce symmetry.