Skip to content

Commit 6f2b1b7

Browse files
committed
Added hello world tutorial.
1 parent 147e2eb commit 6f2b1b7

File tree

2 files changed

+232
-76
lines changed

2 files changed

+232
-76
lines changed

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<div>
7878
<h1>Tutorials</h1>
7979
<ul>
80+
<li><a href="index.html?tutorial=tutorial-hello-world.html">Hello World</a></li>
8081
<li><a href="index.html?tutorial=tutorial-primitives.html">Rendering Primitives</a></li>
8182
<li><a href="index.html?tutorial=tutorial-animation.html">Animating Sprites</a></li>
8283
<li><a href="index.html?tutorial=tutorial-arcade-shooter.html">Arcade Shooter</a></li>

tutorial-hello-world.html

Lines changed: 231 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,45 @@
11
<html>
22
<head>
3-
<title>DragonRuby Game Toolkit - Moving a Sprite</title>
3+
<title>DragonRuby Game Toolkit - Hello World</title>
44
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.3/styles/default.min.css" />
55
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.0.3/highlight.min.js"></script>
66
<script src="tutorial.js"></script>
77
<link rel="stylesheet" href="tutorial.css" />
88
</head>
99
<body>
10-
<h1>DragonRuby Game Toolkit - Moving a Sprite</h1>
10+
<h1>Hey Listen!</h1
11+
<p>
12+
You can try out this tutorial interactively <a href="http://fiddle.dragonruby.org?tutorial=http://fiddle.dragonruby.org/tutorial-hello-world.html" target="_blank">here</a>.
13+
</p>
1114
<div itemscope="itemscope" itemtype="tutorial-step" data-step-number="1">
1215
<div itemscope="itemscope" itemtype="tutorial-text">
1316
<h1>Hello World</h1>
14-
In this tutorial, we'll cover how to move a sprite. We'll start off with
15-
a empty canvas with a dark gray color.
17+
<p>
18+
In this tutorial, we'll cover how to move a player around
19+
using the keyboard.
20+
</p>
21+
22+
<p>
23+
DragonRuby requires you to define a <code>method</code> called <code>tick</code>. This <code>tick</code>
24+
method is called on your behalf at the rate of sixty times per second.
25+
</p>
26+
27+
<p>The code you're currently looking at renders a label to the screen and prints the current frame.</p>
1628
</div>
1729
<div itemscope="itemscope" itemtype="tutorial-code">
1830
<pre>
1931
<code class="language-ruby" itemprop="text">
20-
# entry point to game
32+
# this is how you define the tick method in DragonRuby
2133
def tick args
22-
# set the game's background color
23-
# try changing these numbers and seeing how
24-
# the background color changes
25-
args.outputs.background_color = [40, 44, 52]
34+
# this is how a label is rendered to the screen
35+
args.outputs.labels << {
36+
x: 30,
37+
y: 30,
38+
text: args.state.tick_count
39+
}
2640
end
2741

28-
# reset the game on save
42+
# reset the game if we save
2943
$gtk.reset
3044
</code>
3145
</pre>
@@ -34,49 +48,31 @@ <h1>Hello World</h1>
3448

3549
<div itemscope="itemscope" itemtype="tutorial-step" data-step-number="2">
3650
<div itemscope="itemscope" itemtype="tutorial-text">
37-
<h1>Drawing A Sprite</h1>
38-
Here is how you add a sprite to the screen.
51+
<h1>Rendering a Square</h1>
52+
<p>
53+
Now that you have a <code>tick</code> method defined. Let's render a green square to the screen.
54+
This will represent your player character.
55+
</p>
56+
<p>
57+
For rendering <code>labels</code>, we use <code>args.outputs.labels</code>. To render <code>sprites</code>, we
58+
use <code>args.outputs.sprites</code>. A sprite needs to provide its <code>x</code> location, its <code>y</code> location,
59+
its <code>w</code> (width), its <code>h</code> (height), and a <code>path</code> (file path for the image).
60+
</p>
3961
</div>
4062
<div itemscope="itemscope" itemtype="tutorial-code">
4163
<pre>
4264
<code class="language-ruby" itemprop="text">
4365
def tick args
44-
# add a sprite
45-
# try change these numbers to see
46-
# how the sprite changes
47-
args.outputs.sprites << [
48-
0, # X
49-
0, # Y
50-
20, # W
51-
20, # H
52-
'sprites/square-green.png', # PATH
53-
]
54-
55-
# list of sprites you have availble to you:
56-
# colors of the rainbow ROY G BIV.
57-
# - sprites/square-red.png
58-
# - sprites/square-orange.png
59-
# - sprites/square-yellow.png
60-
# - sprites/square-green.png
61-
# - sprites/square-blue.png
62-
# - sprites/square-indigo.png
63-
# - sprites/square-violet.png
64-
# - sprites/square-black.png
65-
# - sprites/square-white.png
66-
# - sprites/circle-red.png
67-
# - sprites/circle-orange.png
68-
# - sprites/circle-yellow.png
69-
# - sprites/circle-green.png
70-
# - sprites/circle-blue.png
71-
# - sprites/circle-indigo.png
72-
# - sprites/circle-violet.png
73-
# - sprites/circle-black.png
74-
# - sprites/circle-white.png
75-
76-
args.outputs.background_color = [40, 44, 52]
66+
# this is how a sprite is rendered to the screen
67+
args.outputs.sprites << {
68+
x: 0,
69+
y: 0,
70+
w: 16,
71+
h: 16,
72+
path: 'sprites/square/green.png'
73+
}
7774
end
7875

79-
# reset the game on save
8076
$gtk.reset
8177
</code>
8278
</pre>
@@ -85,46 +81,205 @@ <h1>Drawing A Sprite</h1>
8581

8682
<div itemscope="itemscope" itemtype="tutorial-step" data-step-number="3">
8783
<div itemscope="itemscope" itemtype="tutorial-text">
88-
<h1>Moving The Sprite</h1>
89-
The <code>tick</code> method is executed <code>60</code> times a second. To
90-
store the location of a sprite accross frames, we need to store it in <code>args.state</code>.
84+
<h1>Storing Variables</h1>
85+
<p>
86+
We have to store the player's position over time. We do this using DragonRuby's <code>args.state</code>
87+
function.
88+
</p>
89+
<p>
90+
Take a look at the code to see how we define the player's properties as <code>state</code> variables.
91+
You'll notice the use of the <code>||=</code> symbol (it's referred to as "or equals"). This symbol tells
92+
DragonRuby to <i>only</i> set a <code>state</code> property if it's never been set before.
93+
</p>
94+
<p>
95+
We will update the player's <code>x</code> position one time every tick. You'll see the player move
96+
across the screen.
97+
</p>
98+
</div>
99+
<div itemscope="itemscope" itemtype="tutorial-code">
100+
<pre>
101+
<code class="language-ruby" itemprop="text">
102+
def tick args
103+
# set the player's state
104+
# only set the player's starting properties
105+
# once using the ||= operator.
106+
args.state.player.x ||= 0
107+
args.state.player.y ||= 0
108+
args.state.player.w ||= 16
109+
args.state.player.h ||= 16
110+
111+
args.outputs.sprites << {
112+
x: args.state.player.x,
113+
y: args.state.player.y,
114+
w: args.state.player.w,
115+
h: args.state.player.h,
116+
path: 'sprites/square/green.png'
117+
}
118+
119+
# update the players x location once every tick
120+
args.state.player.x += 2
121+
end
122+
123+
$gtk.reset
124+
</code>
125+
</pre>
126+
</div>
127+
</div>
128+
129+
<div itemscope="itemscope" itemtype="tutorial-step" data-step-number="4">
130+
<div itemscope="itemscope" itemtype="tutorial-text">
131+
<h1>Keyboard Input</h1>
132+
<p>
133+
The player automatically moves to the right every frame, but we want to control
134+
the player's movement using the keyboard.
135+
</p>
136+
<p>
137+
We'll use a conditional statement called an <code>if</code> statement to only move the player
138+
if we have held down the <code>right</code> arrow key. DragonRuby provides all keyboard data
139+
via <code>args.inputs.keyboard</code>.
140+
</p>
141+
</div>
142+
<div itemscope="itemscope" itemtype="tutorial-code">
143+
<pre>
144+
<code class="language-ruby" itemprop="text">
145+
def tick args
146+
args.state.player.x ||= 0
147+
args.state.player.y ||= 0
148+
args.state.player.w ||= 16
149+
args.state.player.h ||= 16
150+
151+
args.outputs.sprites << {
152+
x: args.state.player.x,
153+
y: args.state.player.y,
154+
w: args.state.player.w,
155+
h: args.state.player.h,
156+
path: 'sprites/square/green.png'
157+
}
158+
159+
# update the players x location only if ~right~
160+
# is pressed or held on the keyboard
161+
if args.inputs.keyboard.right
162+
args.state.player.x += 2
163+
end
164+
end
165+
166+
$gtk.reset
167+
</code>
168+
</pre>
169+
</div>
170+
</div>
171+
172+
<div itemscope="itemscope" itemtype="tutorial-step" data-step-number="5">
173+
<div itemscope="itemscope" itemtype="tutorial-text">
174+
<h1>Keyboard Input All Directions</h1>
175+
<p>
176+
We use multiple conditional statements, called <code>if/elsif</code> conditionals,
177+
to handle all keyboard input.
178+
</p>
179+
<p>
180+
We'll use a conditional statement called an <code>if</code> statement to only move the player
181+
if we have held down the <code>right</code> arrow key. DragonRuby provides all keyboard data
182+
via <code>args.inputs.keyboard</code>.
183+
</p>
184+
</div>
185+
<div itemscope="itemscope" itemtype="tutorial-code">
186+
<pre>
187+
<code class="language-ruby" itemprop="text">
188+
def tick args
189+
args.state.player.x ||= 0
190+
args.state.player.y ||= 0
191+
args.state.player.w ||= 16
192+
args.state.player.h ||= 16
193+
194+
args.outputs.sprites << {
195+
x: args.state.player.x,
196+
y: args.state.player.y,
197+
w: args.state.player.w,
198+
h: args.state.player.h,
199+
path: 'sprites/square/green.png'
200+
}
201+
202+
if args.inputs.keyboard.right
203+
# update the players x location only if
204+
# ~right~ is pressed or held on the keyboard
205+
args.state.player.x += 2
206+
elsif args.inputs.keyboard.left
207+
# ~left~ is pressed or held on the keyboard
208+
args.state.player.x -= 2
209+
end
210+
211+
if args.inputs.keyboard.up
212+
# ~up~ is pressed or held on the keyboard
213+
args.state.player.y += 2
214+
elsif args.inputs.keyboard.down
215+
# ~down~ is pressed or held on the keyboard
216+
args.state.player.y -= 2
217+
end
218+
end
219+
220+
$gtk.reset
221+
</code>
222+
</pre>
223+
</div>
224+
</div>
225+
226+
<div itemscope="itemscope" itemtype="tutorial-step" data-step-number="6">
227+
<div itemscope="itemscope" itemtype="tutorial-text">
228+
<h1>Out of Bounds</h1>
229+
<p>
230+
Finally, we make sure the player can't go outside of the play
231+
area which is defined in DragonRuby via <code>args.grid</code>.
232+
</p>
233+
<p>
234+
We use a combination of <code>args.grid</code> and a mathematical
235+
function called <code>clamp</code> to make sure the player's
236+
properties are "clamped" to a minimum and maximum value.
237+
</p>
238+
<p>
239+
Boom. You've just learned how to move a player around. Congrats.
240+
</p>
91241
</div>
92242
<div itemscope="itemscope" itemtype="tutorial-code">
93243
<pre>
94244
<code class="language-ruby" itemprop="text">
95245
def tick args
96-
# initialize the x location once
97-
# using Ruby's ||= operator
98-
args.state.x ||= 0
99-
args.state.y ||= 0
100-
101-
# every tick, increment the location
102-
# of the sprite by 1
103-
args.state.x += 1
104-
args.state.y += 1
105-
106-
# if the sprite is off the screen
107-
# move it back to the original position
108-
# the size of this canvas is
109-
# 160 pixels by 90 pixels
110-
if args.state.x > 160
111-
args.state.x = -10
246+
args.state.player.x ||= 0
247+
args.state.player.y ||= 0
248+
args.state.player.w ||= 16
249+
args.state.player.h ||= 16
250+
251+
args.outputs.sprites << {
252+
x: args.state.player.x,
253+
y: args.state.player.y,
254+
w: args.state.player.w,
255+
h: args.state.player.h,
256+
path: 'sprites/square/green.png'
257+
}
258+
259+
if args.inputs.keyboard.right
260+
args.state.player.x += 2
261+
elsif args.inputs.keyboard.left
262+
args.state.player.x -= 2
112263
end
113264

114-
if args.state.y > 90
115-
args.state.y = -10
265+
if args.inputs.keyboard.up
266+
args.state.player.y += 2
267+
elsif args.inputs.keyboard.down
268+
args.state.player.y -= 2
116269
end
117270

118-
# render the sprite based on state
119-
args.outputs.sprites << [
120-
args.state.x, # X
121-
args.state.y, # Y
122-
20, # W
123-
20, # H
124-
'sprites/square-green.png', # PATH
125-
]
271+
# make sure the player's x and y position
272+
# are clamped to the the grid's minimum and
273+
# maximum width and height
274+
args.state.player.x = args.state.player.x.clamp(
275+
args.grid.left,
276+
args.grid.right - args.state.player.w
277+
)
126278

127-
args.outputs.background_color = [40, 44, 52]
279+
args.state.player.y = args.state.player.y.clamp(
280+
args.grid.bottom,
281+
args.grid.top - args.state.player.h
282+
)
128283
end
129284

130285
$gtk.reset

0 commit comments

Comments
 (0)