{"id":18473452,"url":"https://github.com/0xopenbytes/planar","last_synced_at":"2025-04-16T02:53:04.943Z","repository":{"id":147554698,"uuid":"618923655","full_name":"0xOpenBytes/Planar","owner":"0xOpenBytes","description":"👾 Build 2D games and simulations in Swift using SpriteKit","archived":false,"fork":false,"pushed_at":"2023-05-18T23:02:38.000Z","size":18,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-29T04:25:48.913Z","etag":null,"topics":["2d","game","game-engine","game-engine-2d","ios","macos","spritekit","swift","tvos","watchos"],"latest_commit_sha":null,"homepage":"https://0xopenbytes.github.io/Planar/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0xOpenBytes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-25T18:35:22.000Z","updated_at":"2025-03-26T03:29:24.000Z","dependencies_parsed_at":"2023-05-31T16:30:38.832Z","dependency_job_id":null,"html_url":"https://github.com/0xOpenBytes/Planar","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FPlanar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FPlanar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FPlanar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FPlanar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xOpenBytes","download_url":"https://codeload.github.com/0xOpenBytes/Planar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249187429,"owners_count":21226906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2d","game","game-engine","game-engine-2d","ios","macos","spritekit","swift","tvos","watchos"],"created_at":"2024-11-06T10:25:03.026Z","updated_at":"2025-04-16T02:53:04.936Z","avatar_url":"https://github.com/0xOpenBytes.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Planar\n\nPlanar is a library for building 2D games and simulations in Swift using SpriteKit. It provides a set of abstractions and utilities for organizing game objects, managing tasks, and handling input events.\n\n## Usage\n\nTo use Planar, simply create a new scene and inherit from `PlanarScene`:\n\n```swift\nclass GameScene: PlanarScene\u003cGameSceneNodeKey\u003e {\n    // ...\n}\n```\n\nNext, define a set of unique node keys using an enum:\n\n```swift\nenum GameSceneNodeKey: Hashable {\n    case player(UInt)\n    case enemy(UInt)\n    case powerUp\n}\n```\n\nYou can then add nodes to the scene using the `add(node:forKey:)` method, passing in a key that matches one of your defined keys:\n\n```swift\nadd(node: playerNode, forKey: .player(0))\nadd(node: enemyNode, forKey: .enemy(0))\nadd(node: powerUpNode, forKey: .powerUp)\n```\n\nTo retrieve a node from the scene, use the `get(_:)` or `resolve(_:)` methods, passing in the appropriate key:\n\n```swift\nif let player = get(.player(0)) {\n    // Do something with the player node\n}\n```\n\nYou can also create plugins to modify properties of nodes in a type-safe way. Here's an example:\n\n```swift\nstruct PositionPlugin: Plugin {\n    var keyPath: WritableKeyPath\u003cPlanarNode, CGPoint\u003e\n\n    func handle(value: CGPoint, output: inout CGPoint) async throws {\n        output = value\n    }\n}\n\nlet playerNode = PlanarNode(node: SKSpriteNode(imageNamed: \"player\"))\nplayerNode.register(plugin: PositionPlugin(keyPath: \\.position))\n\ntry await playerNode.handle(value: CGPoint(x: 100, y: 100))\n\n```\n\nIn this example, we create a `PositionPlugin` that modifies the `position` property of a `PlanarNode`. We then create a `PlanarNode` representing a player, and use the `handle` method to apply the `PositionPlugin` to set the player's position to (100, 100).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xopenbytes%2Fplanar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xopenbytes%2Fplanar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xopenbytes%2Fplanar/lists"}