Solar2D Native — iOS

以下资源将更深入地介绍如何在 iOS 上使用 Solar2D Native。

Solar2D Native 设置

以下步骤将帮助您设置您的原生开发环境,使其针对与 Solar2D Native 的集成进行优化。

  1. /Applications/Corona/Native/ 文件夹中,双击 **Setup Corona Native**。这将创建项目模板所需的符号链接。

  2. 要开发原生 iOS 应用程序,您需要安装 Xcode,可从 Mac App Store 或直接下载。如果您已经安装了 Xcode,请确保您已更新到最新版本。

  3. 您必须拥有一个 Apple 开发者 帐户才能在 iOS 设备上安装/测试应用程序并发布到 App Store。建立帐户后,您需要将其与 Xcode 集成。此过程概述 此处

  4. 如果您的 iOS 开发环境正常工作,您应该能够构建一个原生 iOS 示例项目,例如 MyLife。此外,您应该能够 部署并运行 设备上的示例。

项目模板

使用模板文件作为起点可以轻松创建新项目。在/Applications/Corona/Native/Project Template/App/文件夹中,以下文件/目录是主要关注点

  • Corona — 此文件夹代表一个经典的 Corona 项目,包含 main.lua、应用程序图标等文件。默认情况下,ios/App.xcodeproj 设置为假设这些文件位于此确切文件夹 (Corona) 内。
  • ios — 包含所有iOS 特定代码、项目等。
    • App.xcodeproj — 这是在 Xcode 中构建和运行应用程序的主要项目。我们建议您使用此项目模板作为 Xcode 项目的起点,因为它包含自定义构建阶段,负责打包 Lua 源代码和资源文件(图像、音频等)。它还允许您将原生扩展构建为 插件,以便在重复使用在未来的项目中。
    • AppCoronaDelegate.h / AppCoronaDelegate.mm — 主要应用程序入口点位于此处。该类符合 CoronaDelegate 协议,因此您将在加载和执行 main.lua 之前和之后立即收到通知。您还可以添加 UIApplicationDelegate 方法。我们建议您通过插件添加新的 Lua 库。
    • Plugin/ — 对于 插件,这是 plugin.library 的实现所在的位置。
      • PluginLibrary.h / PluginLibrary.mm — 这些实现了 plugin.library
    • Plugin.xcodeproj — 对于 插件,这是包含您要向应用程序公开的 Lua 库的主要项目。这是 App.xcodeproj 的依赖项,因此它将自动构建。只有当您想单独构建插件时才需要打开此项目。
    • CoronaNative.xcconfig — 包含 Solar2D Native 的通用设置元素的配置文件(Corona 和 Lua 头文件、库和链接器选项的路径)。
    • CoronaApp.xcconfig — 构建“下载插件”目标时生成的配置文件。此配置可能包含使用 build.settings 中指定的插件所需的信息。它还包括 CoronaNative.xcconfig
项目流程

以下步骤简要概述了/Applications/Corona/Native/Project Template/App/iOS 项目

  1. ios/main.mm — 在启动时,MyCoronaDelegate 注册为实现 CoronaDelegate 接口的类。 Corona 将实例化此类的一个实例,并假定指定的初始化程序是 init

  2. ios/AppCoronaDelegate.mm — 在调用 Corona/main.lua 之前,将调用 willLoadMain 方法。此时,OpenGL 已设置完毕,所有 Corona 框架均可用。

  3. Corona/main.lua — 在 Lua 代码中,plugin.library 通过 require() 加载。然后,Corona 引擎将查找名为 luaopen_plugin_library 的相应 C 函数并调用它。此函数的名称是动态的,使用传递给 require() 的原始库名称构造。它采用该名称并添加前缀 luaopen_,然后将 . 替换为 _

  4. ios/Plugin/PluginLibrary.mm — 调用 luaopen_plugin_library 时,它会调用 PluginLibrary::Open,该函数完成所有繁重的工作,例如创建 Lua 库表、注册 show() 等 Lua 方法,然后将表留在 Lua 栈的顶部。

Solar2D Native 开发

Lua/C 桥接

要桥接 Lua 和 C 代码,您将使用 Lua C API 提供的功能。这允许您在 Lua 中添加直接调用 C 的库和函数。

Lua C API 中的每个函数都将 lua_State 指针 L 作为其第一个参数。您可以通过 CoronaRuntime 的实例访问正确的 lua_State 变量。

为了成功使用 Lua C API,您必须了解 Lua 栈。此堆栈不同于函数调用堆栈;它旨在简化跨Lua-C桥的数据封送。有关详细信息,请参阅此处

原生 API

以下内容特定于适用于 iOS 的 Solar2D Native

原生 API 描述
CoronaDelegate 如果您希望在 Lua 层添加自己的函数,则您的代码**必须**实现此协议。您还可以通过实现此协议来拦截 UIApplicationDelegate 事件。
CoronaRuntime 可以通过此协议访问 Corona 引擎使用的 Lua 状态等关键对象。 Corona 引擎通过 CoronaDelegate 为您提供对此的访问权限。
CoronaLuaIOS.h 包含其他函数,可帮助您在 Lua 和原生之间架起桥梁Obj-C代码。这是为了补充跨平台函数集 CoronaLua.h
Corona C 函数 这是 Corona 引擎提供的一组 C 函数,可帮助您与 Lua 交互以实现Corona 特定模式,例如调度事件。

使用插件

有关如何在 Solar2D Native 项目中获取和包含 Corona 插件的说明,请参阅 在 Solar2D Native — iOS 中使用插件 指南。

设置方向

要在 iOS 上使用 Solar2D Native 时将 Corona 限制为特定方向,您可以在项目的 build.settings 中使用 orientation 表。有关更多详细信息,请参阅 项目构建设置

或者,您可以编辑 Info.plist 文件(模板应用程序中的 App-Info.plist)并添加一个 CoronaViewSupportedInterfaceOrientations 数组,其选项类似于 UISupportedInterfaceOrientations。例如,要启用所有方向

<key>CoronaViewSupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>

向运行时发送事件

Corona 中的所有事件都是 Lua 表。为了将事件发送到全局 Runtime 对象,我们在 CoronaLua.h 中添加了一个名为 CoronaLuaRuntimeDispatchEvent() 的便捷实用程序函数。

在以下 Lua 代码中,我们创建了一个类型为 "delegate" 的自定义事件。为了让 Corona 将事件识别为 Lua 表,Lua 表的 name 属性必须设置为事件的类型

local event = { name="delegate" }
Runtime:dispatchEvent( event )

然后,我们将此调用转换为原生代码,并在 CoronaDelegatedidLoadMain 方法中发送事件

@implementation MyCoronaDelegate

- (void)didLoadMain:(id<CoronaRuntime>)runtime
{
    lua_State *L = runtime.L;

    // DISPATCH CUSTOM EVENT
    // Create 'delegate' event
    const char kNameKey[] = "name";
    const char kValueKey[] = "delegate";
    lua_newtable( L );
    lua_pushstring( L, kValueKey );     // All events are Lua tables
    lua_setfield( L, -2, kNameKey );    // that have a 'name' property

    Corona::Lua::RuntimeDispatchEvent( L, -1 );
}

@end

注册自定义库

如果要在 Lua 中添加自己的包装原生 C 代码的库,则应遵循 插件 指南的 原生 C 部分中描述的标准 Lua 约定。

自定义 Lua 错误处理

您可以通过调用 CoronaLuaSetErrorHandler() 来注册自定义 Lua 错误处理程序。您的处理程序将覆盖 Corona 的内部默认错误处理程序,并且在运行时发生 Lua 错误时都会调用它。

static int MyTraceback( lua_State *L )
{
    lua_getfield(L, LUA_GLOBALSINDEX, "debug");
    if (!lua_istable(L, -1)) {
        lua_pop(L, 1);
        return 1;
    }
    lua_getfield(L, -1, "traceback");
    if (!lua_isfunction(L, -1)) {
        lua_pop(L, 2);
        return 1;
    }
    lua_pushvalue(L, 1);  // pass error message
    lua_pushinteger(L, 1);  // skip this function and traceback
    lua_call(L, 2, 1);  // call debug.traceback

    // Log result of calling debug.traceback()
    NSLog( @"[LUA ERROR]: %s", lua_tostring( L, -1 ) );

    return 1;
}

@implementation MyCoronaDelegate
- (void)willLoadMain:(id<CoronaRuntime>)runtime
{
    Corona::Lua::SetErrorHandler( MyTraceback );
}
@end

OpenGL 上下文不匹配

许多使用 OpenGL 的第三方图形库将使用其自己的 OpenGL 上下文。但是,Corona 在主线程上执行其渲染,并且不希望 OpenGL 上下文发生更改。因此,如果您使用某些图形库,您可能会无意中更改 OpenGL 上下文,这可能会导致 Corona 渲染/更新出现问题。

为了确保您的代码正确处理 OpenGL,您应确保 OpenGL 上下文更改“平衡”,如下所示

// 1. Save Corona context
EAGLContext *context = nil;
context = [EAGLContext currentContext];

// 2. Call third-party library

// 3. Restore Corona context
[EAGLContext setCurrentContext:context];

例如,如果第三方库的界面通过模态视图控制器显示,您将在 presentViewController:animated:completion: 调用中执行步骤 1 和 2,然后在 dismissViewControllerAnimated:completion: 调用中执行步骤 3。

构建设备版本

要从 Xcode 构建 Solar2D Native 项目,请遵循 Apple 的 此处 的指南。