Ink叙事脚本语言的Swift封装。基于InkJS。
loadStory(json: String)
以及直接加载Ink loadStory(ink: String)
;continueStory()
和选择分支 chooseChoiceIndex(_ index: Int)
;moveToKnitStitch(_ knot: String, stitch: String? = nil)
;currentTags
变量;stateToJSON()
和 loadState(_ jsonDataString: String)
;Linux上的JXKit需要JavaScriptCore库,它是WebKit的一部分。 对于Ubuntu 20.04及更高版本:sudo apt install libwebkit2gtk-4.0-dev
使用“File”->“Swift Packages”->“Add Package Dependency...”将软件包添加到您的项目。
将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加载故事(您可以使用Inklecate 或 Inky 将 .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!")
InkStory符合 ObservableObject
协议。 这使得可以在Combine中使用它,并且SwiftUI非常容易。 一个简单的SwiftUI视图,可以播放Ink故事,将包含
添加
import InkSwift
到ContentView.swift
将以下属性添加到您的ContentView: @StateObject var story = InkStory()
注意:将要加载的文件名更改为您自己的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)
}
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()
}
}