{"id":16603712,"url":"https://github.com/swordfish90/radialgamepad","last_synced_at":"2025-08-04T06:16:52.171Z","repository":{"id":42175470,"uuid":"267958093","full_name":"Swordfish90/RadialGamePad","owner":"Swordfish90","description":"A customizable Android library for creating virtual gamepads","archived":false,"fork":false,"pushed_at":"2022-12-20T22:50:32.000Z","size":490,"stargazers_count":25,"open_issues_count":1,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T08:40:05.409Z","etag":null,"topics":["android","android-library","configurable","games","hacktoberfest","touch-controls"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Swordfish90.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-29T21:25:12.000Z","updated_at":"2024-12-12T16:39:49.000Z","dependencies_parsed_at":"2023-01-30T02:15:43.067Z","dependency_job_id":null,"html_url":"https://github.com/Swordfish90/RadialGamePad","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/Swordfish90/RadialGamePad","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swordfish90%2FRadialGamePad","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swordfish90%2FRadialGamePad/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swordfish90%2FRadialGamePad/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swordfish90%2FRadialGamePad/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Swordfish90","download_url":"https://codeload.github.com/Swordfish90/RadialGamePad/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Swordfish90%2FRadialGamePad/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268657598,"owners_count":24285533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","configurable","games","hacktoberfest","touch-controls"],"created_at":"2024-10-12T00:52:28.783Z","updated_at":"2025-08-04T06:16:52.110Z","avatar_url":"https://github.com/Swordfish90.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RadialGamePad\n\nRadialGamePad 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).\n\n|Screen 1|Screen 2|Screen 3|\n|---|---|---|\n|![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)|\n\n## Getting started\n\nRadialGamePad is distributed through jitpack, modify your ```build.gradle``` file to include this:\n\n```\nrepositories {\n    maven { url \"https://jitpack.io\" }\n}\n\ndependencies {\n    implementation 'com.github.swordfish90:radialgamepad:$LAST_RELEASE'\n    \n    // To handle the Flow of events from RadialGamePad\n    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'\n}\n```\n\n## Usage\n\nAs 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.\n\nTo 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.\n\nEvents are returned as a Kotlin ```Flow``` and are composed of three different types:\n\n* **Direction**: fired from Sticks and Crosses and indicates a direction through the two components xAxis and yAxis\n* **Button**: indicates when a control has been pressed or released (```KeyEvent.ACTION_DOWN``` or ```KeyEvent.ACTION_UP```)\n* **Gesture**: a higher level event such as tap, double tap or triple tap\n\nHere's a simple example which creates a remote control pad and handles its events:\n\n```\nclass MainActivity : Activity() {\n    private lateinit var pad: RadialGamePad\n\n    private val padConfig = RadialGamePadConfig(\n        sockets = 6,\n        primaryDial = PrimaryDialConfig.Cross(\n            CrossConfig(\n                id = 0,\n                useDiagonals = false\n            )\n        ),\n        secondaryDials = listOf(\n            SecondaryDialConfig.SingleButton(\n                index = 1,\n                scale = 1f,\n                distance = 0f,\n                ButtonConfig(\n                    id = KeyEvent.KEYCODE_BUTTON_SELECT,\n                    iconId = R.drawable.ic_play\n                )\n            ),\n            SecondaryDialConfig.SingleButton(\n                index = 2,\n                scale = 1f,\n                distance = 0f,\n                ButtonConfig(\n                    id = KeyEvent.KEYCODE_BUTTON_L1,\n                    iconId = R.drawable.ic_stop\n                )\n            ),\n            SecondaryDialConfig.SingleButton(\n                index = 4,\n                scale = 1f,\n                distance = 0f,\n                ButtonConfig(\n                    id = KeyEvent.KEYCODE_BUTTON_MODE,\n                    iconId = R.drawable.ic_volume_down\n                )\n            ),\n            SecondaryDialConfig.SingleButton(\n                index = 5,\n                scale = 1f,\n                distance = 0f,\n                ButtonConfig(\n                    id = KeyEvent.KEYCODE_BUTTON_MODE,\n                    iconId = R.drawable.ic_volume_up\n                )\n            )\n        )\n    )\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        setContentView(R.layout.main_activity)\n\n        // Create a pad with default theme and 8dp of margins\n        pad = RadialGamePad(padConfig, 8f, requireContext())\n\n        findViewById\u003cFrameLayout\u003e(R.id.container).addView(pad)\n\n        // Collect the Flow of events to a handler\n        lifecycleScope.launch {\n            pad.events()\n                .flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED)\n                .collect {\n                    handleEvent(it)\n                }\n        }\n    }\n\n    private fun handleEvent(event: Event) {\n        // Do something with the event.\n        when (event) {\n            is Event.Button -\u003e {\n                Log.d(\"Event\", \"Button event from control ${event.id}\")\n            }\n            is Event.Gesture -\u003e {\n                Log.d(\"Event\", \"Gesture event from control ${event.id}\")\n            }\n            is Event.Direction -\u003e {\n                Log.d(\"Event\", \"Direction event from control ${event.id}\")\n            }\n        }\n    }\n}\n```\n\n### Advanced usage\n\nCheck the included app sample. If you want to see even more layouts check [Lemuroid](https://github.com/Swordfish90/Lemuroid).\n\n### Random tips\n* 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\n* If your gamepad is split into multiple views (very likely for games), consider using SecondaryDialConfig.Empty to enforce symmetry.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswordfish90%2Fradialgamepad","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswordfish90%2Fradialgamepad","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswordfish90%2Fradialgamepad/lists"}