Swift 5.6CircleCI

InkSwift

Ink叙事脚本语言的Swift封装。基于InkJS。

支持的特性

Linux安装

Linux上的JXKit需要JavaScriptCore库,它是WebKit的一部分。 对于Ubuntu 20.04及更高版本:sudo apt install libwebkit2gtk-4.0-dev

局限性

入门指南

常规的XCode项目

使用“File”->“Swift Packages”->“Add Package Dependency...”将软件包添加到您的项目。

使用SwiftPM

将InkSwift作为依赖项添加到 Package.swift

let package = Package(
    name: "test_swiftpm",   // choose your own name
    platforms: [
        .macOS(.v10_15),
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
        .package(url: "https://github.com/maartene/InkSwift.git", from: "2.0.0")
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "test_swiftpm",
            dependencies: ["InkSwift"]),
        .testTarget(
            name: "test_swiftpmTests",
            dependencies: ["test_swiftpm"]),
    ]
)

用法

首先创建一个InkStory

let story = InkStory()

然后从Ink JSON加载故事(您可以使用InklecateInky 将 .ink 文件转换为 .json 文件。)

let storyJSON = ... //
story.loadStory(json: storyJSON)

或者,您可以直接从Ink加载故事。 但是请注意,这可能会降低用户的性能。

story.loadStory(ink: "Hello, World!")

您只需几行代码即可创建一个非常基本的命令行“播放器”

// As long as the story can continue (either because there is more text or there are options you can choose)), keep the loop going
while story.canContinue || story.options.count > 0 {
    // Print the current text to the console/terminal
    print(story.currentText)

    // If you can continue the story, we wait for input before continuing.
    if story.canContinue {
        print("Press 'enter' to continue")
        _ = readLine()
        story.continueStory()
    }
    // If there are options, show the options and wait for player to choose
    else if story.options.count > 0 {
        // print every option
        for option in story.options {
            print("\(option.index). \(option.text)")
        }
        print("What is your choice?")

        // wait for input from player
        if let choice = readLine() {
            // try and convert input to an index.
            if let index = Int(String(choice.first ?? "a")) {
                // choose the selected option index
                story.chooseChoiceIndex(index)
            }
        }
    }
}
// no more content, story is done.
print("Story done!")

使用Combine/SwiftUI

InkStory符合 ObservableObject 协议。 这使得可以在Combine中使用它,并且SwiftUI非常容易。 一个简单的SwiftUI视图,可以播放Ink故事,将包含

导入InkSwift包

添加

import InkSwift

到ContentView.swift

Ink故事作为@StateObject

将以下属性添加到您的ContentView: @StateObject var story = InkStory()

添加一个加载Ink故事的函数

注意:将要加载的文件名更改为您自己的JSON文件。 不要忘记将其添加到项目中。

func loadStory() {
guard let url = Bundle.main.url(forResource: "test.ink", withExtension: "json") else {
    fatalError("Could not find ink story file.")
}

guard let storyJSON = try? String(contentsOf: url) else {
    fatalError("Could not load story file.")
}

story.loadStory(json: storyJSON)
}

创建body属性

var body: some View {
    VStack {
        Text(story.currentText)
        if story.canContinue {
            Button("Continue") {
                story.continueStory()
            }
        }
        ForEach(story.options, id: \.index) { option in
            Button(option.text) {
                story.chooseChoiceIndex(option.index)
            }
        }
    }.padding()
    .onAppear {
        loadStory()
    }
}

贡献者

授权内容