Java使用FFM API调用SDL

首发于Enaium的个人博客


首先我们需要创建一个Gradle项目,之后设置项目的JDK版本,设置为22及以上版本。

kotlin 复制代码
plugins {
    kotlin("jvm") version "2.1.0"
}

group = "cn.enaium"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}
kotlin {
    jvmToolchain(23)
}

接着我们在当前目录初始化git仓库,之后需要添加一个子模块。、

复制代码
git init
git submodule add git@github.com:libsdl-org/SDL.git SDL

之后编写生成接口的脚本,在这之前你必须安装CMakejextract到环境变量中。

powershell 复制代码
$sdl_path = "SDL"
mkdir "$sdl_path/build"; cmake -DCMAKE_BUILD_TYPE=Release "$sdl_path" -B "$sdl_path/build"; cmake --build "$sdl_path/build" --config Release --parallel
jextract --include-dir "$sdl_path/include" --dump-includes "$sdl_path/build/includes.txt" "$sdl_path/include/SDL3/SDL.h"
jextract --include-dir "$sdl_path/include" --output src/main/java --target-package org.libsdl --library SDL3 --use-system-load-library "@$sdl_path/build/includes.txt" "$sdl_path/include/SDL3/SDL.h"

首先是使用CMake编译SDL,之后使用jextract生成Java接口,之后运行脚本,这样就会在src/main/java生成SDL3的接口。

接着我们回到build.gradle.kts,添加application插件,之后将编译好的路径添加到启动参数中。

kotlin 复制代码
plugins {
    application
}

application {
    mainClass = "MainKt"
    applicationDefaultJvmArgs = listOf("-Djava.library.path=SDL/build/Release", "--enable-native-access=ALL-UNNAMED")
}

之后就可以调用SDL的接口了。

kotlin 复制代码
import org.libsdl.*
import org.libsdl.SDL_h_1.*
import java.lang.foreign.Arena

/**
 * @author Enaium
 */
fun main() {
    Arena.ofConfined().use {
        val init = SDL_h_2.SDL_Init(SDL_INIT_VIDEO() and SDL_INIT_EVENTS())

        if (!init) {
            println("SDL_Init Error: ${SDL_h_3.SDL_GetError()}")
            return
        }

        val windowPtr = it.allocate(C_POINTER)
        val rendererPtr = it.allocate(C_POINTER)

        SDL_CreateWindowAndRenderer(it.allocateFrom("Hello World"), 640, 480, 0, windowPtr, rendererPtr)

        val window = windowPtr.get(C_POINTER, 0)
        val renderer = rendererPtr.get(C_POINTER, 0)

        val rect = SDL_FRect.allocate(it)
        SDL_FRect.x(rect, 100f)
        SDL_FRect.y(rect, 100f)
        SDL_FRect.w(rect, 440f)
        SDL_FRect.h(rect, 280f)


        val event = SDL_Event.allocate(it)
        var quit = false
        while (!quit) {
            while (SDL_PollEvent(event)) {
                when (SDL_Event.type(event)) {
                    SDL_EVENT_QUIT() -> {
                        quit = true
                    }

                    SDL_EVENT_KEY_DOWN() -> {
                        when (SDL_KeyboardEvent.key(SDL_Event.key(event))) {
                            SDLK_UP() -> {
                                SDL_FRect.y(rect, SDL_FRect.y(rect) - 5)
                            }

                            SDLK_DOWN() -> {
                                SDL_FRect.y(rect, SDL_FRect.y(rect) + 5)
                            }

                            SDLK_LEFT() -> {
                                SDL_FRect.x(rect, SDL_FRect.x(rect) - 5)
                            }

                            SDLK_RIGHT() -> {
                                SDL_FRect.x(rect, SDL_FRect.x(rect) + 5)
                            }
                        }
                    }
                }
            }

            SDL_h_2.SDL_SetRenderDrawColor(renderer, 33.toByte(), 33.toByte(), 33.toByte(), 255.toByte())
            SDL_h_2.SDL_RenderClear(renderer)

            SDL_h_2.SDL_SetRenderDrawColor(renderer, 0.toByte(), 0.toByte(), 255.toByte(), 255.toByte())

            SDL_h_2.SDL_RenderFillRect(renderer, rect)

            SDL_h_2.SDL_RenderPresent(renderer)
        }

        SDL_h_2.SDL_DestroyRenderer(renderer)
        SDL_h_3.SDL_DestroyWindow(window)
    }
}

首先这里创建了一个窗口和渲染器,还渲染了一个矩形。之后做了事件处理,关闭的时候跳出循环,之后销毁窗口和渲染器。按下键盘上下左右键可以移动矩形。

之后调用./gradlew run就可以运行程序了。

相关推荐
IT 行者2 小时前
Web逆向工程AI工具:JSHook MCP,80+专业工具让Claude变JS逆向大师
开发语言·javascript·ecmascript·逆向
程序员 沐阳4 小时前
JavaScript 内存与引用:深究深浅拷贝、垃圾回收与 WeakMap/WeakSet
开发语言·javascript·ecmascript
pshdhx_albert4 小时前
AI agent实现打字机效果
java·http·ai编程
Mr_Xuhhh4 小时前
Java泛型进阶:从基础到高级特性完全指南
开发语言·windows·python
沉鱼.444 小时前
第十二届题目
java·前端·算法
He1955015 小时前
wordpress搭建块
开发语言·wordpress·古腾堡·wordpress块
老天文学家了5 小时前
蓝桥杯备战Python
开发语言·python
赫瑞5 小时前
数据结构中的排列组合 —— Java实现
java·开发语言·数据结构
初夏睡觉6 小时前
c++1.3(变量与常量,简单数学运算详解),草稿公放
开发语言·c++
升职佳兴6 小时前
C盘爆满自救:3步无损迁移应用数据到E盘(含回滚)
c语言·开发语言