rofltim 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +94 -0
- data/bin/roflbalt +5 -0
- data/lib/roflbalt.rb +477 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 30444f0e7475fea054716007d5ab3253ec50e13da69c6d293691580704affac1
|
4
|
+
data.tar.gz: 776a3cc65cfcee5b4666d97ef14bc45ce7d925f014b9ce6eb777abd4ac00aa6e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 457fcd1cc833d03b206b6dc22c04bafd05c3ff26a17e60379cee07b6281343d3248cc5bf08863a90d3527df1652cfd2824e1f9ec7dadd99ad3983d529aeeab14
|
7
|
+
data.tar.gz: 03fcde9e488cadf6470135664c66e5c11a7513e83777799167f6972caae9ef70dfc5235d3b63a6b9fbc1c6cc837cde5406c94f511ac776aaeee5c7fe84dc79a2
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
ROFLBALT
|
2
|
+
========
|
3
|
+
|
4
|
+
A Canabalt-inspired sidescroller in ASCII (with ANSI color!) for your console.
|
5
|
+
|
6
|
+
|
7
|
+
WTF?
|
8
|
+
----
|
9
|
+
|
10
|
+
It's built by [Paul Annesley][1] ([@pda][2])
|
11
|
+
and [Dennis Hotson][3] ([@dennishotson][4])
|
12
|
+
with < 500 lines of Ruby, no dependencies;
|
13
|
+
it just uses `print` and raw xterm-256color escape codes.
|
14
|
+
|
15
|
+
We wrote it at [Rails Camp X][5] in two days,
|
16
|
+
pair programming over SSH with a shared [tmux][6]/[vim][7] session.
|
17
|
+
As such, ~50% of the commits labelled Paul were actually Dennis!
|
18
|
+
|
19
|
+
[1]: http://paul.annesley.cc/
|
20
|
+
[2]: https://twitter.com/pda
|
21
|
+
[3]: http://dhotson.tumblr.com/
|
22
|
+
[4]: https://twitter.com/dennishotson
|
23
|
+
[5]: http://railscamps.com/#adelaide_jan_2012
|
24
|
+
[6]: http://tmux.sourceforge.net/
|
25
|
+
[7]: http://www.vim.org/
|
26
|
+
|
27
|
+
|
28
|
+
Requirements
|
29
|
+
------------
|
30
|
+
|
31
|
+
**Ruby 1.9**. It doesn't work with Ruby 1.8, but I'm sure somebody could easily fix that...
|
32
|
+
|
33
|
+
You'll need a terminal with 256 color support and at least 120 columns by 40 rows of text.
|
34
|
+
|
35
|
+
* For Mac OS X we highly recommend [iTerm2](http://www.iterm2.com/),
|
36
|
+
but if you're running Lion (or newer?) you can use the default Terminal.app.
|
37
|
+
* For Windows, I imagine [PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/)
|
38
|
+
is still the thing to use.
|
39
|
+
* For GNU/Linux etc, use xterm!
|
40
|
+
|
41
|
+
|
42
|
+
Instructions
|
43
|
+
------------
|
44
|
+
|
45
|
+
```sh
|
46
|
+
# install:
|
47
|
+
gem install roflbalt
|
48
|
+
|
49
|
+
# using rbenv? it rocks.
|
50
|
+
rbenv rehash
|
51
|
+
|
52
|
+
# LOL
|
53
|
+
roflbalt
|
54
|
+
```
|
55
|
+
|
56
|
+
Press any key to jump! If you can't find the any key, try the spacebar.
|
57
|
+
|
58
|
+
And of course, ctrl-c to exit.
|
59
|
+
|
60
|
+
If your terminal isn't quite right afterwards, try running `reset` to get it back to normal.
|
61
|
+
There's [an issue open](https://github.com/pda/roflbalt/issues/2) for this.
|
62
|
+
|
63
|
+
|
64
|
+
"Screenshot"
|
65
|
+
------------
|
66
|
+
|
67
|
+
(or [check out the video](http://www.youtube.com/watch?v=VoHmJfXqwbM))
|
68
|
+
|
69
|
+
Score: 23432
|
70
|
+
|
71
|
+
ROFL:ROFL:LoL:ROFL:ROFL
|
72
|
+
O/ L ____|__
|
73
|
+
/| O ===` []\
|
74
|
+
/ > L \________]
|
75
|
+
.__|____|__/
|
76
|
+
|
77
|
+
==========================================
|
78
|
+
::::::::::::::::::::::::::::::::::::::::::
|
79
|
+
::: :: :: :: ::
|
80
|
+
::: :: :: :: ::
|
81
|
+
==================== ::::::::::::::::::::::::::::::::::::::::::
|
82
|
+
::::::::::::::::::::: ::: :: :: :: ::
|
83
|
+
:: :: :: ::: :: :: :: ::
|
84
|
+
:: :: :: ::::::::::::::::::::::::::::::::::::::::::
|
85
|
+
::::::::::::::::::::: ::: :: :: :: ::
|
86
|
+
:: :: :: ::: :: :: :: ::
|
87
|
+
|
88
|
+
|
89
|
+
License
|
90
|
+
-------
|
91
|
+
|
92
|
+
(c) 2012 Dennis Hotson, Paul Annesley
|
93
|
+
|
94
|
+
Open source: MIT license.
|
data/bin/roflbalt
ADDED
data/lib/roflbalt.rb
ADDED
@@ -0,0 +1,477 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
SCREEN_WIDTH = 120
|
4
|
+
SCREEN_HEIGHT = 40
|
5
|
+
|
6
|
+
class Game
|
7
|
+
def initialize
|
8
|
+
reset
|
9
|
+
end
|
10
|
+
def reset
|
11
|
+
@run = true
|
12
|
+
@world = World.new(SCREEN_WIDTH)
|
13
|
+
@screen = Screen.new(SCREEN_WIDTH, SCREEN_HEIGHT, @world)
|
14
|
+
end
|
15
|
+
def run
|
16
|
+
Signal.trap(:INT) do
|
17
|
+
@run = false
|
18
|
+
end
|
19
|
+
while @run
|
20
|
+
start_time = Time.new.to_f
|
21
|
+
unless @world.tick
|
22
|
+
reset
|
23
|
+
end
|
24
|
+
render start_time
|
25
|
+
end
|
26
|
+
on_exit
|
27
|
+
end
|
28
|
+
def render start_time
|
29
|
+
@world.buildings.each do |building|
|
30
|
+
@screen.draw(building)
|
31
|
+
end
|
32
|
+
@screen.draw(@world.player)
|
33
|
+
@world.misc.each do |object|
|
34
|
+
@screen.draw(object)
|
35
|
+
end
|
36
|
+
@screen.render start_time
|
37
|
+
end
|
38
|
+
def on_exit
|
39
|
+
@screen.on_exit
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Screen
|
44
|
+
OFFSET = -20
|
45
|
+
def initialize width, height, world
|
46
|
+
@width = width
|
47
|
+
@height = height
|
48
|
+
@world = world
|
49
|
+
@background = world.background
|
50
|
+
create_frame_buffer
|
51
|
+
%x{stty -icanon -echo}
|
52
|
+
print "\033[0m" # reset
|
53
|
+
print "\033[2J" # clear screen
|
54
|
+
print "\x1B[?25l" # disable cursor
|
55
|
+
end
|
56
|
+
attr_reader :width, :height, :world
|
57
|
+
def create_frame_buffer
|
58
|
+
@fb = Framebuffer.new @background
|
59
|
+
end
|
60
|
+
def draw renderable
|
61
|
+
renderable.each_pixel(world.ticks) do |x, y, pixel|
|
62
|
+
@fb.set x, y, pixel
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def render start_time
|
66
|
+
print "\e[H"
|
67
|
+
buffer = ''
|
68
|
+
previous_pixel = nil
|
69
|
+
(0...height).each do |y|
|
70
|
+
(OFFSET...(width + OFFSET)).each do |x|
|
71
|
+
pixel = @fb.get(x, y)
|
72
|
+
if Pixel === previous_pixel && Pixel === pixel && pixel.color_equal?(previous_pixel)
|
73
|
+
buffer << pixel.char
|
74
|
+
else
|
75
|
+
buffer << pixel.to_s
|
76
|
+
end
|
77
|
+
previous_pixel = pixel
|
78
|
+
end
|
79
|
+
buffer << "\n"
|
80
|
+
end
|
81
|
+
print "\033[0m"
|
82
|
+
|
83
|
+
dt = Time.new.to_f - start_time;
|
84
|
+
target_time = 0.04
|
85
|
+
sleep target_time - dt if dt < target_time
|
86
|
+
|
87
|
+
print buffer
|
88
|
+
create_frame_buffer
|
89
|
+
end
|
90
|
+
def on_exit
|
91
|
+
print "\033[0m" # reset colours
|
92
|
+
print "\x1B[?25h" # re-enable cursor
|
93
|
+
print "\n"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Pixel
|
98
|
+
def initialize char = " ", fg = nil, bg = nil
|
99
|
+
@char = char
|
100
|
+
@fg, @bg = fg, bg
|
101
|
+
end
|
102
|
+
attr_reader :char
|
103
|
+
def fg; @fg || 255 end
|
104
|
+
def bg; @bg || 0 end
|
105
|
+
def to_s
|
106
|
+
"\033[48;5;%dm\033[38;5;%dm%s" % [ bg, fg, @char ]
|
107
|
+
end
|
108
|
+
def color_equal? other
|
109
|
+
fg == other.fg && bg == other.bg
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Background
|
114
|
+
PALETTE = [ 16, 232, 233 ]
|
115
|
+
PERIOD = 16.0
|
116
|
+
SPEED = 0.5
|
117
|
+
BLOCKINESS = 10.0
|
118
|
+
def initialize world
|
119
|
+
@world = world
|
120
|
+
end
|
121
|
+
def pixel x, y, char = " "
|
122
|
+
Pixel.new char, 0, color(x, y)
|
123
|
+
end
|
124
|
+
def color x, y
|
125
|
+
y = (y / BLOCKINESS).round * BLOCKINESS
|
126
|
+
sin = Math.sin((x + @world.distance.to_f * SPEED) / PERIOD + y / PERIOD)
|
127
|
+
PALETTE[(0.9 * sin + 0.9).round]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class WindowColor
|
132
|
+
PALETTE = [ 16, 60 ]
|
133
|
+
PERIOD = 6.0
|
134
|
+
def pixel x, y, char = " "
|
135
|
+
Pixel.new char, 0, color(x, y)
|
136
|
+
end
|
137
|
+
def color x, y
|
138
|
+
sin = Math.sin(x / PERIOD + y / (PERIOD * 0.5))
|
139
|
+
PALETTE[(0.256 * sin + 0.256).round]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Framebuffer
|
144
|
+
def initialize background
|
145
|
+
@pixels = Hash.new { |h, k| h[k] = {} }
|
146
|
+
@background = background
|
147
|
+
end
|
148
|
+
def set x, y, pixel
|
149
|
+
@pixels[x][y] = pixel
|
150
|
+
end
|
151
|
+
def get x, y
|
152
|
+
@pixels[x][y] || @background.pixel(x, y)
|
153
|
+
end
|
154
|
+
def size
|
155
|
+
@pixels.values.reduce(0) { |a, v| a + v.size }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class World
|
160
|
+
def initialize horizon
|
161
|
+
@ticks = 0
|
162
|
+
@horizon = horizon
|
163
|
+
@building_generator = BuildingGenerator.new(self, WindowColor.new)
|
164
|
+
@background = Background.new(self)
|
165
|
+
@player = Player.new(25, @background)
|
166
|
+
@buildings = [ @building_generator.build(-10, 30, 120) ]
|
167
|
+
@misc = [ Scoreboard.new(self), RoflCopter.new(50, 4, @background) ]
|
168
|
+
@speed = 4
|
169
|
+
@distance = 0
|
170
|
+
end
|
171
|
+
attr_reader :buildings, :player, :horizon, :speed, :misc, :ticks, :distance, :background
|
172
|
+
def tick
|
173
|
+
# TODO: this, but less often.
|
174
|
+
if @ticks % 20 == 0
|
175
|
+
@building_generator.generate_if_necessary
|
176
|
+
@building_generator.destroy_if_necessary
|
177
|
+
end
|
178
|
+
|
179
|
+
@distance += speed
|
180
|
+
|
181
|
+
buildings.each do |b|
|
182
|
+
b.move_left speed
|
183
|
+
end
|
184
|
+
|
185
|
+
if b = building_under_player
|
186
|
+
if player.bottom_y > b.y
|
187
|
+
b.move_left(-speed)
|
188
|
+
@speed = 0
|
189
|
+
@misc << Blood.new(player.x, player.y)
|
190
|
+
@misc << GameOverBanner.new
|
191
|
+
player.die!
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
begin
|
196
|
+
if STDIN.read_nonblock(1)
|
197
|
+
if player.dead?
|
198
|
+
return false
|
199
|
+
else
|
200
|
+
player.jump
|
201
|
+
end
|
202
|
+
end
|
203
|
+
rescue Errno::EAGAIN
|
204
|
+
end
|
205
|
+
|
206
|
+
player.tick
|
207
|
+
|
208
|
+
if b = building_under_player
|
209
|
+
player.walk_on_building b if player.bottom_y >= b.y
|
210
|
+
end
|
211
|
+
|
212
|
+
@ticks += 1
|
213
|
+
end
|
214
|
+
def building_under_player
|
215
|
+
buildings.detect do |b|
|
216
|
+
b.x <= player.x && b.right_x >= player.right_x
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class BuildingGenerator
|
222
|
+
def initialize world, background
|
223
|
+
@world = world
|
224
|
+
@background = background
|
225
|
+
end
|
226
|
+
def destroy_if_necessary
|
227
|
+
while @world.buildings.any? && @world.buildings.first.x < -100
|
228
|
+
@world.buildings.shift
|
229
|
+
end
|
230
|
+
end
|
231
|
+
def generate_if_necessary
|
232
|
+
while (b = @world.buildings.last).x < @world.horizon
|
233
|
+
@world.buildings << build(
|
234
|
+
b.right_x + minimium_gap + rand(24),
|
235
|
+
next_y(b),
|
236
|
+
rand(40) + 40
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
def minimium_gap; 16 end
|
241
|
+
def maximum_height_delta; 10 end
|
242
|
+
def minimum_height_clearance; 12; end
|
243
|
+
def next_y previous_building
|
244
|
+
p = previous_building
|
245
|
+
delta = 0
|
246
|
+
while delta.abs <= 1
|
247
|
+
delta = maximum_height_delta * -1 + rand(2 * maximum_height_delta + 1)
|
248
|
+
end
|
249
|
+
[25, [previous_building.y - delta, minimum_height_clearance].max].min
|
250
|
+
end
|
251
|
+
def build x, y, width
|
252
|
+
Building.new x, y, width, @background
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
module Renderable
|
257
|
+
def each_pixel ticks
|
258
|
+
(y...(y + height)).each do |y|
|
259
|
+
(x...(x + width)).each do |x|
|
260
|
+
rx = x - self.x
|
261
|
+
ry = y - self.y
|
262
|
+
yield x, y, pixel(x, y, rx, ry, ticks)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
def right_x; x + width end
|
267
|
+
end
|
268
|
+
|
269
|
+
class Building
|
270
|
+
include Renderable
|
271
|
+
def initialize x, y, width, background
|
272
|
+
@x, @y = x, y
|
273
|
+
@width = width
|
274
|
+
@background = background
|
275
|
+
@period = rand(4) + 6
|
276
|
+
@window_width = @period - rand(2) - 1
|
277
|
+
@color = (235..238).to_a.shuffle.first # Ruby 1.8
|
278
|
+
@top_color = @color + 4
|
279
|
+
@left_color = @color + 2
|
280
|
+
end
|
281
|
+
attr_reader :x, :y, :width
|
282
|
+
def move_left distance
|
283
|
+
@x -= distance
|
284
|
+
end
|
285
|
+
def height; SCREEN_HEIGHT - @y end
|
286
|
+
def pixel x, y, rx, ry, ticks
|
287
|
+
if ry == 0
|
288
|
+
if rx == width - 1
|
289
|
+
Pixel.new " "
|
290
|
+
else
|
291
|
+
Pixel.new "=", 234, @top_color
|
292
|
+
end
|
293
|
+
elsif rx == 0 || rx == 1
|
294
|
+
Pixel.new ":", @left_color + 1, @left_color
|
295
|
+
elsif rx == 2
|
296
|
+
Pixel.new ":", 236, 236
|
297
|
+
elsif rx == width - 1
|
298
|
+
Pixel.new ":", 236, 236
|
299
|
+
else
|
300
|
+
if rx % @period >= @period - @window_width && ry % 5 >= 2
|
301
|
+
Pixel.new(" ", 255, @background.color(rx + x/2, ry))
|
302
|
+
else
|
303
|
+
Pixel.new(":", 235, @color)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
class Player
|
310
|
+
include Renderable
|
311
|
+
def initialize y, background
|
312
|
+
@y = y
|
313
|
+
@background = background
|
314
|
+
@velocity = 1
|
315
|
+
@walking = false
|
316
|
+
end
|
317
|
+
def x; 0; end
|
318
|
+
def width; 3 end
|
319
|
+
def height; 3 end
|
320
|
+
def pixel x, y, rx, ry, ticks
|
321
|
+
Pixel.new char(rx, ry, ticks), 255, @background.color(x, y)
|
322
|
+
end
|
323
|
+
|
324
|
+
def char rx, ry, ticks
|
325
|
+
if dead?
|
326
|
+
[
|
327
|
+
' @ ',
|
328
|
+
'\+/',
|
329
|
+
' \\\\',
|
330
|
+
][ry][rx]
|
331
|
+
elsif !@walking
|
332
|
+
[
|
333
|
+
' O/',
|
334
|
+
'/| ',
|
335
|
+
'/ >',
|
336
|
+
][ry][rx]
|
337
|
+
else
|
338
|
+
[
|
339
|
+
[
|
340
|
+
' O ',
|
341
|
+
'/|v',
|
342
|
+
'/ >',
|
343
|
+
],
|
344
|
+
[
|
345
|
+
' 0 ',
|
346
|
+
',|\\',
|
347
|
+
' >\\',
|
348
|
+
],
|
349
|
+
][ticks / 4 % 2][ry][rx]
|
350
|
+
end
|
351
|
+
end
|
352
|
+
def acceleration
|
353
|
+
if @dead
|
354
|
+
0.05
|
355
|
+
else
|
356
|
+
0.35
|
357
|
+
end
|
358
|
+
end
|
359
|
+
def tick
|
360
|
+
@y += @velocity
|
361
|
+
@velocity += acceleration
|
362
|
+
@walking = false
|
363
|
+
end
|
364
|
+
def y; @y.round end
|
365
|
+
def bottom_y; y + height end
|
366
|
+
def walk_on_building b
|
367
|
+
@y = b.y - height
|
368
|
+
@velocity = 0
|
369
|
+
@walking = true
|
370
|
+
end
|
371
|
+
def jump
|
372
|
+
jump! if @walking
|
373
|
+
end
|
374
|
+
def jump!
|
375
|
+
@velocity = -2.5
|
376
|
+
end
|
377
|
+
def die!
|
378
|
+
@dead = true
|
379
|
+
@velocity = 0
|
380
|
+
end
|
381
|
+
def dead?
|
382
|
+
@dead
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
class Blood < Struct.new(:x, :y)
|
387
|
+
include Renderable
|
388
|
+
def height; 4 end
|
389
|
+
def width; 2 end
|
390
|
+
def x; super + 2 end
|
391
|
+
def pixel x, y, rx, ry, ticks
|
392
|
+
Pixel.new ":", 124, 52
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
class Scoreboard
|
397
|
+
include Renderable
|
398
|
+
def initialize world
|
399
|
+
@world = world
|
400
|
+
end
|
401
|
+
def height; 3 end
|
402
|
+
def width; 20 end
|
403
|
+
def x; -18 end
|
404
|
+
def y; 1 end
|
405
|
+
def template
|
406
|
+
[
|
407
|
+
' ',
|
408
|
+
' Score: %9s ' % [ @world.distance],
|
409
|
+
' '
|
410
|
+
]
|
411
|
+
end
|
412
|
+
def pixel x, y, rx, ry, ticks
|
413
|
+
Pixel.new template[ry][rx], 244, 234
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
class GameOverBanner
|
418
|
+
FG = 16
|
419
|
+
BG = 244
|
420
|
+
include Renderable
|
421
|
+
def x; 28 end
|
422
|
+
def y; 14 end
|
423
|
+
def width; 28 end
|
424
|
+
def height; 3 end
|
425
|
+
def template
|
426
|
+
[
|
427
|
+
' ',
|
428
|
+
' YOU DIED. LOL. ',
|
429
|
+
' ',
|
430
|
+
]
|
431
|
+
end
|
432
|
+
def pixel x, y, rx, ry, ticks
|
433
|
+
Pixel.new template[ry][rx], FG, BG
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
class RoflCopter
|
438
|
+
include Renderable
|
439
|
+
def initialize x, y, background
|
440
|
+
@x, @y = x, y
|
441
|
+
@background = background
|
442
|
+
@frames = [
|
443
|
+
[
|
444
|
+
' :TiM:TIM:TIM ',
|
445
|
+
' T ____|__ ',
|
446
|
+
' I ===` []\ ',
|
447
|
+
' M \________] ',
|
448
|
+
' .__|____|__/ ',
|
449
|
+
],
|
450
|
+
[
|
451
|
+
' TIM:TIM:tIm: ',
|
452
|
+
' ____|__ ',
|
453
|
+
' TIM===` []\ ',
|
454
|
+
' \________] ',
|
455
|
+
' .__|____|__/ ',
|
456
|
+
],
|
457
|
+
]
|
458
|
+
end
|
459
|
+
def width; 24 end
|
460
|
+
def height; 5 end
|
461
|
+
def y
|
462
|
+
range = 1.5
|
463
|
+
@y + (range * Math.sin(Time.new.to_f * 1.5)).round
|
464
|
+
end
|
465
|
+
def x
|
466
|
+
range = 20
|
467
|
+
@x + (range * Math.sin(Time.new.to_f * 0.7)).round
|
468
|
+
end
|
469
|
+
def pixel x, y, rx, ry, ticks
|
470
|
+
Pixel.new char(rx, ry, ticks), 246, @background.color(x, y)
|
471
|
+
end
|
472
|
+
def char rx, ry, ticks
|
473
|
+
@frames[ticks % 2][ry][rx] || " "
|
474
|
+
rescue
|
475
|
+
" " # Roflcopter crashes from time to time..
|
476
|
+
end
|
477
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rofltim
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Annesley
|
8
|
+
- Dennis Hotson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2022-07-28 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Tim edition of an ASCII side-scrolling game, with ANSI color!
|
15
|
+
email:
|
16
|
+
- paul@annesley.cc
|
17
|
+
executables:
|
18
|
+
- roflbalt
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- README.md
|
23
|
+
- bin/roflbalt
|
24
|
+
- lib/roflbalt.rb
|
25
|
+
homepage: https://github.com/pda/roflbalt
|
26
|
+
licenses: []
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubygems_version: 3.0.3.1
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: Canabalt-inspired ASCII side-scroller for your terminal, with ANSI color!
|
47
|
+
test_files: []
|