
EC를 기반으로하고 iOS, MacOS, TVOS 및 VisionOS에 대해 100% 신속하게 작성된 2D 게임 엔진.
주의
? 이 프로젝트는 더 이상 단독 관리자에 의해 업데이트되지 않습니다.
? 나는 Godot으로 이사했습니다. Comedot ← Godot에서 2D 게임에 대한 내 구성 요소 기반 프레임 워크를 확인하십시오 !
중요한
octopuskit에는 옥토 푸스 코어가 필요합니다. 비 게임 기능은 일반 앱에서 사용하기 위해 별도의 저장소로 분할되었습니다. 마지막 독립형 버전은 4.0.0-Beta-5를 참조하십시오
공식 API를 고수하면서 Swift에서 게임을 만들려고했다면 이것이 당신을위한 것일 수 있습니다! 낙지는 Apple의 프레임 워크를 감싸고 확장합니다.
• 유연한 엔티티 구성 요소 시스템 아키텍처를위한 GamePlayKit 게임 동작을 동적으로 구성합니다.
• 2D 그래픽, 물리 및 GPU 셰이더 용 Spritekit .
• 선언문 구문으로 유체, 확장 가능한 허드를 빠르게 설계하기위한 Swiftui .
• 후드 아래에서 최고의 기본 성능을 보장하기위한 금속 .
• OS 독립적 구성 요소를 사용하면 동일한 코드로 마우스/터치 또는 키보드/게임 패드 입력을 처리하고 촉매가 필요하지 않고 iOS + MacOS에 기본적으로 컴파일 할 수 있습니다.

Octopuskit은 끊임없이 진행중인 작업 이며 여전히 배우면서 배우고 있으므로 거꾸로 호환성을 유지하거나 문서를 업데이트하지 않고 빠르게 변경 될 수 있습니다.
이 프로젝트는 순수한 신속하게 게임을 만들려고 시도한 결과입니다. 나는 언어를 좋아했지만 그것을 지원하거나 직관적 인 건축물을 가진 엔진을 찾을 수 없었기 때문에 직접 만들기 시작했습니다.
피드백을 환영합니다! - Shinryakutako
다이빙을 열망합니까? Swiftui 프로젝트에 Swift 패키지 관리자 종속성으로 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은 "Entity Component-System"아키텍처를 사용합니다.
? 게임은 Mainmenu , Play and Saused 와 같은 상태 로 구성됩니다. 각 상태는 사용자 인터페이스를 표시하는 Swiftui 보기 및 엔티티 , 구성 요소 및 시스템을 사용하여 해당 상태의 게임 플레이를 제공하는 SpriteKit 장면 과 관련이 있습니다.
게임을 원하는만큼 또는 소수의 상태로 나눌 수 있습니다. 예를 들어 메인 메뉴, 일시 정지, 컷씬 등을 처리하는 단일 "Playstate".
상태, 장면 및 Swiftui보기에는 런타임 중에 변경 될 수있는 다수의 관계가있을 수 있습니다.
? 엔티티 는 단순히 구성 요소 의 컬렉션입니다. 관련 구성 요소 그룹을 초기화하는 편의 생성자를 제외하고는 논리가 포함되어 있지 않습니다.
? 구성 요소 (행동, 효과, 특징 또는 특성이라고도 함)는 옥토 포스 스키트의 핵심 개념이며, 속성과 게임의 각 시각적 또는 추상 요소를 구성하는 논리*를 포함합니다. 구성 요소는 엔티티에 추가 될 때, 프레임이 업데이트 될 때 및/또는 엔티티에서 제거 될 때 코드를 실행합니다. 구성 요소는 다른 구성 요소에 대한 엔터티를 쿼리하고 런타임 중에 동적 종속성을 형성하기 위해 서로의 동작에 영향을 줄 수 있습니다. 엔진에는 그래픽, 게임 플레이, 물리학 등 사용자 정의 가능한 구성 요소 라이브러리가 제공됩니다.
systems 시스템은 단순히 특정 클래스의 구성 요소 모음입니다. 그들은 논리를 수행하지 않지만 배열의 장면 에 의해 모든 프레임의 결정 론적 순서로 모든 엔티티의 구성 요소를 실행하여 다른 구성 요소에 의존하는 구성 요소가 종속성 후에 업데이트됩니다.
* 이러한 정의는 모든 논리가 시스템 내에 포함 된 Unity와 같은 다른 엔진과 다를 수 있습니다.
? 버튼, 목록 및 HUD와 같은 사용자 인터페이스 요소는 Swiftui 로 설계되었습니다. 이를 통해 유체 애니메이션, 날카로운 텍스트, 벡터 모양, 라이브 미리보기, 자동 데이터 중심 업데이트 및 Apple의 SF 기호의 1,500 개 이상의 고품질 아이콘이 가능합니다.
객체 계층 구조의 자세한 분석은 아키텍처 문서를 참조하십시오.
기본 워크 플로우는 그래픽 및 게임 플레이의 각 "부품"에 대한 구성 요소 클래스를 작성한 다음이를 결합하여 화면에 표시되는 엔티티 또는 "백엔드"의 데이터를 처리하는 초록 엔티티를 작성하는 것입니다.
예를 들어, 구름을 앓고있는 시차원 , 힐즈 컨택기 및 트리 컨텐츠 또는 Worldmapcomponent 및 멀티 플레이어 동기화 요소를 포함하는 GamesSessionEntity가 포함 된 시차 거절이라고 말합니다.
성능 : 광범위한 벤치 마크는 아직 수행되지 않았지만 OK는 iPhone XS에 초당 60 프레임으로 5000 개가 넘는 스프라이트를 표시 할 수 있습니다. 각 스프라이트는 엔터티로 표시되어 여러 구성 요소가 모든 프레임을 업데이트하고 터치 입력에 응답합니다.
Swift에 맞게 조정 : Swift, Swift, Swift! 프레임 워크는 Swift API 설계에 대한 확립 된 지침을 따라야합니다. 모든 것이 신속하고 신속한 관용구와 함께 원활하게 흐르고 흐르면서 모든 것이 의미가 있어야합니다.
비타민 2D : 현재 OK는 주로 2D 게임의 프레임 워크이지만 SceneKit 또는 저수준 금속 뷰와 같은 기술을 사용하지 못하며 게임이 아닌 앱에 사용될 수 있습니다.
Ettins의 어깨 : 엔진은 Spritekit, Gameplaykit, Swiftui 및 Apple이 제공하는 기타 기술을 활용합니다. 그것은 그들을 "싸우거나"교체하거나 너무 많은 추상화 뒤에 숨기려고하지 않아야합니다.
OK는 주로 SpriteKit 및 GamePlayKit 클래스의 사용자 정의 서브 클래스 및 확장을 통해 구현되며, 기본 클래스와 상호 작용하는 것을 막지 않고 SpriteKit 및 GamePlayKit 클래스의 확장을 통해 구현됩니다. 이를 통해이 프레임 워크를 점차적으로 채택 할 수 있으며 가능한 경우 장면 편집기와 같은 Xcode IDE 도구와 게임을 통합 할 수 있습니다.
Apple API와의 단단한 결합은 또한 게임이 미래에 견딜 수 있도록합니다. Apple이 이러한 프레임 워크를 개선 할 때마다 Octopuskit과 게임은 "무료로"몇 가지 이점을 얻어야합니다. 예를 들어, 금속이 도입되었을 때 Spritekit은 후드 아래에서 OpenGL 대신 금속을 자동으로 사용하도록 업데이트되어 많은 기존 게임의 성능 향상을 제공했습니다. (WWDC 2016, 세션 610)
코드는 먼저 제공됩니다 . OK는 주로 "프로그래밍 방식"엔진입니다. 거의 모든 것이 코드로 수행됩니다. 이것은 또한 소스 제어에 도움이됩니다. Xcode 장면 편집기는 불완전 성과 버그 (2018 년 5 월 현재 Xcode 9.4)로 인해 "2 급 시민"상태로 강등되지만 편리한 곳에서는 지원됩니다. 다음 요점을 참조하십시오.
이름 (식별자)이있는 자리 표시 자 노드를 사용하여 장면 편집기에서 높은 수준의 레이아웃/모형을 설계 할 수 있습니다. 그러면 해당 노드에서 엔티티를 작성하고 코드에 구성 요소를 추가 할 수 있습니다.
이제 Swiftui를 통해 Apple 플랫폼의 프로그래밍은 어쨌든 시각적 편집기 대신 코드에 중점을두고 있습니다.
사용자 정의 및 유연성 : 엔진은 유연하게 노력하고 다양한 방식으로 게임을 자유롭게 구조화 할 수 있습니다. 엔진의 소스 코드에 완전히 액세스 할 수 있으므로 각 프로젝트의 정확한 요구에 맞게 모든 것을 수정하거나 확장 할 수 있습니다.
엔진 지원 순서대로 다음 접근 방식 중 하나를 사용하여 장면 구축을 할 수 있습니다.
- 주로 코드에서 노드의 생성 및 배치를 수행하십시오. Xcode 장면 편집기를 자주 사용하여 전체 장면이 아닌 특정 위치 등이있는 엔티티와 같은 몇 가지 개별 요소를 설계하고 미리보고
SKReferenceNode사용하여 코드에로드하십시오.
- Xcode 장면 편집기를 시작점으로 사용하여
OKScene의 최상위SKReferenceNode인스턴스로로드 될 수있는 템플릿 장면을 만듭니다. 이 접근법은 "wysiwyg"비주얼 디자인 및 미리보기를 가능하게합니다.
- Xcode 장면 편집기에서 거의 전적으로 장면을 만들어 지원되는 구성 요소, 액션, 물리 본문, 내비게이션 그래프 및 텍스처 등을 바로 추가하십시오.
장면의 사용자 정의 클래스를OKScene또는 서브 클래스로 설정하십시오.OKViewController.loadAndPresentScene(fileNamed:withTransition:), 예를 들어,didEnter.from(_:)OKGameState의 이벤트를 호출하여 장면을로드하십시오.
- 여기에 제안 된 아키텍처와 패턴을 사용할 필요는 없습니다. 게임 상태를 사용할 필요가 없으며 게임 객체는 OK 클래스에서 상속받을 필요조차 없습니다. 자신의 아키텍처를 사용하고 몇 가지 헬퍼 방법 등에 확인을 사용할 수 있습니다.이 프레임 워크에서 필요한 것만 유지하고 나머지는 편집에서 제외 할 수 있습니다.
자체 포함 : 자신의 프로젝트가 필요하지 않은 경우 다른 타사 라이브러리를 다운로드하거나 따라야 할 필요가 없습니다. OK가 사용하는 모든 것은 OK 또는 Apple 프레임 워크 내에 있으므로 완전히 사용 가능한 상자가 있습니다.
QuickStart 및 Usage Guide를 읽으십시오. Xcode 12, iOS 14 및 MacOS Big Sur가 필요합니다 (OK는 일부 수동 수정으로 이전 버전에서 작동 할 수 있습니다.)
기술 수준 : 중간 : OK는 절대 초보자를 위해 설계된 양식으로 표시되지 않지만 대부분 Step Zero에서 문서를 작성하기에는 너무 게으르기 때문에 "고급"레벨 작업도 아닙니다. Swift Language Book을 읽고 Xcode에서 Spritekit 게임을 시도한 경우 OK를 사용할 준비가되었습니다!
또한 OK의 구현이 기대하는 것과 다를 수 있지만 "상속의 구성"및 "엔티티 - 컴퓨터 시스템"패턴에 대해서도 읽어야합니다.
Swiftui에 대한 Apple의 자습서도 참조하십시오.
엔진 아키텍처에 대한 자세한 개요는 아키텍처를 참조하십시오.
갇힌? 팁 및 문제 해결을 참조하십시오.
무언가가 의도적으로 그대로 이루어 졌는지 궁금합니다. 코딩 규칙 및 설계 결정에는 설명이있을 수 있습니다.
누락 된 기능 개발에 대한 탭을 유지하고 싶으십니까? Todo & Roadmap을 참조하십시오.
기고자 및 지지자 ❤︎
이 프로젝트는 낙지, "OK"또는 "Okio"( "Octopus를 침입하여"Octopuskit의 경우)라고 불릴 수 있지만 "iook"은 이상하게 들릴 수 있습니다.
이름 지정은 Rogue Amoeba, .io 도메인 및 Anime Shinryaku와 같은 회사의 영감의 조합입니다! Ika Musume .
예제 섹션에서 마지막 ]) 이전의 공간은 명확성입니다. :)
라이센스 : Apache 2.0
MIT 라이센스에 따라 라이센스가 부여 된 Shaderkit © Paul Hudson의 셰이더를 통합합니다 (관련 파일의 헤더 참조).
모든 것이 얼마나 굉장하거나 끔찍한 지 말 해주세요 : Discord, Twitter 또는? ctopus?it@?nvading?ctopus.
그래도 이것을 거의 확인하지 않으므로 질문을하는 가장 좋은 방법은 Github 저장소에서 문제를 열 수 있습니다.
내 퇴폐적 인 라이프 스타일을 지원하여 말할 수없는 물건을 만드는 데 집중할 수 있습니다 : 내 Patreon
이 프로젝트는 Apple과 어떤 식 으로든 제휴하지 않습니다.
낙지 © 2023 침입 낙지 • 아파치 라이센스 2.0