1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
def tick args
#tick_instructions args, "Use LEFT and RIGHT arrow keys to move and SPACE to jump."
defaults args
render args
input args
calc args
end
# sets default values and creates empty collections
# initialization only happens in the first frame
def defaults args
fiddle args
args.state.tick_count = args.state.tick_count
args.state.bridge_top = 128
args.state.player.x ||= 0 # initializes player's properties
args.state.player.y ||= args.state.bridge_top
args.state.player.w ||= 64
args.state.player.h ||= 64
args.state.player.dy ||= 0
args.state.player.dx ||= 0
args.state.player.r ||= 0
args.state.game_over_at ||= 0
args.state.animation_time ||=0
args.state.timeleft ||=0
args.state.timeright ||=0
args.state.lastpush ||=0
args.state.inputlist ||= ["j","k","l"]
end
# sets enemy, player, hammer values
def fiddle args
args.state.gravity = -0.5
args.state.player_jump_power = 10 # sets player values
args.state.player_jump_power_duration = 5
args.state.player_max_run_speed = 20
args.state.player_speed_slowdown_rate = 0.9
args.state.player_acceleration = 0.9
end
# outputs objects onto the screen
def render args
if (args.state.player.dx < 0.01) && (args.state.player.dx > -0.01)
args.state.player.dx = 0
end
#move list
(args.layout.rect_group row: 0, col_from_right: 8, drow: 0.3,
merge: { vertical_alignment_enum: 0, size_enum: -2 },
group: [
{ text: "move: WASD" },
{ text: "jump: Space" },
{ text: "attack forwards: J (while on ground" },
{ text: "attack upwards: K (while on groud)" },
{ text: "attack backwards: J (while on ground and holding A)" },
{ text: "attack downwards: K (while in air)" },
{ text: "dash attack: J, K in quick succession." },
{ text: "shield: hold J, K at the same time." },
{ text: "dash backwards: A, A in quick succession." },
]).into args.outputs.labels
# registered moves
args.outputs.labels << { x: 0.to_layout_col,
y: 0.to_layout_row,
text: "input history",
size_enum: -2,
vertical_alignment_enum: 0 }
(args.state.inputlist.take(5)).map do |s|
{ text: s, size_enum: -2, vertical_alignment_enum: 0 }
end.yield_self do |group|
(args.layout.rect_group row: 0.3, col: 0, drow: 0.3, group: group).into args.outputs.labels
end
#sprites
player = [args.state.player.x, args.state.player.y,
args.state.player.w, args.state.player.h,
"sprites/square/white.png",
args.state.player.r]
playershield = [args.state.player.x - 20, args.state.player.y - 10,
args.state.player.w + 20, args.state.player.h + 20,
"sprites/square/blue.png",
args.state.player.r,
0]
playerjab = [args.state.player.x + 32, args.state.player.y,
args.state.player.w, args.state.player.h,
"sprites/isometric/indigo.png",
args.state.player.r,
0]
playerupper = [args.state.player.x, args.state.player.y + 32,
args.state.player.w, args.state.player.h,
"sprites/isometric/indigo.png",
args.state.player.r+90,
0]
if ((args.state.tick_count - args.state.lastpush) <= 15)
if (args.state.inputlist[0] == "<<")
player = [args.state.player.x, args.state.player.y,
args.state.player.w, args.state.player.h,
"sprites/square/yellow.png", args.state.player.r]
end
if (args.state.inputlist[0] == "shield")
player = [args.state.player.x, args.state.player.y,
args.state.player.w, args.state.player.h,
"sprites/square/indigo.png", args.state.player.r]
playershield = [args.state.player.x - 10, args.state.player.y - 10,
args.state.player.w + 20, args.state.player.h + 20,
"sprites/square/blue.png", args.state.player.r, 50]
end
if (args.state.inputlist[0] == "back-attack")
playerjab = [args.state.player.x - 20, args.state.player.y,
args.state.player.w - 10, args.state.player.h,
"sprites/isometric/indigo.png", args.state.player.r, 255]
end
if (args.state.inputlist[0] == "forward-attack")
playerjab = [args.state.player.x + 32, args.state.player.y,
args.state.player.w, args.state.player.h,
"sprites/isometric/indigo.png", args.state.player.r, 255]
end
if (args.state.inputlist[0] == "up-attack")
playerupper = [args.state.player.x, args.state.player.y + 32,
args.state.player.w, args.state.player.h,
"sprites/isometric/indigo.png", args.state.player.r + 90, 255]
end
if (args.state.inputlist[0] == "dair")
playerupper = [args.state.player.x, args.state.player.y - 32,
args.state.player.w, args.state.player.h,
"sprites/isometric/indigo.png", args.state.player.r + 90, 255]
end
if (args.state.inputlist[0] == "dash-attack")
playerupper = [args.state.player.x, args.state.player.y + 32,
args.state.player.w, args.state.player.h,
"sprites/isometric/violet.png", args.state.player.r + 90, 255]
playerjab = [args.state.player.x + 32, args.state.player.y,
args.state.player.w, args.state.player.h,
"sprites/isometric/violet.png", args.state.player.r, 255]
end
end
args.outputs.sprites << playerjab
args.outputs.sprites << playerupper
args.outputs.sprites << player
args.outputs.sprites << playershield
args.outputs.solids << 20.map_with_index do |i| # uses 20 squares to form bridge
[i * 64, args.state.bridge_top - 64, 64, 64]
end
end
# Performs calculations to move objects on the screen
def calc args
# Since velocity is the change in position, the change in x increases by dx. Same with y and dy.
args.state.player.x += args.state.player.dx
args.state.player.y += args.state.player.dy
# Since acceleration is the change in velocity, the change in y (dy) increases every frame
args.state.player.dy += args.state.gravity
# player's y position is either current y position or y position of top of
# bridge, whichever has a greater value
# ensures that the player never goes below the bridge
args.state.player.y = args.state.player.y.greater(args.state.bridge_top)
# player's x position is either the current x position or 0, whichever has a greater value
# ensures that the player doesn't go too far left (out of the screen's scope)
args.state.player.x = args.state.player.x.greater(0)
# player is not falling if it is located on the top of the bridge
args.state.player.falling = false if args.state.player.y == args.state.bridge_top
#args.state.player.rect = [args.state.player.x, args.state.player.y, args.state.player.h, args.state.player.w] # sets definition for player
end
# Resets the player by changing its properties back to the values they had at initialization
def reset_player args
args.state.player.x = 0
args.state.player.y = args.state.bridge_top
args.state.player.dy = 0
args.state.player.dx = 0
args.state.enemy.hammers.clear # empties hammer collection
args.state.enemy.hammer_queue.clear # empties hammer_queue
args.state.game_over_at = args.state.tick_count # game_over_at set to current frame (or passage of time)
end
# Processes input from the user to move the player
def input args
if args.state.inputlist.length > 5
args.state.inputlist.pop
end
should_process_special_move = (args.inputs.keyboard.key_down.j) ||
(args.inputs.keyboard.key_down.k) ||
(args.inputs.keyboard.key_down.a) ||
(args.inputs.keyboard.key_down.d) ||
(args.inputs.controller_one.key_down.y) ||
(args.inputs.controller_one.key_down.x) ||
(args.inputs.controller_one.key_down.left) ||
(args.inputs.controller_one.key_down.right)
if (should_process_special_move)
if (args.inputs.keyboard.key_down.j && args.inputs.keyboard.key_down.k) ||
(args.inputs.controller_one.key_down.x && args.inputs.controller_one.key_down.y)
args.state.inputlist.unshift("shield")
elsif (args.inputs.keyboard.key_down.k || args.inputs.controller_one.key_down.y) &&
(args.state.inputlist[0] == "forward-attack") && ((args.state.tick_count - args.state.lastpush) <= 15)
args.state.inputlist.unshift("dash-attack")
args.state.player.dx = 20
elsif (args.inputs.keyboard.key_down.j && args.inputs.keyboard.a) ||
(args.inputs.controller_one.key_down.x && args.inputs.controller_one.key_down.left)
args.state.inputlist.unshift("back-attack")
elsif ( args.inputs.controller_one.key_down.x || args.inputs.keyboard.key_down.j)
args.state.inputlist.unshift("forward-attack")
elsif (args.inputs.keyboard.key_down.k || args.inputs.controller_one.key_down.y) &&
(args.state.player.y > 128)
args.state.inputlist.unshift("dair")
elsif (args.inputs.keyboard.key_down.k || args.inputs.controller_one.key_down.y)
args.state.inputlist.unshift("up-attack")
elsif (args.inputs.controller_one.key_down.left || args.inputs.keyboard.key_down.a) &&
(args.state.inputlist[0] == "<") &&
((args.state.tick_count - args.state.lastpush) <= 10)
args.state.inputlist.unshift("<<")
args.state.player.dx = -15
elsif (args.inputs.controller_one.key_down.left || args.inputs.keyboard.key_down.a)
args.state.inputlist.unshift("<")
args.state.timeleft = args.state.tick_count
elsif (args.inputs.controller_one.key_down.right || args.inputs.keyboard.key_down.d)
args.state.inputlist.unshift(">")
end
args.state.lastpush = args.state.tick_count
end
if args.inputs.keyboard.space || args.inputs.controller_one.r2 # if the user presses the space bar
args.state.player.jumped_at ||= args.state.tick_count # jumped_at is set to current frame
# if the time that has passed since the jump is less than the player's jump duration and
# the player is not falling
if args.state.player.jumped_at.elapsed_time < args.state.player_jump_power_duration && !args.state.player.falling
args.state.player.dy = args.state.player_jump_power # change in y is set to power of player's jump
end
end
# if the space bar is in the "up" state (or not being pressed down)
if args.inputs.keyboard.key_up.space || args.inputs.controller_one.key_up.r2
args.state.player.jumped_at = nil # jumped_at is empty
args.state.player.falling = true # the player is falling
end
if args.inputs.left # if left key is pressed
if args.state.player.dx < -5
args.state.player.dx = args.state.player.dx
else
args.state.player.dx = -5
end
elsif args.inputs.right # if right key is pressed
if args.state.player.dx > 5
args.state.player.dx = args.state.player.dx
else
args.state.player.dx = 5
end
else
args.state.player.dx *= args.state.player_speed_slowdown_rate # dx is scaled down
end
if ((args.state.player.dx).abs > 5) #&& ((args.state.tick_count - args.state.lastpush) <= 10)
args.state.player.dx *= 0.95
end
end
def tick_instructions args, text, y = 715
return if args.state.key_event_occurred
if args.inputs.mouse.click ||
args.inputs.keyboard.directional_vector ||
args.inputs.keyboard.key_down.enter ||
args.inputs.keyboard.key_down.space ||
args.inputs.keyboard.key_down.escape
args.state.key_event_occurred = true
end
args.outputs.debug << [0, y - 50, 1280, 60].solid
args.outputs.debug << [640, y, text, 1, 1, 255, 255, 255].label
args.outputs.debug << [640, y - 25, "(click to dismiss instructions)" , -2, 1, 255, 255, 255].label
end
|