├── .gitignore
├── SpaceInvaders
├── .gitignore
├── .rubocop.yml
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── top_level.rb
├── live_reload.rb
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── square.png
├── space-invaders.gif
└── spec
│ └── main_spec.rb
├── actions
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── actions.gif
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── ball.png
│ ├── button.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── square.png
└── spec
│ └── main_spec.rb
├── animated-sprite
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── animated-sprite.gif
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── ball.png
│ ├── button.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ ├── sprite_1.png
│ ├── sprite_2.png
│ ├── sprite_3.png
│ ├── sprite_4.png
│ ├── sprite_5.png
│ └── square.png
└── spec
│ └── main_spec.rb
├── collision-detection
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── collision-detection.gif
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── ball.png
│ ├── explosion_particle.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── wall.png
└── spec
│ └── main_spec.rb
├── create-sprite
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── create-sprite.gif
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── square.png
└── spec
│ └── main_spec.rb
├── hello-world
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ └── game_view_controller.rb
├── hello-world.gif
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── large.png
│ ├── medium.png
│ └── small.png
└── spec
│ └── main_spec.rb
├── license.txt
├── particle-effects
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── particle-effects.gif
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── ball.png
│ ├── button.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── square.png
└── spec
│ └── main_spec.rb
├── physics
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── app_delegate.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── physics.gif
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── ball.png
│ ├── explosion_particle.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── wall.png
└── spec
│ └── main_spec.rb
├── putting-it-together
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
│ ├── .#game_scene.rb
│ ├── app_delegate.rb
│ ├── arrow.rb
│ ├── game_scene.rb
│ ├── game_view_controller.rb
│ └── screen_sizes.rb
├── readme.md
├── resources
│ ├── Default-375w-667h@2x.png
│ ├── Default-414w-736h@3x.png
│ ├── Default-568h@2x.png
│ ├── Default-667h@2x.png
│ ├── Default-736h@3x.png
│ ├── ball.png
│ ├── explosion_particle.png
│ ├── large.png
│ ├── medium.png
│ ├── small.png
│ └── wall.png
└── spec
│ └── main_spec.rb
├── readme.md
└── touch-event
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app
├── app_delegate.rb
├── game_scene.rb
├── game_view_controller.rb
└── screen_sizes.rb
├── readme.md
├── resources
├── Default-375w-667h@2x.png
├── Default-414w-736h@3x.png
├── Default-568h@2x.png
├── Default-667h@2x.png
├── Default-736h@3x.png
├── large.png
├── medium.png
├── small.png
└── square.png
├── spec
└── main_spec.rb
└── touch-event.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | /.DS_Store
2 | */profiles
3 |
--------------------------------------------------------------------------------
/SpaceInvaders/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/SpaceInvaders/.rubocop.yml:
--------------------------------------------------------------------------------
1 | Style/Documentation:
2 | Enabled: false
3 |
4 | Metrics/ClassLength:
5 | Enabled: false
6 |
7 | Metrics/MethodLength:
8 | Enabled: false
9 |
10 | Metrics/AbcSize:
11 | Enabled: false
12 |
13 | Style/MethodDefParentheses:
14 | Enabled: false
15 |
16 | MultilineBlockChain:
17 | Enabled: false
18 |
19 | Metrics/CyclomaticComplexity:
20 | Enabled: false
21 |
22 | Metrics/PerceivedComplexity:
23 | Enabled: false
24 |
25 | Metrics/ParameterLists:
26 | Enabled: false
27 |
28 | Style/BlockComments:
29 | Enabled: false
30 |
31 | Metrics/LineLength:
32 | Enabled: false
33 |
34 | Style/BracesAroundHashParameters:
35 | Enabled: false
36 |
--------------------------------------------------------------------------------
/SpaceInvaders/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/SpaceInvaders/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/SpaceInvaders/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'Space Invaders'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/SpaceInvaders/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/SpaceInvaders/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | BULLET_SPEED = 2.5
3 | BOOST_POWER = 0.95
4 | BOOST_DRAG_PERCENTAGE = 0.95
5 | WORLD_WIDTH = UIScreen.mainScreen.bounds.size.width
6 | WORLD_HEIGHT = UIScreen.mainScreen.bounds.size.height
7 | SHIP_SIZE = WORLD_WIDTH.fdiv(14)
8 | BULLET_SIZE = SHIP_SIZE.fdiv(2)
9 | ENEMY_MOVEMENT_SPACE = 7
10 | PLAYER_SHIP_ENEMY_BULLET_CATEGORY = 2
11 | ENEMY_SHIP_PLAYER_BULLET_CATEGORY = 4
12 | PLAYER_Y_POSITION = 150
13 | INSTRUCTIONS_FONT = 17
14 |
15 | def didMoveToView view
16 | $self = self
17 | self.scaleMode = SKSceneScaleModeAspectFit
18 | physicsWorld.gravity = CGVectorMake 0, 0
19 | physicsWorld.contactDelegate = self
20 | @live_canvas = SKNode.new
21 | @dead_canvas = SKNode.new
22 | addChild @live_canvas
23 | addChild @dead_canvas
24 | @bullets = []
25 | @enemies = []
26 | @score_label = add_label '', WORLD_WIDTH.fdiv(2), WORLD_HEIGHT.fdiv(2), 100
27 | @instructions_label_one = add_label 'Tap hereish to move right.',
28 | WORLD_WIDTH - WORLD_WIDTH.fdiv(4),
29 | PLAYER_Y_POSITION.fdiv(2),
30 | INSTRUCTIONS_FONT
31 | @instructions_label_two = add_label 'Tap hereish to move left.',
32 | WORLD_WIDTH.fdiv(4),
33 | PLAYER_Y_POSITION.fdiv(2),
34 | INSTRUCTIONS_FONT
35 | @instructions_label_three = add_label 'Tap anywhere ABOVE the ship to shoot.',
36 | WORLD_WIDTH.fdiv(2),
37 | PLAYER_Y_POSITION + SHIP_SIZE * 1.5,
38 | INSTRUCTIONS_FONT
39 | @ship = add_sprite 'ship', 0, 0, SHIP_SIZE, PLAYER_SHIP_ENEMY_BULLET_CATEGORY
40 | reset_game
41 | end
42 |
43 | def reset_game
44 | @dx = 0
45 | @hide_instructions = false
46 | @instructions_label_one.alpha =
47 | @instructions_label_two.alpha =
48 | @instructions_label_three.alpha = 1
49 | @ship.position = CGPointMake WORLD_WIDTH.fdiv(2), PLAYER_Y_POSITION
50 | reset_enemies
51 | @time_between_enemy_bullets = 600
52 | @bullets.each(&:removeFromParent)
53 | @bullets.clear
54 | @ship_bullet && @ship_bullet.removeFromParent
55 | @ship_bullet = nil
56 | flash_score 0
57 | end
58 |
59 | def reset_enemies
60 | @enemies.each(&:removeFromParent)
61 | @enemies = (0..3).to_a.product((0..6).to_a).map do |tuple|
62 | row, column = tuple
63 | add_sprite 'enemy',
64 | (column * SHIP_SIZE) + SHIP_SIZE.fdiv(2),
65 | WORLD_HEIGHT - (row * SHIP_SIZE) - SHIP_SIZE.fdiv(2) - 40,
66 | SHIP_SIZE,
67 | ENEMY_SHIP_PLAYER_BULLET_CATEGORY
68 | end
69 |
70 | @movement_direction = 1
71 | @move_movement_direction_tick = ENEMY_MOVEMENT_SPACE
72 | end
73 |
74 | def add_sprite name, x, y, size, collision_category
75 | sprite = SKSpriteNode.spriteNodeWithTexture SKTexture.textureWithImageNamed('square.png')
76 | sprite.name = name
77 | sprite.position = CGPointMake x, y
78 | scale = size.fdiv(sprite.size.width)
79 | sprite.xScale = sprite.yScale = scale
80 | sprite.physicsBody = SKPhysicsBody.bodyWithRectangleOfSize sprite.size
81 | sprite.physicsBody.collisionBitMask = 0
82 | sprite.physicsBody.categoryBitMask = collision_category
83 | sprite.physicsBody.contactTestBitMask = collision_category
84 | sprite.alpha = 0
85 | @live_canvas.addChild sprite
86 | sprite
87 | end
88 |
89 | def add_label text, x, y, font_size
90 | label = SKLabelNode.labelNodeWithText text
91 | label.position = CGPointMake(x, y)
92 | label.fontSize = font_size
93 | addChild label
94 | label
95 | end
96 |
97 | def update _
98 | fade_in_fade_out_labels
99 | fade_in_fade_out_sprites
100 | move_enemies
101 | generate_bullet
102 | move_bullets
103 | move_ship
104 | reset_enemies if @enemies.length.zero?
105 | end
106 |
107 | def fade_in_fade_out_labels
108 | @score_label.alpha -= 0.1 if @score_label.alpha > 0
109 | @instructions_label_one.alpha -= rand.fdiv(5) if @instructions_label_one.alpha > 0 && @hide_instructions
110 | @instructions_label_two.alpha -= rand.fdiv(5) if @instructions_label_two.alpha > 0 && @hide_instructions
111 | @instructions_label_three.alpha -= rand.fdiv(5) if @instructions_label_three.alpha > 0 && @hide_instructions
112 | end
113 |
114 | def fade_in_fade_out_sprites
115 | @live_canvas.children.find_all { |c| c.alpha < 1 }.each { |c| c.alpha += rand.fdiv(5) }
116 | @dead_canvas.children.find_all { |c| c.alpha > 0 }.each { |c| c.alpha -= rand.fdiv(5) }
117 | @dead_canvas.children.find_all { |c| c.alpha <= 0 }.each(&:removeFromParent)
118 | end
119 |
120 | def move_ship
121 | @ship.position = CGPointMake(@ship.position.x + @dx, @ship.position.y)
122 |
123 | if @ship.position.x - SHIP_SIZE.fdiv(2) < 0
124 | @ship.position = CGPointMake SHIP_SIZE.fdiv(2), @ship.position.y
125 | @dx = 0
126 | end
127 |
128 | if @ship.position.x + SHIP_SIZE.fdiv(2) > WORLD_WIDTH
129 | @ship.position = CGPointMake WORLD_WIDTH - SHIP_SIZE.fdiv(2), @ship.position.y
130 | @dx = 0
131 | end
132 |
133 | @dx *= BOOST_DRAG_PERCENTAGE
134 |
135 | @boost_direction && @dx += BOOST_POWER * @boost_direction
136 | end
137 |
138 | def touchesBegan touches, withEvent: _
139 | @hide_instructions = true
140 | first_touch = touches.allObjects.first.locationInNode(self)
141 | if first_touch.y < PLAYER_Y_POSITION
142 | @boost_direction = 1
143 | @boost_direction = -1 if first_touch.x < WORLD_WIDTH.fdiv(2)
144 | elsif !@ship_bullet
145 | @ship_bullet = add_sprite 'ship_bullet',
146 | @ship.position.x,
147 | @ship.position.y + SHIP_SIZE.fdiv(2),
148 | BULLET_SIZE,
149 | ENEMY_SHIP_PLAYER_BULLET_CATEGORY
150 | else
151 | @instructions_label_three.text = 'You can only shoot one bullet at a time. Wait.'
152 | @instructions_label_three.alpha = 10
153 | end
154 | end
155 |
156 | def touchesEnded touches, withEvent: _
157 | @boost_direction = nil
158 | end
159 |
160 | def move_bullets
161 | @bullets.each { |b| b.position = CGPointMake(b.position.x, b.position.y - BULLET_SPEED) }
162 | bullets_to_remove = @bullets.find_all { |b| b.position.y + BULLET_SIZE < 0 }
163 | bullets_to_remove.each(&:removeFromParent)
164 | @bullets -= bullets_to_remove
165 | return unless @ship_bullet
166 | @ship_bullet.position = CGPointMake(@ship_bullet.position.x, @ship_bullet.position.y + BULLET_SPEED)
167 | return unless @ship_bullet.position.y > WORLD_HEIGHT
168 | @ship_bullet.removeFromParent
169 | @ship_bullet = nil
170 | end
171 |
172 | def generate_bullet
173 | @fire_tick_count ||= rand(@time_between_enemy_bullets) + 10
174 | @fire_tick_count -= 1
175 | return unless @fire_tick_count <= 0
176 | @fire_tick_count = nil
177 | return if @bullets.count >= @enemies.count
178 | random_enemy = @enemies.sample
179 | @bullets << add_sprite('enemy_bullet',
180 | random_enemy.position.x,
181 | random_enemy.position.y - SHIP_SIZE.fdiv(2) - BULLET_SIZE.fdiv(2),
182 | BULLET_SIZE,
183 | PLAYER_SHIP_ENEMY_BULLET_CATEGORY)
184 | end
185 |
186 | def move_enemies
187 | @move_unit_tick_count ||= 60
188 | @move_unit_tick_count -= 1
189 | return unless @move_unit_tick_count <= 0
190 | @enemies.each do |e|
191 | e.position = CGPointMake(e.position.x + SHIP_SIZE * @movement_direction, e.position.y)
192 | end
193 | @move_movement_direction_tick -= 1
194 | @move_unit_tick_count = nil
195 | return if @move_movement_direction_tick > 0
196 | @move_movement_direction_tick = ENEMY_MOVEMENT_SPACE
197 | @movement_direction *= -1
198 | end
199 |
200 | def flash_score score
201 | @score = score
202 | @score_label.text = @score.to_s
203 | @score_label.alpha = 10
204 | end
205 |
206 | def didBeginContact contact
207 | return if !contact.bodyA.node || !contact.bodyB.node
208 | if contact.bodyA.node.name == 'ship_bullet' || contact.bodyB.node.name == 'ship_bullet'
209 | [contact.bodyA.node, contact.bodyB.node].each do |n|
210 | n.removeFromParent
211 | @dead_canvas.addChild n
212 | @enemies -= [n]
213 | n.physicsBody = nil
214 | end
215 | flash_score(@score += 1)
216 | @time_between_enemy_bullets *= 0.95
217 | @time_between_enemy_bullets = @time_between_enemy_bullets.floor
218 | @ship_bullet = nil
219 | elsif contact.bodyA.node.name == 'ship' || contact.bodyB.node.name == 'ship'
220 | reset_game
221 | end
222 | end
223 | end
224 |
--------------------------------------------------------------------------------
/SpaceInvaders/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | def viewDidLoad
3 | super
4 | @sk_view = SKView.alloc.initWithFrame CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)
5 | self.view = @sk_view
6 | @scene = GameScene.sceneWithSize(@sk_view.frame.size)
7 | @sk_view.presentScene @scene
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/SpaceInvaders/app/top_level.rb:
--------------------------------------------------------------------------------
1 | class TopLevel
2 | def do_live_reload
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/SpaceInvaders/live_reload.rb:
--------------------------------------------------------------------------------
1 | require 'readline'
2 |
3 | def restart
4 | result = IO.popen('rake device', 'w')
5 | result.puts 'do_live_reload'
6 | result
7 | end
8 |
9 | ios_io = restart
10 | first_time = true
11 |
12 | Signal.trap('SIGUSR1') do
13 | if first_time
14 | first_time = false
15 | else
16 | repl_pid = `pgrep repl`
17 | Process.kill('INT', repl_pid.to_i)
18 | ios_io.close
19 | ios_io = restart
20 | end
21 | end
22 |
23 | `echo rerun \\"kill -30 #{Process.pid}\\" --no-notify | pbcopy`
24 |
25 | Readline.readline('Press any key to exit..', true)
26 |
--------------------------------------------------------------------------------
/SpaceInvaders/readme.md:
--------------------------------------------------------------------------------
1 | # Space Invaders Clone
2 |
3 | This sample app is a Space Invaders clone.
4 |
5 | To run the application:
6 |
7 | `rake` will run the app in the iPhone 6 simulator.
8 |
9 | Here's what it looks like:
10 |
11 |
12 |
13 |
14 |
15 | This combines all the techniques learned in the previous sample apps into a game.
16 |
--------------------------------------------------------------------------------
/SpaceInvaders/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/large.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/medium.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/small.png
--------------------------------------------------------------------------------
/SpaceInvaders/resources/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/resources/square.png
--------------------------------------------------------------------------------
/SpaceInvaders/space-invaders.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/SpaceInvaders/space-invaders.gif
--------------------------------------------------------------------------------
/SpaceInvaders/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/actions/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/actions/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/actions/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/actions/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'actions'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/actions/actions.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/actions.gif
--------------------------------------------------------------------------------
/actions/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/actions/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | @camera = SKNode.new
8 | @camera.position = CGPointMake(0, 0)
9 | addChild @camera
10 | @button_2 = add_sprite(190, 60, 'button.png', 'button 2')
11 | particle_2
12 | end
13 |
14 | def touchesBegan touches, withEvent: _
15 | node = nodeAtPoint(touches.allObjects.first.locationInNode(self))
16 | case node.name
17 | when 'button 2'
18 | shake
19 | end
20 | end
21 |
22 | def add_sprite x, y, path, name
23 | texture = SKTexture.textureWithImageNamed path
24 | sprite = SKSpriteNode.spriteNodeWithTexture texture
25 | sprite.position = CGPointMake x, y
26 | sprite.name = name
27 | @camera.addChild sprite
28 | sprite
29 | end
30 |
31 | def shake
32 | randomActions = []
33 | direction_x = 1
34 | direction = [1, -1]
35 | how_many = 10
36 | max_distance = 100
37 | duration = 0.25
38 |
39 | how_many.times do |i|
40 | from = max_distance - (max_distance.fdiv(how_many) * i)
41 | to = from + 10
42 | randX = @camera.position.x + (rand(from..to) * direction_x)
43 | randY = @camera.position.y + (rand(from..to) * direction.sample)
44 | action = SKAction.moveTo(CGPointMake(randX, randY), duration: (duration).fdiv(how_many))
45 | randomActions << action
46 | direction_x *= -1
47 | end
48 |
49 | randomActions << SKAction.moveTo(CGPointMake(0, 0), duration: (duration).fdiv(how_many))
50 |
51 | rep = SKAction.sequence(randomActions)
52 |
53 | @camera.runAction(rep)
54 | end
55 |
56 | def particle_2
57 | particle = SKEmitterNode.alloc.init
58 | particle.setParticleTexture SKTexture.textureWithImageNamed('square.png')
59 | particle.setParticleBirthRate 50
60 | particle.setEmissionAngleRange 360
61 | particle.setParticleSpeed 30
62 | particle.setParticleLifetime 10
63 | particle.setParticleLifetimeRange 20
64 | particle.setParticleAlphaSpeed(-0.5)
65 | particle.setPosition CGPointMake(device_screen_width.fdiv(2), device_screen_height.fdiv(2))
66 | particle.setParticleRotation 0.1
67 | particle.setParticleRotationRange 6
68 | particle.setParticlePositionRange CGVectorMake(120, 120)
69 | particle.setParticleBlendMode SKBlendModeAlpha
70 | @camera.addChild particle
71 | end
72 |
73 | def update currentTime
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/actions/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/actions/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/actions/readme.md:
--------------------------------------------------------------------------------
1 | # Actions
2 |
3 | This sample app shows how to use declarative animations (`SKActions`)
4 | to create a camera shake.
5 |
6 | To run the application:
7 |
8 | `rake` will run the app in the iPhone 6 simulator.
9 |
10 | Here's what it looks like:
11 |
12 |
13 |
14 |
15 |
16 | High level project structure:
17 |
18 | - The camera shake will occur when the button at the button is
19 | pressed.
20 | - All nodes are contained in a top level `SKNode` called `@camera`.
21 | - The `shake` function alternates shaking in the x direction (denoted
22 | by `direction_x`.
23 | - The number of shakes is denoted by the `how_many` variable.
24 | - The random distance the camera moves lessens with every shake, which
25 | is calculated and stored in the `from` and `to` variables.
26 | - An array of `SKAction`s are collected with a random x and random y
27 | (denoted by the `randX` and `randY` variables).
28 | - A final `SKAction` is applied to the camera which places the node
29 | back at postion (0, 0).
30 | - The sequence of `SKAction`'s are applied to `@camera` using the
31 | `runAction` function.
32 |
--------------------------------------------------------------------------------
/actions/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/actions/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/actions/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/actions/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/actions/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/actions/resources/ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/ball.png
--------------------------------------------------------------------------------
/actions/resources/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/button.png
--------------------------------------------------------------------------------
/actions/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/large.png
--------------------------------------------------------------------------------
/actions/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/medium.png
--------------------------------------------------------------------------------
/actions/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/small.png
--------------------------------------------------------------------------------
/actions/resources/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/actions/resources/square.png
--------------------------------------------------------------------------------
/actions/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/animated-sprite/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/animated-sprite/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/animated-sprite/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/animated-sprite/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'animated-sprite'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/animated-sprite/animated-sprite.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/animated-sprite.gif
--------------------------------------------------------------------------------
/animated-sprite/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/animated-sprite/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | @flying_thingy = add_sprite(
8 | device_screen_width.fdiv(2),
9 | device_screen_height.fdiv(2),
10 | "sprite_1.png",
11 | "flying thingy")
12 | @flying_thingy.xScale = 0.5
13 | @flying_thingy.yScale = 0.5
14 | @animation = SKAction.animateWithTextures(
15 | [
16 | texture("sprite_1.png"),
17 | texture("sprite_2.png"),
18 | texture("sprite_3.png"),
19 | texture("sprite_4.png"),
20 | texture("sprite_5.png")
21 | ],
22 | timePerFrame: 0.1)
23 | @flying_thingy.runAction(SKAction.repeatActionForever(@animation))
24 | end
25 |
26 | def texture path
27 | SKTexture.textureWithImageNamed(path)
28 | end
29 |
30 | def add_sprite x, y, path, name
31 | texture = SKTexture.textureWithImageNamed path
32 | sprite = SKSpriteNode.spriteNodeWithTexture texture
33 | sprite.position = CGPointMake x, y
34 | sprite.name = name
35 | addChild sprite
36 | sprite
37 | end
38 |
39 | def update currentTime
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/animated-sprite/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/animated-sprite/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/animated-sprite/readme.md:
--------------------------------------------------------------------------------
1 | # Animating a Sprite
2 |
3 | This sample app shows how to use declarative animations (`SKActions`)
4 | to animate a sprite as if it were moving.
5 |
6 | To run the application:
7 |
8 | `rake` will run the app in the iPhone 6 simulator.
9 |
10 | Here's what it looks like:
11 |
12 |
13 |
14 |
15 |
16 | High level project structure:
17 |
18 | - This is very similar to the `actions` sample code.
19 | - Each sprite is loaded into an array.
20 | - The `SKAction.animateWithTextures` is used to enumerate the sprites.
21 | - The action is repeated forever using `SKAction.repeatActionForever`.
22 |
--------------------------------------------------------------------------------
/animated-sprite/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/animated-sprite/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/animated-sprite/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/animated-sprite/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/animated-sprite/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/animated-sprite/resources/ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/ball.png
--------------------------------------------------------------------------------
/animated-sprite/resources/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/button.png
--------------------------------------------------------------------------------
/animated-sprite/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/large.png
--------------------------------------------------------------------------------
/animated-sprite/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/medium.png
--------------------------------------------------------------------------------
/animated-sprite/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/small.png
--------------------------------------------------------------------------------
/animated-sprite/resources/sprite_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/sprite_1.png
--------------------------------------------------------------------------------
/animated-sprite/resources/sprite_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/sprite_2.png
--------------------------------------------------------------------------------
/animated-sprite/resources/sprite_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/sprite_3.png
--------------------------------------------------------------------------------
/animated-sprite/resources/sprite_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/sprite_4.png
--------------------------------------------------------------------------------
/animated-sprite/resources/sprite_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/sprite_5.png
--------------------------------------------------------------------------------
/animated-sprite/resources/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/animated-sprite/resources/square.png
--------------------------------------------------------------------------------
/animated-sprite/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/collision-detection/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/collision-detection/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/collision-detection/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/collision-detection/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'collision-detection'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/collision-detection/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/collision-detection/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | self.physicsWorld.gravity = CGVectorMake(0, 0)
8 | self.physicsWorld.contactDelegate = self
9 | self.view.showsPhysics = true
10 |
11 | @ball = add_sprite(device_screen_width.fdiv(2),
12 | 60,
13 | 'ball.png',
14 | 'circle')
15 |
16 | @ball.physicsBody = SKPhysicsBody.bodyWithCircleOfRadius(20)
17 | @ball.physicsBody.dynamic = true
18 | @ball.physicsBody.categoryBitMask = 2
19 | @ball.physicsBody.contactTestBitMask = 4
20 | @ball.physicsBody.collisionBitMask = 0
21 |
22 | @wall = add_sprite(device_screen_width.fdiv(2),
23 | device_screen_height.fdiv(2),
24 | 'wall.png',
25 | 'wall')
26 |
27 | @wall.physicsBody = SKPhysicsBody.bodyWithRectangleOfSize CGSizeMake(500, 35)
28 |
29 | @wall.physicsBody.dynamic = true
30 | @wall.physicsBody.categoryBitMask = 4
31 | @wall.physicsBody.contactTestBitMask = 2
32 | @wall.physicsBody.collisionBitMask = 0
33 | end
34 |
35 | def init_explosion
36 | @explosion = SKEmitterNode.alloc.init
37 | @explosion.setParticleTexture SKTexture.textureWithImageNamed('explosion_particle.png')
38 | @explosion.setNumParticlesToEmit 200
39 | @explosion.setParticleBirthRate 450
40 | @explosion.setEmissionAngleRange 360
41 | @explosion.setParticleSpeed 1000
42 | @explosion.setParticleLifetimeRange 0.5
43 | @explosion.setParticleAlphaSpeed(-0.5)
44 | @explosion.setPosition CGPointMake(0, 0)
45 | @explosion.setParticleRotation 0.1
46 | @explosion.setParticleRotationRange 6
47 | @explosion.setParticlePositionRange CGVectorMake(10, 10)
48 | @explosion.setParticleBlendMode SKBlendModeAlpha
49 | @ball.addChild @explosion
50 | end
51 |
52 | def add_sprite x, y, path, name
53 | texture = SKTexture.textureWithImageNamed path
54 | sprite = SKSpriteNode.spriteNodeWithTexture texture
55 | sprite.position = CGPointMake x, y
56 | sprite.name = name
57 | addChild sprite
58 | sprite
59 | end
60 |
61 | def update currentTime
62 | @ball_direction ||= 1
63 |
64 | if @ball.position.y > device_screen_height || @ball.position.y < 0
65 | @ball_direction = @ball_direction * -1
66 | end
67 |
68 | @ball.position = CGPointMake(
69 | @ball.position.x,
70 | (@ball.position.y) + 5 * @ball_direction
71 | )
72 | end
73 |
74 | def didBeginContact _
75 | if @explosion
76 | @explosion.resetSimulation
77 | else
78 | init_explosion
79 | end
80 | end
81 | end
82 |
--------------------------------------------------------------------------------
/collision-detection/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/collision-detection/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/collision-detection/collision-detection.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/collision-detection.gif
--------------------------------------------------------------------------------
/collision-detection/readme.md:
--------------------------------------------------------------------------------
1 | # Collision Detection
2 |
3 | This sample app shows how to set up a physics body and apply collision
4 | detection to sprites.
5 |
6 | To run the application:
7 |
8 | `rake` will run the app in the iPhone 6 simulator.
9 |
10 | Here's what it looks like:
11 |
12 |
13 |
14 |
15 |
16 | High level structure:
17 |
18 | - In `didMoveToView`, `gravity` is removed and a `contactDelegate` is
19 | set to `self`.
20 | - The `@ball` is giving a `categoryBitMask`, and a
21 | `contactTestBitMask`.
22 | - The `@wall` is given the opposite `categoryBitMask`, and a
23 | `contactTestBitMask`.
24 | - The `@ball` and `@wall` are each given a `physicsBody` via apis
25 | provide by `SKPhysicsBody`.
26 | - During the `update` loop, the `@ball` is moved up and down within
27 | the bounds of the screen.
28 | - The `didBeginContact` method is called whenever a collision occurs
29 | (I do a particle effect whenever a collision occurs).
30 |
--------------------------------------------------------------------------------
/collision-detection/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/collision-detection/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/collision-detection/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/collision-detection/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/collision-detection/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/collision-detection/resources/ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/ball.png
--------------------------------------------------------------------------------
/collision-detection/resources/explosion_particle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/explosion_particle.png
--------------------------------------------------------------------------------
/collision-detection/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/large.png
--------------------------------------------------------------------------------
/collision-detection/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/medium.png
--------------------------------------------------------------------------------
/collision-detection/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/small.png
--------------------------------------------------------------------------------
/collision-detection/resources/wall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/collision-detection/resources/wall.png
--------------------------------------------------------------------------------
/collision-detection/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/create-sprite/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/create-sprite/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/create-sprite/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/create-sprite/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'create-sprite'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/create-sprite/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/create-sprite/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | @square = add_sprite device_screen_width.fdiv(2),
8 | device_screen_height.fdiv(2),
9 | 'square.png'
10 | end
11 |
12 | def add_sprite x, y, path
13 | texture = SKTexture.textureWithImageNamed path
14 | sprite = SKSpriteNode.spriteNodeWithTexture texture
15 | sprite.position = CGPointMake x, y
16 | addChild sprite
17 | sprite
18 | end
19 |
20 | def update currentTime
21 | @square.zRotation += 0.1
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/create-sprite/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/create-sprite/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/create-sprite/create-sprite.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/create-sprite.gif
--------------------------------------------------------------------------------
/create-sprite/readme.md:
--------------------------------------------------------------------------------
1 | # Create a Single Sprite
2 |
3 | This sample app shows how to create a single sprite and make it spin.
4 |
5 | To run the application:
6 |
7 | `rake` will run the app in the iPhone 6 simulator.
8 |
9 | Here's what it looks like:
10 |
11 |
12 |
13 |
14 |
15 | High level structure:
16 |
17 | - Sprites are created using `SKSpriteNode`.
18 | - Sprite textures are located in the `resources` directory.
19 | - There is a property on `SKSpriteNode` called `zRotation` (radians) which you
20 | can use to turn a sprite.
21 | - The sprite is turned within the `update` method.
22 |
--------------------------------------------------------------------------------
/create-sprite/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/create-sprite/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/create-sprite/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/create-sprite/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/create-sprite/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/create-sprite/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/large.png
--------------------------------------------------------------------------------
/create-sprite/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/medium.png
--------------------------------------------------------------------------------
/create-sprite/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/small.png
--------------------------------------------------------------------------------
/create-sprite/resources/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/create-sprite/resources/square.png
--------------------------------------------------------------------------------
/create-sprite/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/hello-world/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/hello-world/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/hello-world/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/hello-world/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'hello-world'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/hello-world/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/hello-world/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | def didMoveToView view
3 | self.scaleMode = SKSceneScaleModeAspectFit
4 | self.backgroundColor = UIColor.whiteColor
5 | @time_label = add_label(10, 10)
6 | end
7 |
8 | def add_label x, y
9 | label = SKLabelNode.labelNodeWithText '0'
10 | label.position = CGPointMake(x, y)
11 | label.fontColor = UIColor.blackColor
12 | label.fontSize = 15
13 | label.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft
14 | label.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter
15 | label.zPosition = 100
16 | label.fontName = 'Courier New'
17 | addChild label
18 | label
19 | end
20 |
21 | def update currentTime
22 | @time_label.text = "#{currentTime}"
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/hello-world/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | def viewDidLoad
3 | super
4 |
5 | self.view = sk_view
6 |
7 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
8 | sk_view.presentScene @scene
9 | end
10 |
11 | def sk_view
12 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
13 | end
14 |
15 | def prefersStatusBarHidden
16 | true
17 | end
18 |
19 | def device_screen_width
20 | UIScreen.mainScreen.bounds.size.width
21 | end
22 |
23 | def device_screen_height
24 | UIScreen.mainScreen.bounds.size.height
25 | end
26 |
27 | def screen_rect
28 | CGRectMake(0, 0, device_screen_width, device_screen_height)
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/hello-world/hello-world.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/hello-world.gif
--------------------------------------------------------------------------------
/hello-world/readme.md:
--------------------------------------------------------------------------------
1 | # Sprite Kit Hello World
2 |
3 | SpriteKit is a framework created by Apple specifically designed to
4 | build 2D games.
5 |
6 | This is a really really simple applications that shows how to display
7 | an `SKScene` (`SpriteKit` scene) with an update loop (where all the
8 | work is done). Inside of this loop, an `SKLabelNode` is updated with
9 | the `currentTime`.
10 |
11 | To run the application:
12 |
13 | `rake` will run the app in the iPhone 6 simulator.
14 |
15 | Here's what it looks like:
16 |
17 |
18 |
19 |
20 |
21 | I've added a couple of helper rake tasks to run on different types of
22 | devices, but keep in mind that the simulators are _not_ a replacement
23 | for testing on a real device (_especially_ for games):
24 |
25 | - `rake sim:five`
26 | - `rake sim:six`
27 | - `rake sim:plus`
28 | - `rake sim:ipad`
29 | - `rake sim:ipadpro`
30 |
31 | Feel free to create your own aliases in the `Rakefile`. If any of the
32 | rake tasks above don't work:
33 |
34 | - Run `rake`.
35 | - When the simulator starts up, click Hardware->Device->iOS 10.0.
36 | - You'll see a list of simulator names there. You may have to use
37 | XCode to download new simulators.
38 | - You can run any of the simulators by running:
39 |
40 | ```
41 | rake simulator device_name='THE SIMULATOR NAME'
42 | ```
43 |
44 | High level structure:
45 |
46 | - All code is located in the `app` folder.
47 | - Icons and splash screens are located in the `resources`.
48 | - `app_delegate.rb` is the entry point of the application. This is
49 | where the work is done to present a container view that houses our
50 | scene. `app_delegate.rb` is also where you'd put code for different
51 | types of top level iOS events (such memory warnings, events for
52 | when the app is about to terminate/go into the background).
53 | - `game_view_controller.rb` is just a container for the game, nothing
54 | really interesting there.
55 | - `game_scene.rb` is where all the meat is.
56 |
--------------------------------------------------------------------------------
/hello-world/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/hello-world/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/hello-world/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/hello-world/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/hello-world/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/hello-world/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/large.png
--------------------------------------------------------------------------------
/hello-world/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/medium.png
--------------------------------------------------------------------------------
/hello-world/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/hello-world/resources/small.png
--------------------------------------------------------------------------------
/hello-world/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Amir Rajan
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 |
--------------------------------------------------------------------------------
/particle-effects/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/particle-effects/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/particle-effects/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/particle-effects/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'particle-effects'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/particle-effects/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/particle-effects/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | @button_1 = add_sprite( 50, 60, 'button.png', 'button 1')
8 | @button_2 = add_sprite(190, 60, 'button.png', 'button 2')
9 | @button_3 = add_sprite(330, 60, 'button.png', 'button 3')
10 | end
11 |
12 | def touchesBegan touches, withEvent: _
13 | node = nodeAtPoint(touches.allObjects.first.locationInNode(self))
14 | case node.name
15 | when 'button 1'
16 | particle_1
17 | when 'button 2'
18 | particle_2
19 | when 'button 3'
20 | particle_3
21 | end
22 | end
23 |
24 | def add_sprite x, y, path, name
25 | texture = SKTexture.textureWithImageNamed path
26 | sprite = SKSpriteNode.spriteNodeWithTexture texture
27 | sprite.position = CGPointMake x, y
28 | sprite.name = name
29 | addChild sprite
30 | sprite
31 | end
32 |
33 | def particle_1
34 | particle = SKEmitterNode.alloc.init
35 | particle.setParticleTexture SKTexture.textureWithImageNamed('square.png')
36 | particle.setNumParticlesToEmit 200
37 | particle.setParticleBirthRate 450
38 | particle.setEmissionAngleRange 360
39 | particle.setParticleSpeed 1000
40 | particle.setParticleLifetimeRange 0.5
41 | particle.setParticleAlphaSpeed(-0.5)
42 | particle.setPosition CGPointMake(device_screen_width.fdiv(2), device_screen_height.fdiv(2))
43 | particle.setParticleRotation 0.1
44 | particle.setParticleRotationRange 6
45 | particle.setParticlePositionRange CGVectorMake(10, 10)
46 | particle.setParticleBlendMode SKBlendModeAlpha
47 | addChild particle
48 | end
49 |
50 | def particle_2
51 | particle = SKEmitterNode.alloc.init
52 | particle.setParticleTexture SKTexture.textureWithImageNamed('square.png')
53 | particle.setNumParticlesToEmit 200
54 | particle.setParticleBirthRate 50
55 | particle.setEmissionAngleRange 360
56 | particle.setParticleSpeed 30
57 | particle.setParticleLifetime 10
58 | particle.setParticleLifetimeRange 20
59 | particle.setParticleAlphaSpeed(-0.5)
60 | particle.setPosition CGPointMake(device_screen_width.fdiv(2), device_screen_height.fdiv(2))
61 | particle.setParticleRotation 0.1
62 | particle.setParticleRotationRange 6
63 | particle.setParticlePositionRange CGVectorMake(120, 120)
64 | particle.setParticleBlendMode SKBlendModeAlpha
65 | addChild particle
66 | end
67 |
68 | def particle_3
69 | particle = SKEmitterNode.alloc.init
70 | particle.setParticleTexture SKTexture.textureWithImageNamed('square.png')
71 | particle.setNumParticlesToEmit 100
72 | particle.particleBirthRate = 20
73 | particle.particleLifetime = 3
74 | particle.emissionAngle = 3.14159 / 2.0
75 | particle.emissionAngleRange = 3.14159 / 3.0
76 | particle.particleSpeed = 90
77 | particle.yAcceleration = -70
78 | particle.particleAlphaSpeed = -0.3
79 | particle.setPosition CGPointMake(device_screen_width.fdiv(2), device_screen_height.fdiv(2))
80 | particle.setParticlePositionRange(CGVectorMake(10, 10))
81 | particle.particleBlendMode = SKBlendModeAlpha
82 | addChild particle
83 | end
84 |
85 | def update currentTime
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/particle-effects/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/particle-effects/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/particle-effects/particle-effects.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/particle-effects.gif
--------------------------------------------------------------------------------
/particle-effects/readme.md:
--------------------------------------------------------------------------------
1 | # Particle Effects
2 |
3 | This sample app shows how to create assorted particle effects programmatically.
4 |
5 | To run the application:
6 |
7 | `rake` will run the app in the iPhone 6 simulator.
8 |
9 | Here's what it looks like:
10 |
11 |
12 |
13 |
14 |
15 | High level project structure:
16 |
17 | - There are three buttons sprites at the bottom. When each one is
18 | tapped a differt particle effect is created via an `SKEmitterNode`.
19 |
--------------------------------------------------------------------------------
/particle-effects/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/particle-effects/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/particle-effects/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/particle-effects/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/particle-effects/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/particle-effects/resources/ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/ball.png
--------------------------------------------------------------------------------
/particle-effects/resources/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/button.png
--------------------------------------------------------------------------------
/particle-effects/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/large.png
--------------------------------------------------------------------------------
/particle-effects/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/medium.png
--------------------------------------------------------------------------------
/particle-effects/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/small.png
--------------------------------------------------------------------------------
/particle-effects/resources/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/particle-effects/resources/square.png
--------------------------------------------------------------------------------
/particle-effects/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/physics/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/physics/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/physics/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/physics/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'physics'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/physics/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/physics/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | self.view.showsPhysics = true
8 |
9 | @ball = add_sprite(10,
10 | device_screen_height,
11 | 'ball.png',
12 | 'circle')
13 |
14 | @ball.physicsBody = SKPhysicsBody.bodyWithCircleOfRadius(15)
15 | @wall = add_sprite(device_screen_width.fdiv(2),
16 | 60,
17 | 'wall.png',
18 | 'wall')
19 |
20 | @wall.physicsBody = SKPhysicsBody.bodyWithRectangleOfSize CGSizeMake(1000, 25)
21 | @wall.physicsBody.dynamic = false
22 | @wall.zRotation = 0.5
23 |
24 |
25 | @wall2 = add_sprite(-200,
26 | 500,
27 | 'wall.png',
28 | 'wall')
29 |
30 | @wall2.physicsBody = SKPhysicsBody.bodyWithRectangleOfSize CGSizeMake(1000, 25)
31 | @wall2.physicsBody.dynamic = false
32 | @wall2.zRotation = -0.5
33 | end
34 |
35 | def add_sprite x, y, path, name
36 | texture = SKTexture.textureWithImageNamed path
37 | sprite = SKSpriteNode.spriteNodeWithTexture texture
38 | sprite.position = CGPointMake x, y
39 | sprite.name = name
40 | addChild sprite
41 | sprite
42 | end
43 |
44 | def update currentTime
45 | if(@ball.position.y < -100)
46 | @ball.position = CGPointMake 10, device_screen_height
47 | @ball.physicsBody = SKPhysicsBody.bodyWithCircleOfRadius(15)
48 | end
49 | end
50 |
51 | def didBeginContact _
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/physics/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/physics/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/physics/physics.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/physics.gif
--------------------------------------------------------------------------------
/physics/readme.md:
--------------------------------------------------------------------------------
1 | # Physics
2 |
3 | This sample app shows how to set up a physics body and apply collision
4 | detection.
5 |
6 | To run the application:
7 |
8 | `rake` will run the app in the iPhone 6 simulator.
9 |
10 | Here's what it looks like:
11 |
12 |
13 |
14 |
15 |
16 | High level structure:
17 |
18 | - The `@ball` is given an `SKPhysicsBody`.
19 | - The walls `@wall` and `@wall2` are each given an `SKPhysicsBody`
20 | with `dynamic` set to false (this ensures that they don't move).
21 | - During the `update` loop, the `@ball` has it's position reset if
22 | it's `position.y` is off the screen (it is also given a new
23 | `physicsBody` to remove an carried momentum.
24 |
--------------------------------------------------------------------------------
/physics/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/physics/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/physics/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/physics/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/physics/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/physics/resources/ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/ball.png
--------------------------------------------------------------------------------
/physics/resources/explosion_particle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/explosion_particle.png
--------------------------------------------------------------------------------
/physics/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/large.png
--------------------------------------------------------------------------------
/physics/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/medium.png
--------------------------------------------------------------------------------
/physics/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/small.png
--------------------------------------------------------------------------------
/physics/resources/wall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/physics/resources/wall.png
--------------------------------------------------------------------------------
/physics/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/putting-it-together/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/putting-it-together/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/putting-it-together/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/putting-it-together/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.version = '5.3'
13 | app.deployment_target = "8.1"
14 | app.name = 'A Noble Circle'
15 |
16 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
17 | app.identifier = 'com.scratchworkdevelopment.flatland'
18 |
19 | app.interface_orientations = [:landscape_right, :landscape_left]
20 | app.info_plist['UIRequiresFullScreen'] = true
21 | app.info_plist['ITSAppUsesNonExemptEncryption'] = false
22 |
23 | app.device_family = [:iphone, :ipad]
24 |
25 | # development
26 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
27 | app.provisioning_profile = './profiles/Development.mobileprovision'
28 |
29 | # test
30 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
31 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
32 | # app.entitlements['beta-reports-active'] = true
33 |
34 | # production
35 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
36 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
37 | end
38 |
39 | namespace :sim do
40 | task :five do
41 | system("rake simulator device_name='iPhone 5'")
42 | end
43 |
44 | task :six do
45 | system("rake simulator device_name='iPhone 6'")
46 | end
47 |
48 | task :plus do
49 | system("rake simulator device_name='iPhone 6 Plus'")
50 | end
51 |
52 | task :ipad do
53 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
54 | end
55 |
56 | task :ipadpro do
57 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/putting-it-together/app/.#game_scene.rb:
--------------------------------------------------------------------------------
1 | amiralirajan@Amiralis-MBP.attlocal.net.20540
--------------------------------------------------------------------------------
/putting-it-together/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/putting-it-together/app/arrow.rb:
--------------------------------------------------------------------------------
1 | class Arrow
2 | attr_accessor :node, :x, :y, :floor
3 |
4 | def initialize x, y, vx, vy, floor
5 | @x = x
6 | @y = y
7 | @dx = vx
8 | @dy = vy
9 | @floor = floor
10 | end
11 |
12 | def gravity
13 | -1
14 | end
15 |
16 | def bottom_of_arrow
17 | @floor + 30
18 | end
19 |
20 | def update
21 | if(@y > bottom_of_arrow)
22 | @x += @dx
23 | @y += @dy
24 | @dy += gravity
25 | @y = bottom_of_arrow if @y < bottom_of_arrow
26 | node.position = CGPointMake(@x, @y)
27 | else
28 | node.position = CGPointMake(@x, bottom_of_arrow)
29 | end
30 | end
31 |
32 | def create_node parent
33 | return @node if @node
34 |
35 | @node = add_sprite(parent,
36 | @x,
37 | @y,
38 | 'ball.png',
39 | 'circle')
40 |
41 | @node.physicsBody = SKPhysicsBody.bodyWithCircleOfRadius(20)
42 | @node.physicsBody.dynamic = true
43 | @node.physicsBody.categoryBitMask = 2
44 | @node.physicsBody.contactTestBitMask = 4
45 | @node.physicsBody.collisionBitMask = 0
46 | end
47 |
48 | def add_sprite parent, x, y, path, name
49 | texture = SKTexture.textureWithImageNamed path
50 | sprite = SKSpriteNode.spriteNodeWithTexture texture
51 | sprite.position = CGPointMake x, y
52 | sprite.name = name
53 | parent.addChild sprite
54 | sprite
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/putting-it-together/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def shoot_arrow vx, vy
5 | arrow = Arrow.new(20, device_screen_height * 0.8, vx, vy, floor)
6 | arrow.create_node self
7 | @arrows << arrow
8 | end
9 |
10 | def didMoveToView view
11 | $self = self
12 | @arrows = []
13 | self.scaleMode = SKSceneScaleModeAspectFit
14 | self.backgroundColor = UIColor.whiteColor
15 | self.physicsWorld.gravity = CGVectorMake(0, 0)
16 | self.physicsWorld.contactDelegate = self
17 | self.view.showsPhysics = true
18 |
19 | @wall = add_sprite(device_screen_width.fdiv(2),
20 | floor,
21 | 'wall.png',
22 | 'wall')
23 | end
24 |
25 | def add_sprite x, y, path, name
26 | texture = SKTexture.textureWithImageNamed path
27 | sprite = SKSpriteNode.spriteNodeWithTexture texture
28 | sprite.position = CGPointMake x, y
29 | sprite.name = name
30 | addChild sprite
31 | sprite
32 | end
33 |
34 | def update currentTime
35 | @arrows.each do |a|
36 | a.update
37 | end
38 | end
39 |
40 | def floor
41 | 35
42 | end
43 |
44 | def touchesBegan touches, withEvent: _
45 | @begin_touch = touches.allObjects.first.locationInNode(self)
46 | end
47 |
48 | def touchesEnded touches, withEvent: _
49 | @end_touch = touches.allObjects.first.locationInNode(self)
50 | vx = @begin_touch.x - @end_touch.x
51 | vy = @begin_touch.y - @end_touch.y
52 | shoot_arrow(vx * 0.10, vy * 0.10)
53 | end
54 |
55 | def didBeginContact _
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/putting-it-together/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/putting-it-together/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/putting-it-together/readme.md:
--------------------------------------------------------------------------------
1 | # Putting it Together
2 |
3 | This sample app shows a simple game. Built from the concepts in the
4 | sample apps.
5 |
6 | To run the application:
7 |
8 | `rake` will run the app in the iPhone 6 simulator.
9 |
10 | Here's what it looks like:
11 |
12 | TODO
13 |
--------------------------------------------------------------------------------
/putting-it-together/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/putting-it-together/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/putting-it-together/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/putting-it-together/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/putting-it-together/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/putting-it-together/resources/ball.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/ball.png
--------------------------------------------------------------------------------
/putting-it-together/resources/explosion_particle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/explosion_particle.png
--------------------------------------------------------------------------------
/putting-it-together/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/large.png
--------------------------------------------------------------------------------
/putting-it-together/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/medium.png
--------------------------------------------------------------------------------
/putting-it-together/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/small.png
--------------------------------------------------------------------------------
/putting-it-together/resources/wall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/putting-it-together/resources/wall.png
--------------------------------------------------------------------------------
/putting-it-together/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Mobile Game Development in Ruby #
2 |
3 | Game development is fun!
4 |
5 | Here are some sample apps that will help you build games for iOS using... _drumroll_
6 |
7 | Ruby :-) (specifically using [RubyMotion](http://rubymotion.com)).
8 |
9 | Steps to get started with RubyMotion:
10 |
11 | - You need a mac.
12 | - Download the RubyMotion Starter Pack from the [RubyMotion](http://rubymotion.com) website.
13 | - You need to be on the El Cap OS (at least).
14 | - You need to download XCode (you can get it from the AppStore).
15 | - You need to then open XCode and accept the license.
16 | - You need to install XCode command line tools by running `xcode-select --install`.
17 | - You need Ruby installed, preferablly version `2.3.1p112` or
18 | later. Use [`rbenv`](https://github.com/rbenv/rbenv) for managing Ruby
19 | versions.
20 |
21 | ## Overview of Sample Projects ##
22 |
23 | You'll want to go through the projects in the following order:
24 |
25 | - [hello-world](/hello-world): This sample app shows how to set up a scene, get a
26 | label on the page, and have it update within the game loop.
27 | - [create-sprite](/create-sprite): This sample app shows how to create a single sprite
28 | and put it on the screen. Within the game loop, the sprite's angle
29 | is updated so that it spins.
30 | - [touch-event](/touch-event): This sample app shows how to accept a simple tap
31 | event from the player.
32 | - [particle-effects](/particle-effects): This sample app shows how to create particle
33 | effects programatically.
34 | - [collision-detection](/collision-detection): This sample app shows how to do collision
35 | detection using SpriteKit's physics engine.
36 | - [physics](/physics): This sample app shows how to use SpriteKit's physic
37 | engine to apply gravity to sprites.
38 | - [actions](/actions): This sample app shows how to use SpriteKit's declarative
39 | animations to create a camera shake.
40 | - [animated-sprite](/animated-sprite): This sample app shows how to
41 | chain frame by frame sprite drawings together to create a moving character.
42 | - [Space Invaders](/SpaceInvaders): This sample app takes a lot of
43 | things learned from the sample apps above and makes a Space Invaders game.
44 |
45 | ## ObjectiveC to Ruby ##
46 |
47 | Answers on StackOverflow for iOS are usually in ObjectiveC. There's no
48 | denying that. This section goes into how you can translate ObjectiveC
49 | to Ruby. It's surprisingly simple, even if you've never written a line
50 | of ObjectiveC. If you're gun shy about using Ruby, you'll still get a
51 | great overview of how to read ObjectiveC and Java code contextualized
52 | through Ruby lenses. So let's get started. You can also
53 | read [Learn Ruby the Hard Way](https://learnrubythehardway.org/book/)
54 | to learn more about the language (independent of a framework).
55 |
56 | Here is how a `Person` class would be created in ObjectiveC. There are
57 | two properties `firstName` and `lastName`, and an instance method
58 | called `sayHello` that returns a string. Instance methods in
59 | ObjectiveC are denoted by the `-` sign preceeding the function name:
60 |
61 | ### Class Construction ###
62 |
63 | ```objectivec
64 | //Person.h
65 | @interface Person : NSObject
66 | @property NSString *firstName;
67 | @property NSString *lastName;
68 | - (NSString*)sayHello;
69 | @end
70 |
71 | //Person.m
72 | #import "Person.h"
73 | @implementation Person
74 | - (NSString*)sayHello {
75 | return [NSString stringWithFormat:@"Hello, %@ %@.",
76 | _firstName,
77 | _lastName];
78 | }
79 | @end
80 | ```
81 |
82 | Here is how you would instanciate an instance of `Person` and call the
83 | `sayHello` function.
84 |
85 | ```objectivec
86 | Person *person = [[Person alloc] init];
87 | person.firstName = @"Amir";
88 | person.lastName = @"Rajan";
89 | NSLog([person sayHello]);
90 | ```
91 |
92 | Let's break this down:
93 |
94 | Method invocation in ObjectiveC is done through
95 | paired brackets `[]`. So instead of `person.sayHello()` you have
96 | `[person sayHello]`. All ObjectiveC classes have an `alloc` class
97 | method, and an `init` instance method. The `alloc` class method
98 | creates a memory space for the instance of the class, and the `init`
99 | method initializes it (essentially a constructor).
100 |
101 | Properties are accessed using the `.` operator (as opposed to the `[]`).
102 |
103 | String literals must be preceded by an `@` sign. This is required for
104 | backwards compatability with C (all C code is valid ObjectiveC
105 | code... ObjectiveC is a superset of C).
106 |
107 | `NSLog` is essentially `puts`. It's a global C method so is available anywhere.
108 |
109 | Here is the same `Person` class and usage, but in Ruby.
110 |
111 | ```ruby
112 | class Person
113 | attr_accessor :firstName, :lastName
114 |
115 | def sayHello
116 | "Hello, #{@firstName} #{@lastName}"
117 | end
118 | end
119 | ```
120 |
121 | The usage should be pretty straight forward. It's important to
122 | interalize the _mechancial_ aspect of converting ObjectiveC to
123 | Ruby. Basically, you remove the `[]` and replace it with `.`. We'll
124 | have more examples later.
125 |
126 | ```ruby
127 | person = Person.alloc.init
128 | person.firstName = "Amir"
129 | person.lastName = "Rajan"
130 | NSLog(person.sayHello)
131 | ```
132 |
133 | Also, in Ruby, you _can_ use `Person.alloc.init`, but `Person.new` is
134 | also available to you and does the same thing.
135 |
136 | ### Method Anatomy ###
137 |
138 | Generally speaking, all APIs in iOS use named parameters (and by
139 | extension, most iOS developers follow suit with their own
140 | classes). Here is an example how you would declare a method in ObjectiveC.
141 |
142 | ```objectivec
143 | - (void)setDobWithMonth:(NSInteger)month
144 | withDay:(NSInteger)day
145 | withYear:(NSInteger)year {
146 |
147 | }
148 | ```
149 |
150 | This was really weird the first time I saw it too. So let's break down
151 | the code above. First, the `-` sign preceeding the method name denotes
152 | that this is an instance method (a `+` sign denotes that it's a class
153 | method... more on that later). The next token `(void)` denotes the
154 | return type.
155 |
156 | Now for the fun part. The method name _includes_ the name of the first
157 | parameter (usually the method name is seperated from the parameter
158 | name using the word `With` as a delimeter). The `setDobWithMonth`,
159 | `withDay`, `withYear` are the _public_ names or the parameters. This
160 | is what users of the method will see when autocompletion pops up.
161 |
162 | The tokens `month`, `day`, `year` are what the public names are bound
163 | to _within_ the method body. This is crazy/weird I know. Take a moment
164 | to internalize this. In short, a method's name includes its named
165 | parameters, and each parameter has a outward facing name and an
166 | internal binding.
167 |
168 | Here is how you would call the method.
169 |
170 | ```objectivec
171 | [person setDobWithMonth:1 withDay:1 withYear:2013];
172 | ```
173 |
174 | If you were to tell a teammate to call this method you would say.
175 |
176 | >Call the `setDobWithMonth:withDay:withYear` method.
177 |
178 | Now that you understand the anatomy of a ObjectiveC function. Here is
179 | how you would do exact same thing in Ruby.
180 |
181 | ```ruby
182 | def setDobWithMonth(month,
183 | withDay,
184 | withYear)
185 |
186 | end
187 | ```
188 |
189 | And here is the invocation:
190 |
191 | ```ruby
192 | person.setDobWithMonth(1, withDay: 1, withYear: 2013)
193 | ```
194 |
195 | Now, of course, you can nix the public names of the methods if you
196 | wish, and simply have:
197 |
198 |
199 | ```ruby
200 | def setDobWithMonth(month, day, year)
201 |
202 | end
203 |
204 | person.setDobWithMonth(1, 1, 2013)
205 | ```
206 |
207 | But it's important to know how to call methods with named parameters,
208 | because all iOS APIs are built that way.
209 |
210 | ### Blocks ###
211 |
212 | There is a reason why
213 | [Fucking Block Syntax](http://fuckingblocksyntax.com/) exists. It's
214 | because it's terrifying. Let's break down the next piece of code,
215 | which does an `POST (HTTP)`, passing a dictionary, to a url, and
216 | providing a callback on success.
217 |
218 | ```objectivec
219 | - (void)
220 | post:(NSDictionary *)objectToPost
221 | toUrl:(NSString *)toUrl
222 | success:(void (^)(RKMappingResult *mappingResult))success { }
223 | ```
224 |
225 | Building upon what we learned in the previous section. The name of
226 | this method is `post:toUrl:success` (a more idiomatic name would
227 | probably be `postWithObject:withUrl:success`... but I digress).
228 |
229 | The block is denoted by the `^` token. The full type signature for the
230 | block is `void (^)(RKMappingResult) (╯°□°)╯︵ ┻━┻`.
231 |
232 | Here is how you would invoke the `post:toUrl:success` method:
233 |
234 | ```objectivec
235 | [client post: @{ @"firstName": @"Amir", @"lastName": @"Rajan" }
236 | toUrl: @"http://localhost/people"
237 | success:^(RKMappingResult *result) {
238 | //callback code here
239 | }];
240 | ```
241 |
242 | Again, method invocation is denoted by using `[]`. For backward
243 | compatability with C, dictionary literals must be prefixed with the
244 | `@`, and of course, strings must also be prefixed with the `@` sign. I
245 | call it the bloody stump character, because after you've typed a good
246 | 100 times, your fingers will end up being bloody stumps.
247 |
248 | The callback `success` is denoted with the `^`, plus the typed
249 | parameters, plus the callback method body. Here's how you would write
250 | and invoke the same thing in Ruby:
251 |
252 | ```ruby
253 | def post(objectToPost, toUrl: toUrl, success: success)
254 |
255 | end
256 |
257 | client post({ firstName: "Amir", lastName: "Rajan" },
258 | toUrl: "http://localhost/people",
259 | success: lambda { |result|
260 | #callback code here
261 | })
262 | ```
263 |
264 | With what you've read so far, you should be able to translate the
265 | ObjectiveC code to Ruby. This was taken from an actual StackOverflow answer:
266 |
267 | ```objectivec
268 | _label.layer.backgroundColor = [UIColor whiteColor].CGColor;
269 |
270 | [UIView animateWithDuration:2.0 animations:^{
271 | _label.layer.backgroundColor = [UIColor greenColor].CGColor;
272 | } completion:NULL];
273 | ```
274 |
275 | Don't look, below until you think you've got the translation figured out.
276 |
277 | ```ruby
278 | @label.layer.backgroundColor = UIColor.whiteColor.CGColor
279 |
280 | UIView.animateWithDuration(2.0, animations: lambda {
281 | @label.layer.backgroundColor = UIColor.greenColor.CGColor
282 | }, completion: nil)
283 | ```
284 |
285 | ### Categories vs Mixins ###
286 |
287 | To extend a sealed/third party classes, ObjectiveC has the concept of
288 | a `Category`. Let's say we want to take the animation logic from the
289 | StackOverflow question above, and make it a part of `UIView` (a class
290 | within iOS's `UIKit` library). Here is how you would do it in
291 | ObjectiveC.
292 |
293 | First we define the preprocessor directive (method with named
294 | parameters, blocks, and bloody stump characters):
295 |
296 | ```objectivec
297 | @interface UIView (UIViewExtensions)
298 | - (void)animate:(double)duration block:(void (^)(void))block;
299 | - (void)animate:(void (^)(void))block;
300 | @end
301 | ```
302 |
303 | ObjectiveC has method overloading, so we provide two implementations
304 | of the function, one that takes in a duration and another that has a
305 | default value.
306 |
307 | ```objectivec
308 | @implementation UIView (UIViewExtensions)
309 | - (void)animate:(void (^)(void))block {
310 | [self animate:0.5 block:block];
311 | }
312 |
313 | - (void)animate:(double)duration block:(void (^)(void))block {
314 | [UIView beginAnimations:NULL context:NULL];
315 | [UIView setAnimationDuration:duration];
316 | block();
317 | [UIView commitAnimations];
318 | }
319 | @end
320 | ```
321 |
322 | This is the usage:
323 |
324 | ```objectivec
325 | [label setAlpha:0];
326 | [label animate:1 block:^{ [label setAlpha:1]; }];
327 | ```
328 |
329 | In Ruby, we simply open the class/use a mixin. For berevity, I've just
330 | opened the class \#yolo.
331 |
332 | ```ruby
333 | class UIView
334 | def animate duration = 0.5, &block
335 | UIView.beginAnimations(nil, context:nil)
336 | UIView.setAnimationDuration(duration)
337 | instance_eval &block
338 | UIView.commitAnimations
339 | end
340 | end
341 |
342 | def animate duration = 0.5, &block
343 | UIView.beginAnimations(nil, context:nil)
344 | UIView.setAnimationDuration(duration)
345 | instance_eval &block
346 | UIView.commitAnimations
347 | end
348 | end
349 | ```
350 |
351 | Here is how you would invoke that function.
352 |
353 | ```ruby
354 | label.setAlpha 0
355 | label.animate 1 { label.setAlpha 1 }
356 | ```
357 |
358 | ### Benefit of Class Macros ###
359 |
360 | Ruby class macros are great, and significantly increase
361 | readability. Here is a class from my game A Dark Room, which describes
362 | an encounter with an enemy.
363 |
364 | ```ruby
365 | class SnarlingBeastEvent < EncounterEvent
366 | title "a snarling beast"
367 | text "a snarling beast leaps out of the underbrush."
368 | damage 1
369 |
370 | def loot
371 | {
372 | fur: { min: 3, max: 7, chance: 1.0 }
373 | }
374 | end
375 | end
376 | ```
377 |
378 | Here is the definition of the class macro.
379 |
380 | ```ruby
381 | class EncounterEvent
382 | def self.title title
383 | define_method("title") { title }
384 | end
385 |
386 | def self.text text
387 | define_method("text") { text }
388 | end
389 |
390 | def self.health health
391 | define_method("health") { health }
392 | end
393 | end
394 | ```
395 |
396 | Given that ObjectiveC:
397 |
398 | - Doesn't have class macros.
399 | - Makes you use the bloody stump character.
400 | - Doesn't have the concept of a symbol.
401 | - Forces you to explicitly box and unbox value types from
402 | dictionaries.
403 |
404 | You get a death by 1000 paper cuts. Here is the ObjectiveC code that
405 | accomplishes the same thing as the Ruby code with class macros.
406 |
407 | Define the preprocessor directive. One class method `initNew`, and one
408 | instance method `loot`:
409 |
410 | ```objectivec
411 | @interface SnarlingBeastEvent : EncounterEvent
412 | + (id)initNew;
413 | - (NSDictionary *)loot;
414 | @end
415 | ```
416 |
417 | Call parent constructor with specific attributes. Override `loot`
418 | method. The dictionary literal contstruction, and boxing/unboxing apis
419 | are horrid:
420 |
421 | ```objectivec
422 | @implementation SnarlingBeastEvent
423 | + (id)initNew {
424 | return [super initWithAttributes: @{
425 | @"health": [[NSNumber alloc]initWithInt: 1],
426 | @"title": @"a snarling beast",
427 | @"text": @"a snarling beast leaps out of the underbrush."
428 | }];
429 | }
430 |
431 | - (NSDictionary *)loot {
432 | return @{
433 | @"fur": @{
434 | @"min": [[NSNumber alloc]initWithDouble:3.0],
435 | @"max": [[NSNumber alloc]initWithDouble:7.0],
436 | @"chance": [[NSNumber alloc]initWithDouble:1.0]
437 | }
438 | };
439 | }
440 | @end
441 | ```
442 | Base class implementation. Preprocessor directive, plus
443 | implementation. The dictionary boxing/unboxing apis are horrid:
444 |
445 | ```objectivec
446 | @interface EncounterEvent : NSObject
447 | @property NSString *title;
448 | @property NSString *text;
449 | @property NSInteger health;
450 | + (id)initWithAttributes:(NSDictionary *)attributes;
451 | @end
452 |
453 | @implementation EncounterEvent
454 | + (id)initWithAttributes:(NSDictionary *)attributes {
455 | EncounterEvent *e = [[EncounterEvent alloc] init];
456 | e.title = [attributes valueForKey:@"title"];
457 | e.text = [attributes valueForKey:@"text"];
458 | NSNumber *num = [attributes valueForKey:@"health"];
459 | e.health = [num integerValue];
460 | return e;
461 | }
462 | @end
463 | ```
464 |
465 | Congratulations! You can now read and translate ObjectiveC to Ruby.
466 |
--------------------------------------------------------------------------------
/touch-event/.gitignore:
--------------------------------------------------------------------------------
1 | .repl_history
2 | build
3 | tags
4 | app/pixate_code.rb
5 | resources/*.nib
6 | resources/*.momd
7 | resources/*.storyboardc
8 | .DS_Store
9 | nbproject
10 | .redcar
11 | #*#
12 | *~
13 | *.sw[po]
14 | .eprj
15 | .sass-cache
16 | .idea
17 | .dat*.*
18 |
--------------------------------------------------------------------------------
/touch-event/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | # Add your dependencies here:
5 |
--------------------------------------------------------------------------------
/touch-event/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | rake (11.3.0)
5 |
6 | PLATFORMS
7 | ruby
8 |
9 | DEPENDENCIES
10 | rake
11 |
12 | BUNDLED WITH
13 | 1.13.5
14 |
--------------------------------------------------------------------------------
/touch-event/Rakefile:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | $:.unshift("/Library/RubyMotion/lib")
3 | require 'motion/project/template/ios'
4 |
5 | begin
6 | require 'bundler'
7 | Bundler.require
8 | rescue LoadError
9 | end
10 |
11 | Motion::Project::App.setup do |app|
12 | app.name = 'touch-event'
13 | app.frameworks = %w(CoreGraphics AVFoundation UIKit QuartzCore SpriteKit Foundation AudioToolbox)
14 | app.info_plist['UIRequiresFullScreen'] = true
15 | app.device_family = [:iphone, :ipad]
16 | app.icons = ['large', 'medium', 'small']
17 |
18 | # development
19 | app.codesign_certificate = 'iPhone Developer: Amirali Rajan'
20 | app.provisioning_profile = './profiles/Development.mobileprovision'
21 |
22 | # test
23 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
24 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
25 | # app.entitlements['beta-reports-active'] = true
26 |
27 | # production
28 | # app.codesign_certificate = "iPhone Distribution: Amirali Rajan"
29 | # app.provisioning_profile = './profiles/Distribution.mobileprovision'
30 | end
31 |
32 | namespace :sim do
33 | task :five do
34 | system("rake simulator device_name='iPhone 5'")
35 | end
36 |
37 | task :six do
38 | system("rake simulator device_name='iPhone 6'")
39 | end
40 |
41 | task :plus do
42 | system("rake simulator device_name='iPhone 6 Plus'")
43 | end
44 |
45 | task :ipad do
46 | system("rake simulator device_name='iPad Pro (9.7 inch)'")
47 | end
48 |
49 | task :ipadpro do
50 | system("rake simulator device_name='iPad Pro (12.9 inch)'")
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/touch-event/app/app_delegate.rb:
--------------------------------------------------------------------------------
1 | class AppDelegate
2 | def application(application, didFinishLaunchingWithOptions:launchOptions)
3 | @game_view_controller = GameViewController.new
4 |
5 | UIApplication.sharedApplication.setIdleTimerDisabled true
6 | @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
7 | @window.rootViewController = @game_view_controller
8 | @window.makeKeyAndVisible
9 |
10 | true
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/touch-event/app/game_scene.rb:
--------------------------------------------------------------------------------
1 | class GameScene < SKScene
2 | include ScreenSizes
3 |
4 | def didMoveToView view
5 | self.scaleMode = SKSceneScaleModeAspectFit
6 | self.backgroundColor = UIColor.whiteColor
7 | self.view.multipleTouchEnabled = true
8 | @squares = []
9 | end
10 |
11 | def touchesBegan touches, withEvent: _
12 | touches.allObjects.each do |t|
13 | @squares << add_sprite(t.locationInNode(self).x,
14 | t.locationInNode(self).y,
15 | 'square.png')
16 | end
17 | end
18 |
19 | def add_sprite x, y, path
20 | texture = SKTexture.textureWithImageNamed path
21 | sprite = SKSpriteNode.spriteNodeWithTexture texture
22 | sprite.position = CGPointMake x, y
23 | addChild sprite
24 | sprite
25 | end
26 |
27 | def update currentTime
28 | @squares.each { |s| s.zRotation += 0.1 }
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/touch-event/app/game_view_controller.rb:
--------------------------------------------------------------------------------
1 | class GameViewController < UIViewController
2 | include ScreenSizes
3 |
4 | def viewDidLoad
5 | super
6 |
7 | self.view = sk_view
8 |
9 | @scene = GameScene.sceneWithSize(sk_view.frame.size)
10 | sk_view.presentScene @scene
11 | end
12 |
13 | def sk_view
14 | @sk_view ||= SKView.alloc.initWithFrame screen_rect
15 | end
16 |
17 | def prefersStatusBarHidden
18 | true
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/touch-event/app/screen_sizes.rb:
--------------------------------------------------------------------------------
1 | module ScreenSizes
2 | def device_screen_width
3 | UIScreen.mainScreen.bounds.size.width
4 | end
5 |
6 | def device_screen_height
7 | UIScreen.mainScreen.bounds.size.height
8 | end
9 |
10 | def screen_rect
11 | CGRectMake(0, 0, device_screen_width, device_screen_height)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/touch-event/readme.md:
--------------------------------------------------------------------------------
1 | # Create Sprite at Point Touched
2 |
3 | This sample app shows how to create sprites at touch locations.
4 |
5 | To run the application:
6 |
7 | `rake` will run the app in the iPhone 6 simulator.
8 |
9 | Here's what it looks like:
10 |
11 |
12 |
13 |
14 |
15 | High level structure:
16 |
17 | - In the `didMoveToView` method, `view.multipleTouchEnabled` is set to
18 | `true`.
19 | - Whenever a touch occurs the `touchesBegan` method is invoked.
20 | - The `touches.allObjects` is enumerated to create a sprite at each
21 | touch location.
22 | - Each sprite is enumerated within the `update` method to get rotated
23 | via the `zRotation` property.
24 |
--------------------------------------------------------------------------------
/touch-event/resources/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/touch-event/resources/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/touch-event/resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/touch-event/resources/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/Default-667h@2x.png
--------------------------------------------------------------------------------
/touch-event/resources/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/Default-736h@3x.png
--------------------------------------------------------------------------------
/touch-event/resources/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/large.png
--------------------------------------------------------------------------------
/touch-event/resources/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/medium.png
--------------------------------------------------------------------------------
/touch-event/resources/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/small.png
--------------------------------------------------------------------------------
/touch-event/resources/square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/resources/square.png
--------------------------------------------------------------------------------
/touch-event/spec/main_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Application 'sprite-kit-hello-world'" do
2 | before do
3 | @app = UIApplication.sharedApplication
4 | end
5 |
6 | it "has one window" do
7 | @app.windows.size.should == 1
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/touch-event/touch-event.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirrajan/ios-ruby-game-dev/a11f66a8980b8a638ec44b4712b0eb3f9212a7f0/touch-event/touch-event.gif
--------------------------------------------------------------------------------