Experiment with Motion Game
RubyMotion 4.0 was recently released with several great features.
The first one must be RubyMotion Starter, a free version of RubyMotion that comes with full support for iOS and Android development. It’s the right time to get your hands on it if you are a ruby developer who wants to learn mobile app development.
Another great feature is the introduction of motion-game, a brand-new, 100% cross-platform engine to write mobile games. Ruby developer can now write games for iOS and Android with a single code base. And this is what I’m going to do in the next.
Today, we will create a MarioJump game in 100 lines.
Resources and source code can be downloaded from here.
Initialization
Let’s initialize the game with command:
motion create --template=motion-game MarioJump
To see what it creates, execute rake ios:simulator
(or rake android:emulator
).
You’ll see a black screen with nothing but a ‘Hello World’ label.
In this tutorial, the only file we will care about is ‘app/main_scene.rb’.
Add Mario & Ground
Let’s remove the label and add our main character Mario.
class MainScene < MG::Scene
def initialize
add_mario
end
def add_mario
@mario = MG::Sprite.new('mario_1.png')
@mario.position = [200, 200]
@mario.attach_physics_box
add @mario
end
end
If you run the game now, you’ll see Mario falls out of the screen soon. That’s because of the gravity. Let’s tweak it and add a ground.
def initialize
self.gravity = [0, -900]
add_mario
add_ground
end
def add_ground
1.upto(15) do |offset|
block = MG::Sprite.new('block.png')
block.attach_physics_box
block.dynamic = false
block.position = [200 + (offset-1) * 48, 100]
add block
end
end
Run
Now, we can see Mario falls from the sky and then stands on the ground.
To let Mario run, update add_ground
:
add block
block.move_by([-1500, 0], 5.0) { block.delete_from_parent }
...
And to make it look better, we can add an animation:
@mario.animate(['mario_1.png', 'mario_2.png', 'mario_3.png'], 0.1, :forever)
Jump
To let Mario jump when you touch the screen, we can use:
on_touch_begin do
@mario.velocity = [0, 400]
end
However, by just doing this, Mario will jump whenever you touch the screen, even it’s in the air.
To fix this, we’ll need a variable @on_ground
and event on_contact_begin
.
class MainScene < MG::Scene
MARIO = 1
GROUND = 2
def initialize
...
@on_ground = false
on_touch_begin do
if @on_ground
@on_ground = false
@mario.velocity = [0, 400]
end
end
on_contact_begin do
@on_ground = true
@mario.velocity = [0, 0]
true
end
end
def add_ground
...
block.category_mask = GROUND
block.contact_mask = MARIO
...
end
def add_mario
...
@mario.category_mask = MARIO
@mario.contact_mask = GROUND
...
end
end
After doing this, Mario can only jump when he stands on the ground.
Build the level
Now it’s time to build the level.
We’ll be keeping adding endless moving grounds so that players can continuously play the game if they don’t fall from it.
def initialize
...
@block_update = 0
@random = Random.new
start_update
end
def add_block
number = @random.rand(1..5)
1.upto(number) do |offset|
block = MG::Sprite.new('block.png')
block.attach_physics_box
block.dynamic = false
block.category_mask = GROUND
block.contact_mask = MARIO
block.position = [MG::Director.shared.size.width + offset * 48, 100]
add block
block.move_by([-1500, 0], 5.0) { block.delete_from_parent }
end
end
def update(delta)
@block_update += delta
if @block_update >= 1.0
add_block
@block_update = 0
end
end
This will create a 1~5 blocks long ground every one second.
What’s next
A featured game should have sounds, Game Over and Restart Game. Update the file:
...
@on_ground = false
@block_update = 0
@random = Random.new
+ @game_over = false
on_touch_begin do
+ if @game_over
+ MG::Director.shared.replace(MainScene.new)
+ end
if @on_ground
+ MG::Audio.play('jump.wav')
@on_ground = false
@mario.velocity = [0, 400]
end
end
...
def update(delta)
+ if @mario.position.y < 0
+ MG::Audio.play('game_over.wav')
+ stop_update
+ @game_over = true
+ end
...
We can now play the game. Survive as long as you can!