
ECSに基づいた2Dゲームエンジン、iOS、MacOS、TVOS、Visionosの100%Swiftで書かれています。
注意
?このプロジェクトは、唯一のメンテナーによって更新されなくなりました。
?私はゴドットに引っ越しました。 Godotの2DゲームのコンポーネントベースのフレームワークをComedot←チェックしてください!
重要
octopuskitにはOctopuscoreが必要です。ゲーム以外の機能は、一般的なアプリで使用するために別のリポジトリに分割されました。最後のスタンドアロンバージョンについては、4.0.0-Beta-5を参照してください
公式のAPIに固執している間にSwiftでゲームを作ってみた場合、これはあなたのためかもしれません! Octopuskitは、Appleのフレームワークをラップして拡張します。
•ゲームの動作を動的に構成するための柔軟なエンティティコンポーネントシステムアーキテクチャのゲームプレイキット。
•2Dグラフィックス、物理学、GPUシェーダー用のSpriteKit 。
• Swiftuiは、宣言的な構文を備えた液体のスケーラブルなHUDを迅速に設計するための。
•フードの下で最高のネイティブパフォーマンスを確保するための金属。
•OS非依存コンポーネントを使用すると、同じコードを使用してマウス/タッチまたはキーボード/ゲームパッド入力を処理し、触媒を必要とせずにiOS + macOS用にネイティブにコンパイルします。

Octopuskitは進行中の絶え間ない作業であり、私はまだ私が行くように学んでいるので、後方の互換性を維持したり、ドキュメントを更新したりせずに急速に変化する可能性があります。
このプロジェクトは、純粋なスウィフトでゲームを作ろうとする私の試みの結果です。私は言語に恋をしましたが、それをサポートしているエンジンや、直感的だと感じたようなアーキテクチャを持っていたエンジンを見つけることができなかったので、自分で作り始めました。
フィードバックようこそ! - Shinryakutako
飛び込みたいですか? SwiftUIプロジェクトへのSwift Package Managerの依存関係としてOctopuskitを追加し、 QuickStartテンプレートを使用します(これも少しデモとして機能します)。
? Swiftuiで使用します
import SwiftUI
import OctopusKit
struct ContentView : View {
// The coordinator object manages your game's scenes and global state.
@ StateObject var gameCoordinator = OKGameCoordinator ( states : [
MainMenu ( ) ,
Lobby ( ) ,
Gameplay ( ) ] )
var body : some View {
// The container view combines SpriteKit with SwiftUI,
// and presents the coordinator's current scene.
OKContainerView ( )
. environmentObject ( gameCoordinator )
. statusBar ( hidden : true )
}
}?アニメーションスプライトを作成します
var character = OKEntity ( components : [
// Start with a blank texture.
NodeComponent ( node : SKSpriteNode ( color : . clear , size : CGSize ( widthAndHeight : 42 ) ) ) ,
// Load texture resources.
TextureDictionaryComponent ( atlasName : " PlayerCharacter " ) ,
// Animate the sprite with textures whose names begin with the specified prefix.
TextureAnimationComponent ( initialAnimationTexturePrefix : " Idle " ) ] )?プレーヤーコントロールの追加
// Add a component to the scene that will be updated with input events.
// Other components that handle player input will query this component.
// This lets us handle asynchronous events in sync with the frame-update cycle.
// A shared event stream is more efficient than forwarding events to every entity.
// PointerEventComponent is an OS-agnostic component for touch or mouse input.
let sharedPointerEventComponent = PointerEventComponent ( )
scene . entity ? . addComponent ( sharedPointerEventComponent )
character . addComponents ( [
// A relay component adds a reference to a component from another entity,
// and also fulfills the dependencies of other components in this entity.
RelayComponent ( for : sharedPointerEventComponent ) ,
// This component checks the entity's PointerEventComponent (provided here by a relay)
// and syncs the entity's position to the touch or mouse location in every frame.
PointerControlledPositioningComponent ( ) ] )?プレーヤーのコントロールを動的に削除したり、別の入力方法に変更したりする
character . removeComponent ( ofType : PointerControlledPositioningComponent . self )
character . addComponents ( [
// Add a physics body to the sprite.
PhysicsComponent ( ) ,
RelayComponent ( for : sharedKeyboardEventComponent ) ,
// Apply a force to the body based on keyboard input in each frame.
KeyboardControlledForceComponent ( ) ] )?カスタムゲーム固有のコンポーネント
class AngryEnemyComponent : OKComponent , RequiresUpdatesPerFrame {
override func didAddToEntity ( withNode node : SKNode ) {
node . colorTint = . angryMonster
}
override func update ( deltaTime seconds : TimeInterval ) {
guard let behaviorComponent = coComponent ( EnemyBehaviorComponent . self ) else { return }
behaviorComponent . regenerateHP ( )
behaviorComponent . chasePlayerWithExtraFervor ( )
}
override func willRemoveFromEntity ( withNode node : SKNode ) {
node . colorTint = . mildlyInconveniencedMonster
}
}?カスタムクロージャーを使用して、プレーヤーの動きに基づいてアニメーションを変更する
// Add a component that executes the supplied closure every frame.
character . addComponent ( RepeatingClosureComponent { component in
// Check if the entity of this component has the required dependencies at runtime.
// This approach allows dynamic behavior modification instead of halting the game.
if let physicsBody = component . coComponent ( PhysicsComponent . self ) ? . physicsBody ,
let animationComponent = component . coComponent ( TextureAnimationComponent . self )
{
// Change the animation depending on whether the body is stationary or mobile.
animationComponent . textureDictionaryPrefix = physicsBody . isResting ? " Idle " : " Moving "
}
} )
// This behavior could be better encapsulated in a custom component,
// with many different game-specific animations depending on many conditions.? Xcodeシーンエディターに組み込まれたシーンを読み込み、共有名で識別されたスプライトから複数のエンティティを作成する
// Load a ".sks" file as a child node.
if let editorScene = SKReferenceNode ( fileNamed : " EditorScene.sks " ) {
scene . addChild ( editorScene )
}
// Search the entire tree for all nodes named "Turret",
// and give them properties of "tower defense" turrets,
// and make them independently draggable by the player.
for turretNode in scene [ " //Turret " ] {
// Create a new entity for each node found.
scene . addEntity ( OKEntity ( components : [
NodeComponent ( node : turretNode ) ,
RelayComponent ( for : sharedPointerEventComponent ) ,
// Hypothetical game-specific components.
HealthComponent ( ) ,
AttackComponent ( ) ,
MonsterTargetingComponent ( ) ,
// Track the first touch or mouse drag that begins inside the sprite.
NodePointerStateComponent ( ) ,
// Let the player select and drag a specific sprite.
// This differs from the PointerControlledPositioningComponent in a previous example,
// which repositions nodes regardless of where the pointer began.
PointerControlledDraggingComponent ( ) ] ) )
}
// Once the first monster wave starts, you could replace PointerControlledDraggingComponent
// with PointerControlledShootingComponent to make the turrets immovable but manually-fired.Octopuskitは「エンティティコンポーネントシステム」アーキテクチャを使用します。
?ゲームは、 Mainmenu 、 Playing 、 Deauseなどの州に編成されています。各状態は、ユーザーインターフェイスを表示するSwiftUIビューと、エンティティ、コンポーネント、システムを使用してその状態のゲームプレイを提示するSpriteKitシーンに関連付けられています。
ゲームを必要なだけ多くまたは少数の状態に分割できます。たとえば、メインメニュー、一時停止、カットシーンなどを処理する単一の「PlayState」。
州、シーン、およびスウィフトゥイビューには、ランタイム中に変化する可能性のある多くの関係がある場合があります。
?エンティティは、単にコンポーネントのコレクションです。関連するコンポーネントのグループを初期化する便利なコンストラクターを除いて、これらにはロジックが含まれていません。
?コンポーネント(動作、効果、機能、または特性とも呼ばれることもあります)は、ゲームの各視覚または抽象要素を構成するロジック*を含むOctopuskitのコアコンセプトです。コンポーネントは、エンティティに追加されたとき、フレームが更新されたとき、および/またはエンティティから削除されたときにコードを実行します。コンポーネントは、他のコンポーネントのエンティティを照会し、互いの動作に影響を与え、ランタイム中に動的依存関係を形成する場合があります。エンジンには、グラフィック、ゲームプレイ、物理学などのカスタマイズ可能なコンポーネントのライブラリが付属しています。
⛓システムは、特定のクラスのコンポーネントの単純なコレクションです。ロジック*は実行されませんが、すべてのエンティティのコンポーネントをすべてのフレームで実行するためにシーンによって配置されているため、他のコンポーネントに依存するコンポーネントが依存関係の後に更新されます。
*これらの定義は、すべてのロジックがシステム内に含まれているUnityなど、他のエンジンとは異なる場合があります。
?ボタン、リスト、HUDなどのユーザーインターフェイス要素は、 SwiftUIで設計されています。これにより、流動的なアニメーション、シャープなテキスト、ベクトル形状、ライブプレビュー、自動データ駆動型の更新、およびAppleのSFシンボルから1,500を超える高品質のアイコンが可能になります。
オブジェクト階層の詳細な内訳については、アーキテクチャのドキュメントを参照してください。
主なワークフローは、グラフィックとゲームプレイの各「部分」のコンポーネントクラスを作成し、それらを組み合わせて画面に表示されるエンティティまたは「バックエンド」のデータを処理する抽象エンティティを構築することです。
たとえば、 CloudSComponent 、 HillsComponent 、 TreesComponent 、またはWorldMapComponentとMultiplayersYnccomponentを含むゲームセッション性を含む視差の根拠を告げる。
パフォーマンス:大規模なベンチマークはまだ行われていませんが、OKはiPhone XSに5000を超えるスプライトを1秒あたり60フレームで表示できます。複数のコンポーネントがすべてのフレームを更新され、タッチ入力に応答するエンティティで表される各スプライト。
Swiftに合わせて調整:Swift、Swift、Swift!フレームワークは、Swift API設計のための確立されたガイドラインに従う必要があります。 Swift内ですべてが意味をなす必要があり、Swift Idiomsを可能な限りシームレスに流れます。
ビタミン2D :現時点では、OKは主に2Dゲームのフレームワークですが、SceneKitや低レベルのメタルビューなどのテクノロジーを使用することを妨げず、ゲーム以外のアプリに使用できます。
エティンの肩:エンジンは、SpriteKit、GamePlaykit、Swiftui、およびAppleが提供するその他の技術を活用しています。それらを「戦う」、交換したり、あまりにも多くの抽象化の後ろに隠そうとしないでください。
OKは、主にスプライトキットとゲームプレイキットクラスのカスタムサブクラスと拡張機能を通じて実装されており、それらを「曖昧に」したり、基本クラスとのやり取りをブロックしたりすることはありません。これにより、このフレームワークを段階的に採用することができ、可能な場合はシーンエディターなどのXcode IDEツールとゲームを統合できます。
Apple APIとの緊密な結合により、ゲームが将来的に根付いていることも保証されます。 Appleがこれらのフレームワークを改善するたびに、Octopuskitとゲームも「無料で」いくつかの利点をもたらすはずです。たとえば、Metalが導入されたときに、SpriteKitが更新され、フードの下でOpenGLの代わりにMetalを自動的に使用して、多くの既存のゲームにパフォーマンスが向上しました。 (WWDC 2016、セッション610)
コードが最初に来ます:OKは主に「プログラム」エンジンです。ほとんどすべてがコードで行われます。これは、ソース制御にも役立ちます。 Xcodeシーンのエディターは、その不完全性とバグ(2018年5月の時点でXcode 9.4)のために「セカンドクラスの市民」のステータスに追いやられますが、便利な場所にサポートされています。次のポイントを参照してください。
シーンエディターで高レベルのレイアウト/モックアップを設計できます。名前を付けたプレースホルダーノードを使用して(識別子)。それらのノードからエンティティを作成し、コードでコンポーネントを追加できます。
現在、Swiftuiを使用すると、Apple Platformsのプログラミングは、とにかくビジュアルエディターではなく、コードに焦点を当てています。
カスタマイズ性と柔軟性:エンジンは柔軟性を築くよう努め、さまざまな方法でゲームを構成する自由を提供します。エンジンのソースコードに完全にアクセスできるため、各プロジェクトの正確なニーズに合わせて何かを変更または拡張できます。
エンジンサポートの順に、シーンを構築するために、次のアプローチのいずれかを使用できます。
- 主にコードでノードの作成と配置を実行します。 Xcodeシーンエディターを使用して、シーン全体ではなく特定のポジションなどのエンティティなどのいくつかの個別の要素を設計およびプレビューし、
SKReferenceNode使用してコードにロードします。
- Xcodeシーンエディターを出発点として使用して、
OKSceneのトップレベルのSKReferenceNodeインスタンスとしてロードされる可能性のあるテンプレートシーンを作成します。このアプローチにより、「wysiwyg」の視覚的なデザインとプレビューのわずかなものが可能になります。
- Xcodeシーンエディターでほぼ完全にシーンを作成し、サポートされているコンポーネント、アクション、物理学、ナビゲーショングラフ、テクスチャなどをIDEに追加します。
シーンのカスタムクラスをOKSceneまたはそのサブクラスとして設定します。OKViewController.loadAndPresentScene(fileNamed:withTransition:)、たとえばdidEnter.from(_:)OKGameStateのイベント)を呼び出してシーンを読み込みます。
- ここで提案されているアーキテクチャやパターンを使用する必要はありません。ゲーム状態を使用する必要はなく、ゲームオブジェクトはOKクラスから継承する必要さえありません。独自のアーキテクチャを使用し、いくつかのヘルパーメソッドなどにOKを使用して、このフレームワークから必要なもののみを保持し、残りをコンパイルから除外することができます。
自己受胎:あなた自身のプロジェクトがそれらを必要としない場合、他のサードパーティライブラリをダウンロードしたり追いかけたりする必要はありません。 OKが使用するものはすべてOKまたはAppleフレームワーク内にあるため、すぐに使用できるようになります。
QuickStartと使用ガイドを読んでください。 Xcode 12、iOS 14、およびMacos Big Surが必要になります(ただし、手動で変更された古いバージョンで動作する場合があります。)
スキルレベル:中級:OKは、絶対的な初心者向けに設計された形式では表示されません。これは、主にステップゼロからドキュメントを書くのが面倒すぎるため、「高度な」レベルのものではありません。 Swift Language Bookを読んで、XcodeでSpriteKitゲームを作成しようとした場合は、OKを使用する準備ができています。
また、これらの概念にまだ精通していない場合は、「継承に対する構成」および「エンティティ - コンポーネント - システム」パターンについても読む必要がありますが、OKの実装は予想とは異なる場合があります。
SwiftuiのAppleのチュートリアルもご覧ください。
エンジンのアーキテクチャの詳細な概要については、アーキテクチャを参照してください。
立ち往生?ヒントとトラブルシューティングを参照してください。
何かが意図的にそのように行われたのか、それともなぜですか?コーディングコンベンションと設計上の決定には説明があるかもしれません。
何が来るのか、または不足している機能の開発を手伝ってくれるものを監視したいですか? Todo&Roadmapを参照してください。
貢献者とサポーター❤︎
このプロジェクトは、octopuskit、「OK」または「okio」(「タコに侵入してタコ」の場合)と呼ばれる場合がありますが、「iook」は奇妙に聞こえます。
命名は、Rogue Amoeba、The .io Domain、Anime Shinryakuなどの企業からのインスピレーションの組み合わせです! Ika Musume 。
最後のスペース])セクションのセクションは明確にします。 :)
ライセンス:Apache 2.0
Shaderkitのシェーダーが組み込まれています©Paul Hudson、MITライセンスに基づいてライセンスされています(関連するファイルのヘッダーを参照)。
すべてがどれほど素晴らしいか、ひどいことを教えてください:Discord、Twitter、または?ctopus?it@?nvading?ctopus.ⓘⓞ
ただし、これらをチェックすることはめったにないため、質問をする最良の方法は、GitHubリポジトリに問題を開くことである可能性があります。
私の退廃的なライフスタイルをサポートして、私は販売不可能なものを作ることに集中できる:私のパトレオン
このプロジェクトは、Appleとどのような方法でも提携していません。
Octopuskit©2023侵略Octopus•Apacheライセンス2.0