├── .gitignore
├── .swift-version
├── .swiftlint.yml
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── Configs
├── ImagineEngine.plist
└── ImagineEngineTests.plist
├── Dangerfile
├── Documentation
├── Guides
│ ├── CustomEvents.md
│ └── README.md
├── README.md
└── Tutorials
│ ├── 1-AsteroidBlaster
│ ├── AsteroidBlaster.xcworkspace
│ │ ├── Playground.playground
│ │ │ ├── Contents.swift
│ │ │ ├── Resources
│ │ │ │ ├── Asteroid
│ │ │ │ │ └── 0@2x.png
│ │ │ │ ├── Explosion
│ │ │ │ │ ├── 0@2x.png
│ │ │ │ │ ├── 1@2x.png
│ │ │ │ │ ├── 2@2x.png
│ │ │ │ │ ├── 3@2x.png
│ │ │ │ │ ├── 4@2x.png
│ │ │ │ │ ├── 5@2x.png
│ │ │ │ │ └── 6@2x.png
│ │ │ │ ├── Ground
│ │ │ │ │ ├── bottom@2x.png
│ │ │ │ │ ├── bottomLeft@2x.png
│ │ │ │ │ ├── bottomRight@2x.png
│ │ │ │ │ ├── center@2x.png
│ │ │ │ │ ├── left@2x.png
│ │ │ │ │ ├── right@2x.png
│ │ │ │ │ ├── top@2x.png
│ │ │ │ │ ├── topLeft@2x.png
│ │ │ │ │ └── topRight@2x.png
│ │ │ │ └── House
│ │ │ │ │ └── 0@2x.png
│ │ │ └── contents.xcplayground
│ │ └── contents.xcworkspacedata
│ ├── FinalCode.swift
│ ├── README.md
│ └── Screenshots
│ │ ├── Asteroids.png
│ │ ├── Explosions.png
│ │ ├── Finished.png
│ │ ├── Ground.png
│ │ └── Houses.png
│ ├── 2-Walkabout
│ ├── FinalCode.swift
│ ├── README.md
│ ├── Screenshots
│ │ ├── Edge.png
│ │ ├── Finished.png
│ │ ├── Grass.png
│ │ └── Player.png
│ └── Walkabout.xcworkspace
│ │ ├── Playground.playground
│ │ ├── Contents.swift
│ │ ├── Resources
│ │ │ ├── Ground@2x.png
│ │ │ ├── Obstacle@2x.png
│ │ │ └── Player
│ │ │ │ ├── Idle
│ │ │ │ └── 0@2x.png
│ │ │ │ └── Walking
│ │ │ │ ├── Down@2x.png
│ │ │ │ ├── Left@2x.png
│ │ │ │ ├── Right@2x.png
│ │ │ │ └── Up@2x.png
│ │ └── contents.xcplayground
│ │ └── contents.xcworkspacedata
│ └── README.md
├── Gemfile
├── ImagineEngine.podspec
├── ImagineEngine.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ ├── ImagineEngine-iOS.xcscheme
│ ├── ImagineEngine-macOS.xcscheme
│ └── ImagineEngine-tvOS.xcscheme
├── LICENSE
├── Logo.png
├── README.md
├── Sources
├── Core
│ ├── API
│ │ ├── Action.swift
│ │ ├── ActionPerformer.swift
│ │ ├── ActionToken.swift
│ │ ├── Actor.swift
│ │ ├── ActorEventCollection.swift
│ │ ├── Animation.swift
│ │ ├── AnimationAction.swift
│ │ ├── Block.swift
│ │ ├── BlockTextureCollection.swift
│ │ ├── Camera.swift
│ │ ├── CameraEventCollection.swift
│ │ ├── CancellationToken.swift
│ │ ├── ClosureAction.swift
│ │ ├── Constraint.swift
│ │ ├── Coordinate.swift
│ │ ├── Event.swift
│ │ ├── EventCollection.swift
│ │ ├── EventToken.swift
│ │ ├── FadeAction.swift
│ │ ├── Fadeable.swift
│ │ ├── Game.swift
│ │ ├── Group.swift
│ │ ├── InstanceHashable.swift
│ │ ├── Label.swift
│ │ ├── LabelEventCollection.swift
│ │ ├── MetricAction.swift
│ │ ├── Mirroring.swift
│ │ ├── Movable.swift
│ │ ├── MoveAction.swift
│ │ ├── Node.swift
│ │ ├── Pluggable.swift
│ │ ├── Plugin.swift
│ │ ├── RepeatAction.swift
│ │ ├── RepeatMode.swift
│ │ ├── Rotatable.swift
│ │ ├── RotateAction.swift
│ │ ├── Scalable.swift
│ │ ├── ScaleAction.swift
│ │ ├── Scene.swift
│ │ ├── SceneEventCollection.swift
│ │ ├── Shadow.swift
│ │ ├── SpriteSheet.swift
│ │ ├── Texture.swift
│ │ ├── TextureFormat.swift
│ │ ├── TextureImageLoader.swift
│ │ ├── TextureManager.swift
│ │ ├── Timeline.swift
│ │ ├── Typealiases.swift
│ │ └── ZIndexed.swift
│ └── Internal
│ │ ├── ActionManager.swift
│ │ ├── ActionWrapper.swift
│ │ ├── Activatable.swift
│ │ ├── AnyNode.swift
│ │ ├── BundleProtocol.swift
│ │ ├── BundleTextureImageLoader.swift
│ │ ├── CALayer+Transform.swift
│ │ ├── ClickGestureRecognizer-macOS.swift
│ │ ├── ClickPlugin.swift
│ │ ├── ClosureUpdatable.swift
│ │ ├── DisplayLink-iOS+tvOS.swift
│ │ ├── DisplayLink-macOS.swift
│ │ ├── DisplayLinkProtocol.swift
│ │ ├── EdgeInsets-macOS.swift
│ │ ├── Font+Default.swift
│ │ ├── GameView.swift
│ │ ├── Grid.swift
│ │ ├── GridPlaceable.swift
│ │ ├── Image-macOS.swift
│ │ ├── Layer.swift
│ │ ├── LoadedTexture.swift
│ │ ├── Optional+GetOrSet.swift
│ │ ├── PluginManager.swift
│ │ ├── PluginWrapper.swift
│ │ ├── ReplicatorLayer.swift
│ │ ├── Screen-iOS.swift
│ │ ├── Screen-macOS.swift
│ │ ├── TextLayer.swift
│ │ ├── TextureErrorHandler.swift
│ │ ├── Updatable.swift
│ │ ├── UpdatableCollection.swift
│ │ ├── UpdatableWrapper.swift
│ │ ├── UpdateOutcome.swift
│ │ └── View+MakeLayer.swift
└── Integrations
│ ├── AppKit
│ ├── GameViewController-macOS.swift
│ └── GameWindowController.swift
│ └── UIKit
│ ├── GameViewController-iOS+tvOS.swift
│ └── GameWindow.swift
├── Tests
└── ImagineEngineTests
│ ├── ActionTests.swift
│ ├── ActorTests.swift
│ ├── BlockTests.swift
│ ├── BundleTextureImageLoaderTests.swift
│ ├── CameraTests.swift
│ ├── EventTests.swift
│ ├── LabelTests.swift
│ ├── Mocks
│ ├── ActionMock.swift
│ ├── BundleMock.swift
│ ├── ClickGestureRecognizerMock.swift
│ ├── DisplayLinkMock.swift
│ ├── GameMock.swift
│ ├── GameViewMock.swift
│ ├── PluginMock.swift
│ ├── TextureErrorHandlerMock.swift
│ └── TextureImageLoaderMock.swift
│ ├── Resources
│ ├── sample.jpg
│ └── sample.png
│ ├── SceneTests.swift
│ ├── SpriteSheetTests.swift
│ ├── TextureManagerTests.swift
│ ├── TimelineTests.swift
│ └── Utilities
│ ├── Assert.swift
│ ├── ImageMockFactory.swift
│ ├── TimeTraveler.swift
│ └── XCTAssertEqual+CATransform3D.swift
├── XcodeTemplates
├── Imagine Engine
│ └── iOS Game.xctemplate
│ │ ├── AppDelegate.swift
│ │ ├── Podfile
│ │ ├── TemplateIcon.png
│ │ ├── TemplateIcon@2x.png
│ │ ├── TemplateInfo.plist
│ │ └── ___PACKAGENAME___Scene.swift
└── README.md
└── fastlane
├── Fastfile
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | .build/
41 |
42 | # CocoaPods
43 | #
44 | # We recommend against adding the Pods directory to your .gitignore. However
45 | # you should judge for yourself, the pros and cons are mentioned at:
46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47 | #
48 | # Pods/
49 |
50 | # Carthage
51 | #
52 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
53 | # Carthage/Checkouts
54 |
55 | Carthage/Build
56 |
57 | # fastlane
58 | #
59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
60 | # screenshots whenever they are needed.
61 | # For more information about the recommended setup visit:
62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
63 |
64 | fastlane/report.xml
65 | fastlane/Preview.html
66 | fastlane/screenshots
67 | fastlane/test_output
68 | Gemfile.lock
69 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 4.2
2 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | excluded:
2 | - XcodeTemplates
3 |
4 | function_body_length: 50
5 | identifier_name:
6 | excluded:
7 | - x
8 | - y
9 |
10 | disabled_rules:
11 | - colon
12 | - cyclomatic_complexity
13 | - file_length
14 | - for_where
15 | - operator_whitespace
16 | - type_body_length
17 |
18 | custom_rules:
19 | empty_line_after_guard_statement:
20 | included: ".*\\.swift"
21 | name: "Empty line after guard statement"
22 | regex: "((?<=\n)([ ]*)guard[^\\}]*?\\}\n\\2[^\n])" # Follow https://regex101.com/r/i1IaQH/1 for the explanation on the regex
23 | message: "Add a newline after guard statement to make it easier to read"
24 | severity: warning
25 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode10.2
3 | script:
4 | - bundle exec fastlane tests
5 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Imagine Engine Code of Conduct
2 |
3 | Below is the Code of Conduct that all contributors and participants in the Imagine Engine community are expected to adhere to.
4 | It's adopted from the [Contributor Covenant Code of Conduct][homepage].
5 |
6 | ## Our Pledge
7 |
8 | In the interest of fostering an open and welcoming environment, we as
9 | contributors and maintainers pledge to making participation in our project and
10 | our community a harassment-free experience for everyone, regardless of age, body
11 | size, disability, ethnicity, gender identity and expression, level of experience,
12 | nationality, personal appearance, race, religion, or sexual identity and
13 | orientation.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to creating a positive environment
18 | include:
19 |
20 | * Using welcoming and inclusive language
21 | * Being respectful of differing viewpoints and experiences
22 | * Gracefully accepting constructive criticism
23 | * Focusing on what is best for the community
24 | * Showing empathy towards other community members
25 |
26 | Examples of unacceptable behavior by participants include:
27 |
28 | * The use of sexualized language or imagery and unwelcome sexual attention or
29 | advances
30 | * Trolling, insulting/derogatory comments, and personal or political attacks
31 | * Public or private harassment
32 | * Publishing others' private information, such as a physical or electronic
33 | address, without explicit permission
34 | * Other conduct which could reasonably be considered inappropriate in a
35 | professional setting
36 |
37 | ## Our Responsibilities
38 |
39 | Project maintainers are responsible for clarifying the standards of acceptable
40 | behavior and are expected to take appropriate and fair corrective action in
41 | response to any instances of unacceptable behavior.
42 |
43 | Project maintainers have the right and responsibility to remove, edit, or
44 | reject comments, commits, code, wiki edits, issues, and other contributions
45 | that are not aligned to this Code of Conduct, or to ban temporarily or
46 | permanently any contributor for other behaviors that they deem inappropriate,
47 | threatening, offensive, or harmful.
48 |
49 | ## Scope
50 |
51 | This Code of Conduct applies both within project spaces and in public spaces
52 | when an individual is representing the project or its community. Examples of
53 | representing a project or community include using an official project e-mail
54 | address, posting via an official social media account, or acting as an appointed
55 | representative at an online or offline event. Representation of a project may be
56 | further defined and clarified by project maintainers.
57 |
58 | ## Enforcement
59 |
60 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
61 | reported by contacting the project leader at john@sundell.co. All
62 | complaints will be reviewed and investigated and will result in a response that
63 | is deemed necessary and appropriate to the circumstances. The project team is
64 | obligated to maintain confidentiality with regard to the reporter of an incident.
65 | Further details of specific enforcement policies may be posted separately.
66 |
67 | Project maintainers who do not follow or enforce the Code of Conduct in good
68 | faith may face temporary or permanent repercussions as determined by other
69 | members of the project's leadership.
70 |
71 | ## Attribution
72 |
73 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
74 | available at [http://contributor-covenant.org/version/1/4][version]
75 |
76 | [homepage]: http://contributor-covenant.org
77 | [version]: http://contributor-covenant.org/version/1/4/
78 |
--------------------------------------------------------------------------------
/Configs/ImagineEngine.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSHumanReadableCopyright
24 | Copyright © 2017 John Sundell. All rights reserved.
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Configs/ImagineEngineTests.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Dangerfile:
--------------------------------------------------------------------------------
1 | # Display a friendly welcoming message to non-contributors
2 | contributors = github.api.contributors("JohnSundell/ImagineEngine").map { |user| user.login }
3 |
4 | unless contributors.include? github.pr_author
5 | message "Hi @#{github.pr_author} 👋! Thank you for contributing to Imagine Engine! I'm the CI Bot for this project, and will assist you in getting your PR merged 👍"
6 | end
7 |
8 | # Show SwiftLint warnings inline in the diff
9 | swiftlint.lint_files inline_mode: true
10 |
11 | # Warning to discourage big PRs
12 | if git.lines_of_code > 500
13 | warn "Your PR has over 500 lines of code 😱 Try to break it up into separate PRs if possible 👍"
14 | end
15 |
16 | # Warning to encourage a PR description
17 | if github.pr_body.length == 0
18 | warn "Please add a decription to your PR to make it easier to review 👌"
19 | end
20 |
21 | # Encourage rebases instead of including merge commits
22 | if git.commits.any? { |c| c.message =~ /^Merge branch 'master'/ }
23 | warn "Please rebase to get rid of the merge commits in this PR 🙏"
24 | end
25 |
26 | # If changes have been made in sources, encourage tests
27 | if !git.modified_files.grep(/Sources/).empty? && git.modified_files.grep(/Tests/).empty?
28 | warn "Remember to write tests in case you have added a new API or fixed a bug. Feel free to ask for help if you need it 👍"
29 | end
30 |
--------------------------------------------------------------------------------
/Documentation/Guides/CustomEvents.md:
--------------------------------------------------------------------------------
1 | # Custom Events
2 |
3 | You can easily extend Imagine Engine's default suite of events with your own. This is super useful for communicating between different parts of your game code, such as between a scene and a plugin.
4 |
5 | ## Starting point
6 |
7 | Let's say that we're building an asteroid game, and each time an asteroid is added to the scene, we want to trigger a custom event. To add an asteroid every 10 seconds, we use the `Timeline` API in our scene, like this:
8 |
9 | ```swift
10 | class AsteroidScene: Scene {
11 | override func setup() {
12 | timeline.repeat(withInterval: 10, using: self) { scene in
13 | let asteroid = Actor(textureNamed: "Asteroid")
14 | asteroid.position = scene.center
15 | scene.add(asteroid)
16 | }
17 | }
18 | }
19 | ```
20 |
21 | ## Defining an event
22 |
23 | To be able to trigger a custom event, we have to start by defining it. To do that, we start by adding an extension on `SceneEventCollection` and define our event as a property. Then all we have to do is to call `makeEvent()` from within that property definition, like this:
24 |
25 | ```swift
26 | extension SceneEventCollection {
27 | var asteroidAdded: Event {
28 | return makeEvent()
29 | }
30 | }
31 | ```
32 |
33 | *If you wanted to add a custom event for actors, you'd instead use `ActorEventCollection` as the class you're extending.*
34 |
35 | ## Triggering event
36 |
37 | You can now observe and trigger the event just like a built-in one. For example, right after we add an asteroid to the scene we can simply add this line of code to trigger our new custom event:
38 |
39 | ```swift
40 | scene.events.asteroidAdded.trigger(with: asteroid)
41 | ```
42 |
43 | We can now observe our new event to drive our game logic, for example to display a warning text whenever a new asteroid is incoming:
44 |
45 | ```swift
46 | scene.events.asteroidAdded.observe { scene, asteroid in
47 | let label = Label(text: "Warning! Incoming asteroid!")
48 | label.position = scene.center
49 | scene.add(label)
50 | }
51 | ```
--------------------------------------------------------------------------------
/Documentation/Guides/README.md:
--------------------------------------------------------------------------------
1 | ## Imagine Engine Programming Guides
2 |
3 | Welcome to Imagine Engine's programming guides section!
4 |
5 | While it's currently quite empty, this section will soon be filled up with targeted programming guides for each of the engine's APIs and features. If you want to help out, feel free to submit a PR adding a new guide! 👍
6 |
7 | ## Available guides
8 |
9 | **[Custom Events](CustomEvents.md):** Learn how to use custom events to communicate between different parts of your game code.
--------------------------------------------------------------------------------
/Documentation/README.md:
--------------------------------------------------------------------------------
1 | ## Imagine Engine Documentation
2 |
3 | Welcome to the Imagine Engine documentation portal! Here you can navigate to the available documentation sections:
4 |
5 | **🚀 [Tutorials](Tutorials)**
6 |
7 | Learn how to use Imagine Engine by completing step-by-step tutorials using Swift playgrounds.
8 |
9 | **📖 [Guides](Guides)**
10 |
11 | Browse various guides that each explain how a certain aspect or feature of Imagine Engine works.
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import PlaygroundSupport
3 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Asteroid/0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Asteroid/0@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/0@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/1@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/2@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/3@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/4@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/5@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Explosion/6@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/bottom@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/bottom@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/bottomLeft@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/bottomLeft@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/bottomRight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/bottomRight@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/center@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/center@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/left@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/left@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/right@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/right@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/top@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/top@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/topLeft@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/topLeft@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/topRight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/Ground/topRight@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/House/0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/Resources/House/0@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/Playground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/AsteroidBlaster.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/FinalCode.swift:
--------------------------------------------------------------------------------
1 | /**
2 | * Imagine Engine
3 | * Copyright (c) John Sundell 2017
4 | * See LICENSE file for license
5 | */
6 |
7 | import Foundation
8 | import PlaygroundSupport
9 | import ImagineEngine
10 |
11 | class AsteroidBlasterScene: Scene {
12 | override func setup() {
13 | backgroundColor = Color(red: 0, green: 0, blue: 0.3, alpha: 1)
14 |
15 | let housesGroup = Group.name("Houses")
16 | let groundGroup = Group.name("Ground")
17 |
18 | let groundSize = Size(width: size.width, height: 100)
19 | let ground = Block(size: groundSize, textureCollectionName: "Ground")
20 | ground.position.x = center.x
21 | ground.position.y = size.height - groundSize.height / 2
22 | ground.group = groundGroup
23 | add(ground)
24 |
25 | for x in stride(from: center.x - 100, to: center.x + 150, by: 50) {
26 | let house = Actor()
27 | house.animation = Animation(name: "House", frameCount: 1, frameDuration: 0)
28 | house.group = housesGroup
29 | add(house)
30 |
31 | house.position.x = x
32 | house.position.y = ground.rect.minY - house.size.height / 2
33 | }
34 |
35 | timeline.repeat(withInterval: 2) { [weak self] in
36 | guard let scene = self else {
37 | return
38 | }
39 |
40 | let asteroid = Actor()
41 | asteroid.animation = Animation(name: "Asteroid", frameCount: 1, frameDuration: 0)
42 | scene.add(asteroid)
43 |
44 | let positionRange = scene.size.width - asteroid.size.width
45 | let randomPosition = Metric(arc4random() % UInt32(positionRange))
46 | asteroid.position.x = asteroid.size.width / 2 + randomPosition
47 |
48 | asteroid.velocity.dy = 100
49 |
50 | asteroid.events.collided(withBlockInGroup: groundGroup).observe { asteroid in
51 | asteroid.explode()
52 | }
53 |
54 | asteroid.events.collided(withActorInGroup: housesGroup).observe { asteroid, house in
55 | asteroid.explode()
56 |
57 | house.explode().then {
58 | guard let scene = self else {
59 | return
60 | }
61 |
62 | for actor in scene.actors {
63 | if actor.group == housesGroup {
64 | return
65 | }
66 | }
67 |
68 | scene.reset()
69 | }
70 | }
71 |
72 | asteroid.events.clicked.observe { asteroid in
73 | asteroid.explode()
74 | }
75 | }
76 | }
77 | }
78 |
79 | extension Actor {
80 | @discardableResult func explode() -> ActionToken {
81 | velocity = .zero
82 |
83 | let explosionAnimation = Animation(
84 | name: "Explosion",
85 | frameCount: 7,
86 | frameDuration: 0.07,
87 | repeatMode: .never
88 | )
89 |
90 | return playAnimation(explosionAnimation).then {
91 | self.remove()
92 | }
93 | }
94 | }
95 |
96 | let sceneSize = Size(width: 375, height: 667)
97 | let scene = AsteroidBlasterScene(size: sceneSize)
98 | PlaygroundPage.current.liveView = GameViewController(scene: scene)
99 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Asteroids.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Asteroids.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Explosions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Explosions.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Finished.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Finished.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Ground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Ground.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Houses.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/1-AsteroidBlaster/Screenshots/Houses.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/FinalCode.swift:
--------------------------------------------------------------------------------
1 | /**
2 | * Imagine Engine
3 | * Copyright (c) John Sundell 2017
4 | * See LICENSE file for license
5 | */
6 |
7 | import Foundation
8 | import PlaygroundSupport
9 | import ImagineEngine
10 |
11 | class WalkaboutScene: Scene {
12 | override func setup() {
13 | let ground = Block(size: size, spriteSheetName: "Ground")
14 | ground.position = center
15 | add(ground)
16 |
17 | let player = Actor()
18 | player.position = center
19 | add(player)
20 |
21 | player.textureNamePrefix = "Player/"
22 |
23 | let idleAnimation = Animation(name: "Idle", frameCount: 1, frameDuration: 1)
24 | player.animation = idleAnimation
25 |
26 | var moveToken: ActionToken?
27 |
28 | events.clicked.observe { _, point in
29 | moveToken?.cancel()
30 |
31 | let speed: Metric = 100
32 | let horizontalTarget = Point(x: point.x, y: player.position.y)
33 | let horizontalDuration = TimeInterval(abs(player.position.x - point.x) / speed)
34 | let verticalTarget = Point(x: point.x, y: point.y)
35 | let verticalDuration = TimeInterval(abs(player.position.y - point.y) / speed)
36 |
37 | moveToken = player.move(to: horizontalTarget, duration: horizontalDuration)
38 | .then(player.move(to: verticalTarget, duration: verticalDuration))
39 | .then(player.playAnimation(idleAnimation))
40 | }
41 |
42 | player.events.moved.addObserver(self) { scene, player, positions in
43 | let directionName: String
44 |
45 | if positions.new.x < positions.old.x {
46 | directionName = "Left"
47 | } else if positions.new.x > positions.old.x {
48 | directionName = "Right"
49 | } else if positions.new.y > positions.old.y {
50 | directionName = "Down"
51 | } else {
52 | directionName = "Up"
53 | }
54 |
55 | player.animation = Animation(
56 | spriteSheetNamed: "Walking/\(directionName)",
57 | frameCount: 4,
58 | rowCount: 1,
59 | frameDuration: 0.15
60 | )
61 |
62 | scene.camera.position = positions.new
63 | }
64 |
65 | player.constraints = [.scene]
66 | camera.constrainedToScene = true
67 | }
68 | }
69 |
70 | let sceneSize = Size(width: 768, height: 768)
71 | let scene = WalkaboutScene(size: sceneSize)
72 | PlaygroundPage.current.liveView = GameViewController(scene: scene)
73 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Screenshots/Edge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Screenshots/Edge.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Screenshots/Finished.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Screenshots/Finished.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Screenshots/Grass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Screenshots/Grass.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Screenshots/Player.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Screenshots/Player.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import PlaygroundSupport
3 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Ground@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Ground@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Obstacle@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Obstacle@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Idle/0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Idle/0@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Down@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Down@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Left@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Left@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Right@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Right@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Up@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/Resources/Player/Walking/Up@2x.png
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/Playground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/2-Walkabout/Walkabout.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Documentation/Tutorials/README.md:
--------------------------------------------------------------------------------
1 | ## Imagine Engine Tutorials
2 |
3 | Welcome to the tutorials section! All tutorials feature a detailed walkthrough, as well as a playground that lets you code along it. Currently, the following tutorials are available:
4 |
5 | ### [1. Asteroid Blaster](1-AsteroidBlaster)
6 |
7 | Learn how to get started with Imagine Engine by building a simple game in which the player has to defend a handful of houses by destroying asteroids falling from the sky.
8 |
9 | ### [2. Walkabout](2-Walkabout)
10 |
11 | Learn more about using sprite sheets, camera control, constrains and more, by building a simple game in which a character can be moved around a 2D scene.
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'danger'
4 | gem 'danger-swiftlint'
5 | gem 'xcpretty'
6 | gem 'fastlane'
7 |
--------------------------------------------------------------------------------
/ImagineEngine.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "ImagineEngine"
3 | s.version = "0.10.0"
4 | s.summary = "A Swift game engine based on Core Animation"
5 | s.description = <<-DESC
6 | Imagine Engine is an ongoing project that aims to create a fast, high-performace Swift 2D game engine for Apple's platforms that is also a joy to use.
7 | While there are still ways to go, things to fix and new capabilities to add, you are invited to participate in this new community to build a tool with
8 | an ambitious but clear goal - to enable you to easily build any game that you can imagine.
9 | DESC
10 | s.homepage = "https://github.com/JohnSundell/ImagineEngine"
11 | s.license = { :type => "MIT", :file => "LICENSE" }
12 | s.author = { "John Sundell" => "john@sundell.co" }
13 | s.social_media_url = "https://twitter.com/johnsundell"
14 | s.ios.deployment_target = "9.0"
15 | s.osx.deployment_target = "10.12"
16 | s.tvos.deployment_target = "10.0"
17 | s.source = { :git => "https://github.com/JohnSundell/ImagineEngine.git", :tag => s.version.to_s }
18 | s.source_files = "Sources/Core/**/*.swift"
19 | s.ios.source_files = "Sources/Integrations/UIKit/*.swift"
20 | s.ios.exclude_files = [
21 | "Sources/Core/Internal/ClickGestureRecognizer-macOS.swift",
22 | "Sources/Core/Internal/DisplayLink-macOS.swift",
23 | "Sources/Core/Internal/EdgeInsets-macOS.swift",
24 | "Sources/Core/Internal/Image-macOS.swift",
25 | "Sources/Core/Internal/Screen-macOS.swift"
26 | ]
27 | s.osx.source_files = "Sources/Integrations/AppKit/*.swift"
28 | s.osx.exclude_files = [
29 | "Sources/Core/Internal/DisplayLink-iOS+tvOS.swift",
30 | "Sources/Core/Internal/Screen-iOS.swift"
31 | ]
32 | s.tvos.source_files = "Sources/Integrations/UIKit/*.swift"
33 | s.tvos.exclude_files = [
34 | "Sources/Core/Internal/ClickGestureRecognizer-macOS.swift",
35 | "Sources/Core/Internal/DisplayLink-macOS.swift",
36 | "Sources/Core/Internal/EdgeInsets-macOS.swift",
37 | "Sources/Core/Internal/Image-macOS.swift",
38 | "Sources/Core/Internal/Screen-macOS.swift"
39 | ]
40 | s.frameworks = "Foundation", "CoreGraphics", "QuartzCore"
41 | end
42 |
--------------------------------------------------------------------------------
/ImagineEngine.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ImagineEngine.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
65 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
84 |
90 |
91 |
92 |
93 |
95 |
96 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-macOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 John Sundell
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | The above license covers Imagine Engine itself. It excludes the graphics from
24 | OpenGameArt.org that are used in the tutorials. For the licenses for those files,
25 | please refer to their respective licenses by following the links included in the
26 | tutorials.
27 |
28 |
--------------------------------------------------------------------------------
/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JohnSundell/ImagineEngine/51651193cffb9762f92b99181881ea98e869431e/Logo.png
--------------------------------------------------------------------------------
/Sources/Core/API/Action.swift:
--------------------------------------------------------------------------------
1 | /**
2 | * Imagine Engine
3 | * Copyright (c) John Sundell 2017
4 | * See LICENSE file for license
5 | */
6 |
7 | import Foundation
8 |
9 | /**
10 | * Object representing an action that can be performed by an Imagine Engine game object
11 | *
12 | * By making an Actor or Camera perform an action, by can change one of its properties
13 | * over time. Actions have a set duration during which they are performed, and get updated
14 | * every frame. You can use actions to, for example, move objects around, resize them
15 | * or fade them in or out.
16 | *
17 | * Imagine Engine ships with a default set of actions that are ready to use, and you
18 | * can also easily define your own by subclassing this class and overriding one of the
19 | * override points to perform your own custom action logic.
20 | *
21 | * Here's an example of how an Action can be used to move an Actor:
22 | *
23 | * ```
24 | * let point = Point(x: 200, y: 300)
25 | * actor.perform(MoveAction(destination: point, duration: 5))
26 | * ```
27 | *
28 | * When actions are performed, you get an `ActionToken` back as the result. These tokens
29 | * enable you to both cancel an ongoing action, as well as to observe when it has been
30 | * completed and chain it to other actions.
31 | */
32 | open class Action