Initial LibGDX project scaffold for ArtLegend

Multi-module Gradle setup targeting Android (S-Pen) and Desktop (Wacom/LWJGL3).
Includes core game stub, Android launcher with immersive mode, and desktop launcher.
Asset directory shared across platforms. Gradle 8.6, Kotlin 1.9.23, LibGDX 1.12.1.
This commit is contained in:
2026-05-04 11:44:40 -07:00
commit 24d78786db
13 changed files with 237 additions and 0 deletions

67
android/build.gradle.kts Normal file
View File

@@ -0,0 +1,67 @@
plugins {
kotlin("android")
id("com.android.application")
}
val gdxVersion: String by project
val natives: Configuration by configurations.creating
android {
namespace = "com.artlegend"
compileSdk = 34
defaultConfig {
applicationId = "com.artlegend"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "0.1.0"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
sourceSets {
getByName("main") {
assets.srcDirs(rootProject.file("assets"))
jniLibs.srcDirs("libs")
}
}
}
dependencies {
implementation(project(":core"))
implementation("com.badlogicgames.gdx:gdx-backend-android:$gdxVersion")
natives("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a")
natives("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a")
natives("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86")
natives("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64")
}
tasks.register("copyAndroidNatives") {
doFirst {
natives.files.forEach { jar ->
val outputDir = file("libs")
outputDir.mkdirs()
copy {
from(zipTree(jar))
into(outputDir)
include("*.so")
eachFile { path = name }
includeEmptyDirs = false
}
}
}
}
tasks.whenTaskAdded {
if (name.contains("package") || name.contains("assemble") || name.contains("bundle")) {
dependsOn("copyAndroidNatives")
}
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Stylus is preferred but not required — allows install on non-stylus devices -->
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/GdxTheme">
<activity
android:name=".AndroidLauncher"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"
android:exported="true"
android:screenOrientation="fullSensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,17 @@
package com.artlegend
import android.os.Bundle
import com.badlogic.gdx.backends.android.AndroidApplication
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration
class AndroidLauncher : AndroidApplication() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val config = AndroidApplicationConfiguration().apply {
useImmersiveMode = true
useGyroscope = false
useAccelerometer = false
}
initialize(ArtLegend(), config)
}
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ArtLegend</string>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="GdxTheme" parent="android:Theme.NoTitleBar.Fullscreen" />
</resources>

21
build.gradle.kts Normal file
View File

@@ -0,0 +1,21 @@
buildscript {
val kotlinVersion: String by project
val androidGradleVersion: String by project
repositories {
mavenCentral()
google()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
classpath("com.android.tools.build:gradle:$androidGradleVersion")
}
}
allprojects {
repositories {
mavenCentral()
google()
}
}

13
core/build.gradle.kts Normal file
View File

@@ -0,0 +1,13 @@
plugins {
kotlin("jvm")
}
val gdxVersion: String by project
dependencies {
api("com.badlogicgames.gdx:gdx:$gdxVersion")
}
kotlin {
jvmToolchain(17)
}

View File

@@ -0,0 +1,27 @@
package com.artlegend
import com.badlogic.gdx.Game
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Screen
import com.badlogic.gdx.graphics.GL20
class ArtLegend : Game() {
override fun create() {
setScreen(PlaceholderScreen())
}
}
class PlaceholderScreen : Screen {
override fun show() {}
override fun render(delta: Float) {
Gdx.gl.glClearColor(0.08f, 0.08f, 0.10f, 1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
}
override fun resize(width: Int, height: Int) {}
override fun pause() {}
override fun resume() {}
override fun hide() {}
override fun dispose() {}
}

28
desktop/build.gradle.kts Normal file
View File

@@ -0,0 +1,28 @@
plugins {
kotlin("jvm")
application
}
val gdxVersion: String by project
dependencies {
implementation(project(":core"))
implementation("com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion")
implementation("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop")
}
application {
mainClass.set("com.artlegend.DesktopLauncherKt")
}
kotlin {
jvmToolchain(17)
}
tasks.withType<Jar> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes["Main-Class"] = "com.artlegend.DesktopLauncherKt"
}
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
}

View File

@@ -0,0 +1,14 @@
package com.artlegend
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
fun main() {
val config = Lwjgl3ApplicationConfiguration().apply {
setTitle("ArtLegend")
setWindowedMode(1280, 800)
setForegroundFPS(60)
useVsync(true)
}
Lwjgl3Application(ArtLegend(), config)
}

6
gradle.properties Normal file
View File

@@ -0,0 +1,6 @@
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
android.useAndroidX=true
gdxVersion=1.12.1
kotlinVersion=1.9.23
androidGradleVersion=8.3.0

View File

@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2
settings.gradle.kts Normal file
View File

@@ -0,0 +1,2 @@
rootProject.name = "artlegend"
include("core", "android", "desktop")