shoes 4.0.0.pre11 → 4.0.0.pre12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/shoes-stub +8 -0
- data/lib/shoes/samples.rb +8 -0
- data/samples/README +122 -0
- data/samples/avatar.png +0 -0
- data/samples/blue-box.png +0 -0
- data/samples/class-book.yaml +387 -0
- data/samples/class_book.rb +46 -0
- data/samples/cy.png +0 -0
- data/samples/expert_definr.rb +24 -0
- data/samples/expert_funnies.rb +60 -0
- data/samples/expert_game_of_life.rb +224 -0
- data/samples/expert_irb.rb +109 -0
- data/samples/expert_minesweeper.rb +272 -0
- data/samples/expert_othello.rb +323 -0
- data/samples/expert_pong.rb +69 -0
- data/samples/expert_snake.rb +88 -0
- data/samples/expert_tankspank.rb +425 -0
- data/samples/expert_tetris.rb +322 -0
- data/samples/good_arc.rb +51 -0
- data/samples/good_bounce.rb +34 -0
- data/samples/good_clock.rb +55 -0
- data/samples/good_displace.rb +99 -0
- data/samples/good_follow.rb +27 -0
- data/samples/good_image_dl.rb +13 -0
- data/samples/good_potato_chopping.rb +23 -0
- data/samples/good_psychidelic_circles.rb +73 -0
- data/samples/good_reminder.rb +163 -0
- data/samples/good_vjot.rb +65 -0
- data/samples/lib/require_me.rb +6 -0
- data/samples/loogink.png +0 -0
- data/samples/menu-corner1.png +0 -0
- data/samples/menu-corner2.png +0 -0
- data/samples/menu-gray.png +0 -0
- data/samples/menu-left.png +0 -0
- data/samples/menu-right.png +0 -0
- data/samples/menu-top.png +0 -0
- data/samples/nks_booklist.rb +25 -0
- data/samples/nks_breadsticks.rb +8 -0
- data/samples/nks_dancing_circle.rb +14 -0
- data/samples/nks_dictionary.rb +24 -0
- data/samples/nks_edit_box.rb +5 -0
- data/samples/nks_edit_line.rb +7 -0
- data/samples/nks_notes.rb +16 -0
- data/samples/nks_poem.rb +23 -0
- data/samples/nks_self.rb +7 -0
- data/samples/nks_text_sizes.rb +11 -0
- data/samples/nks_trurl.rb +6 -0
- data/samples/potato_chopping/1258_s001.gif +0 -0
- data/samples/potato_chopping/1258_s002.gif +0 -0
- data/samples/potato_chopping/1258_s003.gif +0 -0
- data/samples/potato_chopping/1258_s004.gif +0 -0
- data/samples/potato_chopping/1258_s005.gif +0 -0
- data/samples/potato_chopping/1258_s006.gif +0 -0
- data/samples/potato_chopping/1258_s007.gif +0 -0
- data/samples/potato_chopping/1258_s008.gif +0 -0
- data/samples/potato_chopping/1258_s009.gif +0 -0
- data/samples/potato_chopping/1258_s010.gif +0 -0
- data/samples/potato_chopping/1258_s011.gif +0 -0
- data/samples/potato_chopping/1258_s012.gif +0 -0
- data/samples/potato_chopping/1258_s013.gif +0 -0
- data/samples/potato_chopping/1258_s014.gif +0 -0
- data/samples/potato_chopping/1258_s015.gif +0 -0
- data/samples/potato_chopping/1258_s016.gif +0 -0
- data/samples/potato_chopping/1258_s017.gif +0 -0
- data/samples/potato_chopping/1258_s018.gif +0 -0
- data/samples/potato_chopping/1258_s019.gif +0 -0
- data/samples/potato_chopping/1258_s020.gif +0 -0
- data/samples/potato_chopping/1258_s021.gif +0 -0
- data/samples/potato_chopping/1258_s022.gif +0 -0
- data/samples/potato_chopping/1258_s023.gif +0 -0
- data/samples/potato_chopping/1258_s024.gif +0 -0
- data/samples/potato_chopping/1258_s025.gif +0 -0
- data/samples/potato_chopping/1258_s026.gif +0 -0
- data/samples/potato_chopping/1258_s027.gif +0 -0
- data/samples/potato_chopping/1258_s028.gif +0 -0
- data/samples/potato_chopping/1258_s029.gif +0 -0
- data/samples/potato_chopping/1258_s030.gif +0 -0
- data/samples/potato_chopping/1258_s031.gif +0 -0
- data/samples/potato_chopping/1258_s032.gif +0 -0
- data/samples/potato_chopping/1258_s033.gif +0 -0
- data/samples/potato_chopping/1258_s034.gif +0 -0
- data/samples/potato_chopping/1258_s035.gif +0 -0
- data/samples/potato_chopping/1258_s036.gif +0 -0
- data/samples/potato_chopping/1258_s037.gif +0 -0
- data/samples/potato_chopping/1258_s038.gif +0 -0
- data/samples/potato_chopping/1258_s039.gif +0 -0
- data/samples/potato_chopping/1258_s040.gif +0 -0
- data/samples/potato_chopping/1258_s041.gif +0 -0
- data/samples/potato_chopping/1258_s042.gif +0 -0
- data/samples/potato_chopping/1258_s043.gif +0 -0
- data/samples/potato_chopping/1258_s044.gif +0 -0
- data/samples/potato_chopping/1258_s045.gif +0 -0
- data/samples/potato_chopping/1258_s046.gif +0 -0
- data/samples/potato_chopping/1258_s047.gif +0 -0
- data/samples/potato_chopping/1258_s048.gif +0 -0
- data/samples/potato_chopping/1258_s049.gif +0 -0
- data/samples/potato_chopping/1258_s050.gif +0 -0
- data/samples/potato_chopping/1258_s051.gif +0 -0
- data/samples/potato_chopping/1258_s052.gif +0 -0
- data/samples/potato_chopping/1258_s053.gif +0 -0
- data/samples/potato_chopping/1258_s054.gif +0 -0
- data/samples/potato_chopping/1258_s055.gif +0 -0
- data/samples/potato_chopping/1258_s056.gif +0 -0
- data/samples/potato_chopping/1258_s057.gif +0 -0
- data/samples/potato_chopping/1258_s058.gif +0 -0
- data/samples/potato_chopping/1258_s059.gif +0 -0
- data/samples/red-box.png +0 -0
- data/samples/shape_arc_to.rb +10 -0
- data/samples/simple-form.shy +0 -0
- data/samples/simple_accordion.rb +98 -0
- data/samples/simple_alert.rb +10 -0
- data/samples/simple_altered_para.rb +11 -0
- data/samples/simple_anim_shapes.rb +18 -0
- data/samples/simple_anim_text.rb +14 -0
- data/samples/simple_animate.rb +12 -0
- data/samples/simple_arc.rb +25 -0
- data/samples/simple_attach.rb +26 -0
- data/samples/simple_border_image.rb +9 -0
- data/samples/simple_borderless.rb +4 -0
- data/samples/simple_bounce.rb +27 -0
- data/samples/simple_breadsticks.rb +11 -0
- data/samples/simple_breadsticks2.rb +11 -0
- data/samples/simple_brightness_transitions.rb +16 -0
- data/samples/simple_button_animate.rb +17 -0
- data/samples/simple_buttons.rb +4 -0
- data/samples/simple_calc.rb +67 -0
- data/samples/simple_calc_2.rb +49 -0
- data/samples/simple_clipboard.rb +17 -0
- data/samples/simple_color_selector.rb +11 -0
- data/samples/simple_color_transitions.rb +12 -0
- data/samples/simple_concentric_circles.rb +9 -0
- data/samples/simple_console.rb +12 -0
- data/samples/simple_control_sizes.rb +25 -0
- data/samples/simple_count_and_draw.rb +19 -0
- data/samples/simple_curve.rb +34 -0
- data/samples/simple_dialogs.rb +33 -0
- data/samples/simple_dialogs_outside.rb +17 -0
- data/samples/simple_displace.rb +16 -0
- data/samples/simple_downloader.rb +29 -0
- data/samples/simple_draw.rb +16 -0
- data/samples/simple_editor.rb +30 -0
- data/samples/simple_face.rb +15 -0
- data/samples/simple_flashing.rb +22 -0
- data/samples/simple_flow_wrap.rb +12 -0
- data/samples/simple_font.rb +18 -0
- data/samples/simple_form.rb +30 -0
- data/samples/simple_fullscreen.rb +5 -0
- data/samples/simple_gradient_shapes.rb +23 -0
- data/samples/simple_guess_game.rb +30 -0
- data/samples/simple_image_as_stroke.rb +22 -0
- data/samples/simple_image_fill.rb +13 -0
- data/samples/simple_image_stroke.rb +13 -0
- data/samples/simple_info.rb +10 -0
- data/samples/simple_iterated_content.rb +8 -0
- data/samples/simple_keypress.rb +15 -0
- data/samples/simple_logo_display.rb +15 -0
- data/samples/simple_loogink_cy.rb +33 -0
- data/samples/simple_lorem_ipsum.rb +19 -0
- data/samples/simple_manual.rb +5 -0
- data/samples/simple_menu.rb +42 -0
- data/samples/simple_mouse_follow.rb +9 -0
- data/samples/simple_oval.rb +6 -0
- data/samples/simple_polygon_line.rb +19 -0
- data/samples/simple_position_as_we_go.rb +10 -0
- data/samples/simple_progress_bar.rb +15 -0
- data/samples/simple_random_bubbles.rb +15 -0
- data/samples/simple_require.rb +9 -0
- data/samples/simple_sample_executor.rb +7 -0
- data/samples/simple_sample_executor_all.rb +14 -0
- data/samples/simple_sesame_street_shoes.rb +6 -0
- data/samples/simple_shoes_intro.rb +22 -0
- data/samples/simple_slide.rb +57 -0
- data/samples/simple_stack_flow_buttons.rb +16 -0
- data/samples/simple_stripes.rb +9 -0
- data/samples/simple_system_background.rb +5 -0
- data/samples/simple_text_movement.rb +8 -0
- data/samples/simple_tictactoe.rb +224 -0
- data/samples/simple_timer.rb +16 -0
- data/samples/simple_translate.rb +10 -0
- data/samples/simple_visibility.rb +20 -0
- metadata +186 -7
@@ -0,0 +1,322 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#==================================================================================================
|
3
|
+
#
|
4
|
+
# A Tetris game for Ruby Shoes
|
5
|
+
#
|
6
|
+
# Controls:
|
7
|
+
#
|
8
|
+
# left/right - slide the piece horizontally
|
9
|
+
# up - rotate the piece 90 degrees clockwise
|
10
|
+
# down - drop the piece faster
|
11
|
+
# esc - quit the game
|
12
|
+
#
|
13
|
+
# For more details see http://codeincomplete.com/posts/2014/11/7/tetris_shoes/
|
14
|
+
#
|
15
|
+
|
16
|
+
#==================================================================================================
|
17
|
+
# Game Constants
|
18
|
+
#==================================================================================================
|
19
|
+
|
20
|
+
WIDTH = 300 # width of tetris court (in pixels)
|
21
|
+
HEIGHT = 600 # height of tetris court (in pixels)
|
22
|
+
NX = 10 # width of tetris court (in blocks)
|
23
|
+
NY = 20 # height of tetris court (in blocks)
|
24
|
+
DX = WIDTH / NX # pixel width of a single tetris block
|
25
|
+
DY = HEIGHT / NY # pixel height of a single tetris block
|
26
|
+
FPS = 60 # game animation frame rate (fps)
|
27
|
+
|
28
|
+
PACE = { start: 0.5, step: 0.005, min: 0.1 }.freeze # how long before a piece drops by 1 row (seconds)
|
29
|
+
SCORE = { line: 100, multiplier: 2 }.freeze # score per line removed (100) and bonus multiplier when multiple lines cleared in a the same drop
|
30
|
+
|
31
|
+
#==================================================================================================
|
32
|
+
# The 7 Tetromino Types
|
33
|
+
#==================================================================================================
|
34
|
+
#
|
35
|
+
# blocks: each element represents a rotation of the piece (0, 90, 180, 270)
|
36
|
+
# each element is a 16 bit integer where the 16 bits represent
|
37
|
+
# a 4x4 set of blocks, e.g. j.blocks[0] = 0x44C0
|
38
|
+
#
|
39
|
+
# 0100 = 0x4 << 3 = 0x4000
|
40
|
+
# 0100 = 0x4 << 2 = 0x0400
|
41
|
+
# 1100 = 0xC << 1 = 0x00C0
|
42
|
+
# 0000 = 0x0 << 0 = 0x0000
|
43
|
+
# ------
|
44
|
+
# 0x44C0
|
45
|
+
#
|
46
|
+
# (see http://codeincomplete.com/posts/2011/10/10/javascript_tetris/)
|
47
|
+
#
|
48
|
+
|
49
|
+
I = { blocks: {up: 0x0F00, right: 0x2222, down: 0x00F0, left: 0x4444}, color: '#00FFFF', size: 4 }.freeze
|
50
|
+
J = { blocks: {up: 0x44C0, right: 0x8E00, down: 0x6440, left: 0x0E20}, color: '#0000FF', size: 3 }.freeze
|
51
|
+
L = { blocks: {up: 0x4460, right: 0x0E80, down: 0xC440, left: 0x2E00}, color: '#FF8000', size: 3 }.freeze
|
52
|
+
O = { blocks: {up: 0xCC00, right: 0xCC00, down: 0xCC00, left: 0xCC00}, color: '#FFFF00', size: 2 }.freeze
|
53
|
+
S = { blocks: {up: 0x06C0, right: 0x8C40, down: 0x6C00, left: 0x4620}, color: '#00FF00', size: 3 }.freeze
|
54
|
+
T = { blocks: {up: 0x0E40, right: 0x4C40, down: 0x4E00, left: 0x4640}, color: '#8040FF', size: 3 }.freeze
|
55
|
+
Z = { blocks: {up: 0x0C60, right: 0x4C80, down: 0xC600, left: 0x2640}, color: '#FF0000', size: 3 }.freeze
|
56
|
+
|
57
|
+
#==================================================================================================
|
58
|
+
# The Game Runner
|
59
|
+
#==================================================================================================
|
60
|
+
|
61
|
+
class Tetris
|
62
|
+
attr_reader :dt, # time since the current active piece last dropped a row
|
63
|
+
:score, # the current score
|
64
|
+
:lost, # bool to indicate when the game is lost
|
65
|
+
:pace, # current game pace - how long until the current piece drops a single row
|
66
|
+
:blocks, # 2 dimensional array (NX*NY) represeting the tetris court - either empty block or occupied by a piece
|
67
|
+
:actions, # queue of user inputs collected by the game loop
|
68
|
+
:bag, # a collection of random pieces to be used
|
69
|
+
:current # the current active piece
|
70
|
+
|
71
|
+
#----------------------------------------------------------------------------
|
72
|
+
|
73
|
+
def initialize
|
74
|
+
@dt = 0
|
75
|
+
@score = 0
|
76
|
+
@pace = PACE[:start]
|
77
|
+
@blocks = Array.new(NX) { Array.new(NY) } # awkward way to initialize an already sized 2 dimensional array
|
78
|
+
@actions = []
|
79
|
+
@bag = new_bag
|
80
|
+
@current = random_piece
|
81
|
+
end
|
82
|
+
|
83
|
+
#----------------------------------------------------------------------------
|
84
|
+
|
85
|
+
def update(seconds)
|
86
|
+
action = actions.shift
|
87
|
+
case action
|
88
|
+
when :left then move(:left)
|
89
|
+
when :right then move(:right)
|
90
|
+
when :rotate then rotate
|
91
|
+
when :drop then drop
|
92
|
+
end
|
93
|
+
|
94
|
+
@dt += seconds
|
95
|
+
if dt > pace
|
96
|
+
@dt = dt - pace
|
97
|
+
drop
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#----------------------------------------------------------------------------
|
102
|
+
|
103
|
+
def move(direction)
|
104
|
+
nextup = current.move(direction)
|
105
|
+
if unoccupied(nextup)
|
106
|
+
choose_new_piece(nextup)
|
107
|
+
true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def rotate
|
112
|
+
nextup = current.rotate
|
113
|
+
if unoccupied(nextup)
|
114
|
+
choose_new_piece(nextup)
|
115
|
+
true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def drop
|
120
|
+
unless move(:down)
|
121
|
+
finalize_piece
|
122
|
+
reward_for_piece
|
123
|
+
remove_any_completed_lines
|
124
|
+
clear_pending_actions
|
125
|
+
choose_new_piece
|
126
|
+
lose if occupied(current)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
#----------------------------------------------------------------------------
|
131
|
+
|
132
|
+
def unoccupied(piece)
|
133
|
+
!occupied(piece)
|
134
|
+
end
|
135
|
+
|
136
|
+
def occupied(piece)
|
137
|
+
piece.each_occupied_block do |x, y|
|
138
|
+
if x.negative? || (x >= NX) || y.negative? || (y >= NY) || blocks[x][y]
|
139
|
+
return true
|
140
|
+
end
|
141
|
+
end
|
142
|
+
false
|
143
|
+
end
|
144
|
+
|
145
|
+
#----------------------------------------------------------------------------
|
146
|
+
|
147
|
+
def finalize_piece
|
148
|
+
current.each_occupied_block { |x, y| blocks[x][y] = current.tetromino }
|
149
|
+
end
|
150
|
+
|
151
|
+
def choose_new_piece(piece = nil)
|
152
|
+
@current = piece || random_piece
|
153
|
+
end
|
154
|
+
|
155
|
+
def reward_for_piece
|
156
|
+
@score = score + 10
|
157
|
+
end
|
158
|
+
|
159
|
+
def reward_lines(lines)
|
160
|
+
@score = score + (SCORE[:line] * SCORE[:multiplier]**(lines - 1)) # e.g. 1: 100, 2: 200, 3: 400, 4: 800
|
161
|
+
@pace = [pace - lines * PACE[:step], PACE[:min]].max
|
162
|
+
end
|
163
|
+
|
164
|
+
def clear_pending_actions
|
165
|
+
actions.clear
|
166
|
+
end
|
167
|
+
|
168
|
+
def lose
|
169
|
+
@lost = true
|
170
|
+
end
|
171
|
+
|
172
|
+
def lost?
|
173
|
+
@lost
|
174
|
+
end
|
175
|
+
|
176
|
+
def new_bag
|
177
|
+
[I, I, I, I, J, J, J, J, L, L, L, L, O, O, O, O, S, S, S, S, T, T, T, T, Z, Z, Z, Z].shuffle
|
178
|
+
end
|
179
|
+
|
180
|
+
def random_piece
|
181
|
+
@bag = new_bag if bag.empty?
|
182
|
+
Piece.new(bag.pop)
|
183
|
+
end
|
184
|
+
|
185
|
+
#----------------------------------------------------------------------------
|
186
|
+
|
187
|
+
def remove_any_completed_lines
|
188
|
+
lines = 0
|
189
|
+
NY.times do |y|
|
190
|
+
unless NX.times.any? { |x| blocks[x][y].nil? }
|
191
|
+
remove_line(y)
|
192
|
+
lines += 1
|
193
|
+
end
|
194
|
+
end
|
195
|
+
reward_lines(lines) unless lines.zero?
|
196
|
+
end
|
197
|
+
|
198
|
+
def remove_line(n)
|
199
|
+
n.downto(0) do |y|
|
200
|
+
NX.times do |x|
|
201
|
+
blocks[x][y] = y.zero? ? nil : blocks[x][y - 1]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
#----------------------------------------------------------------------------
|
207
|
+
|
208
|
+
def each_occupied_block
|
209
|
+
NY.times do |y|
|
210
|
+
NX.times do |x|
|
211
|
+
yield x, y, blocks[x][y][:color] unless blocks[x][y].nil?
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end # class Tetris
|
216
|
+
|
217
|
+
#==================================================================================================
|
218
|
+
# A Game Piece
|
219
|
+
#==================================================================================================
|
220
|
+
|
221
|
+
class Piece
|
222
|
+
attr_reader :tetromino, # the tetromino type
|
223
|
+
:direction, # the rotation direction (:up, :down, :left, :right)
|
224
|
+
:x, :y # the (x,y) position on the board
|
225
|
+
|
226
|
+
#----------------------------------------------------------------------------
|
227
|
+
|
228
|
+
def initialize(tetromino, x = nil, y = nil, direction = nil)
|
229
|
+
@tetromino = tetromino
|
230
|
+
@direction = direction || :up
|
231
|
+
@x = x || rand(NX - tetromino[:size]) # default to a random horizontal position (that fits)
|
232
|
+
@y = y || 0
|
233
|
+
end
|
234
|
+
|
235
|
+
#----------------------------------------------------------------------------
|
236
|
+
|
237
|
+
def rotate
|
238
|
+
newdir = case direction
|
239
|
+
when :left then :up
|
240
|
+
when :up then :right
|
241
|
+
when :right then :down
|
242
|
+
when :down then :left
|
243
|
+
end
|
244
|
+
Piece.new(tetromino, x, y, newdir)
|
245
|
+
end
|
246
|
+
|
247
|
+
def move(direction)
|
248
|
+
case direction
|
249
|
+
when :right then Piece.new(tetromino, x + 1, y, @direction)
|
250
|
+
when :left then Piece.new(tetromino, x - 1, y, @direction)
|
251
|
+
when :down then Piece.new(tetromino, x, y + 1, @direction)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
#----------------------------------------------------------------------------
|
256
|
+
|
257
|
+
def each_occupied_block # a bit complex, for more details see - http://codeincomplete.com/posts/2011/10/10/javascript_tetris/
|
258
|
+
bit = 0b1000000000000000
|
259
|
+
row = 0
|
260
|
+
col = 0
|
261
|
+
blocks = tetromino[:blocks][direction]
|
262
|
+
until bit.zero?
|
263
|
+
yield x + col, y + row if (blocks & bit) == bit
|
264
|
+
col += 1
|
265
|
+
if col == 4
|
266
|
+
col = 0
|
267
|
+
row += 1
|
268
|
+
end
|
269
|
+
bit = bit >> 1
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end # class Piece
|
273
|
+
|
274
|
+
#==================================================================================================
|
275
|
+
# The SHOES application
|
276
|
+
#==================================================================================================
|
277
|
+
|
278
|
+
Shoes.app title: 'Tetris', width: WIDTH, height: HEIGHT do
|
279
|
+
game = Tetris.new
|
280
|
+
|
281
|
+
keypress do |k|
|
282
|
+
case k
|
283
|
+
when :left then game.actions << :left
|
284
|
+
when :right then game.actions << :right
|
285
|
+
when :down then game.actions << :drop
|
286
|
+
when :up then game.actions << :rotate
|
287
|
+
when :escape then quit
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def block(x, y, color)
|
292
|
+
fill color
|
293
|
+
rect(x * DX, y * DY, DX, DY)
|
294
|
+
end
|
295
|
+
|
296
|
+
last = Time.now
|
297
|
+
animate = animate FPS do
|
298
|
+
now = Time.now
|
299
|
+
|
300
|
+
game.update(now - last)
|
301
|
+
clear
|
302
|
+
|
303
|
+
game.each_occupied_block do |x, y, color|
|
304
|
+
block(x, y, color)
|
305
|
+
end
|
306
|
+
|
307
|
+
game.current.each_occupied_block do |x, y|
|
308
|
+
block(x, y, game.current.tetromino[:color])
|
309
|
+
end
|
310
|
+
|
311
|
+
if game.lost?
|
312
|
+
banner "Game Over", align: 'center', stroke: black
|
313
|
+
animate.stop
|
314
|
+
else
|
315
|
+
subtitle "Score: #{format('%6.6d', game.score)}", stroke: green, align: 'right'
|
316
|
+
end
|
317
|
+
|
318
|
+
last = now
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
#==================================================================================================
|
data/samples/good_arc.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# a translation from a processing example
|
4
|
+
# http://vormplus.be/weging/an-introduction-to-processing/
|
5
|
+
#
|
6
|
+
Shoes.app width: 420, height: 420, resizable: false do
|
7
|
+
stage = 0
|
8
|
+
wide = 3
|
9
|
+
sw = 1.0
|
10
|
+
basesize = 600
|
11
|
+
step = 60
|
12
|
+
stroke white(100)
|
13
|
+
nofill
|
14
|
+
|
15
|
+
animate 40 do |i|
|
16
|
+
stage = rand(1...8) if (i % 40).zero?
|
17
|
+
if wide.abs < 0.1
|
18
|
+
wide = if stage == 6
|
19
|
+
-0.1
|
20
|
+
else
|
21
|
+
0.1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
rotation = -(Shoes::HALF_PI / wide)
|
25
|
+
clear do
|
26
|
+
background gray(240)
|
27
|
+
10.times do |j|
|
28
|
+
strokewidth sw * j
|
29
|
+
size = (basesize + step * j) / 3
|
30
|
+
top = (height - size) / 2
|
31
|
+
left = (width - size) / 2
|
32
|
+
arc top, left,
|
33
|
+
size, size,
|
34
|
+
rotation * j,
|
35
|
+
rotation * j + Shoes::TWO_PI - Shoes::HALF_PI
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
case stage
|
40
|
+
when 1 then wide -= 0.1
|
41
|
+
when 2 then wide += 0.1
|
42
|
+
when 3 then basesize -= 1
|
43
|
+
when 4 then basesize += 2
|
44
|
+
when 5 then sw += 0.1
|
45
|
+
when 6 then sw = [sw - 0.1, 0.1].max
|
46
|
+
when 7 then step += 2
|
47
|
+
else
|
48
|
+
step -= 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# The Shoes logo/icon bounces on the screen. The logo/icon responds to menu options and if clicked on.
|
3
|
+
xspeed = 10
|
4
|
+
yspeed = 6
|
5
|
+
xdir = 1
|
6
|
+
ydir = 1
|
7
|
+
|
8
|
+
Shoes.app width: 300, height: 300 do
|
9
|
+
a = nil
|
10
|
+
button('toggle') { a.toggle }
|
11
|
+
button('stop') { a.stop }
|
12
|
+
button('start') { a.start }
|
13
|
+
button('remove') { a.remove }
|
14
|
+
img = image File.join(Shoes::DIR, 'static/shoes-icon.png'),
|
15
|
+
click: ->() { alert "You're soooo quick!" }
|
16
|
+
|
17
|
+
x = 150
|
18
|
+
y = 150
|
19
|
+
size = [128, 128]
|
20
|
+
pause = 0
|
21
|
+
|
22
|
+
a = animate 24 do |n|
|
23
|
+
unless pause == n
|
24
|
+
x += xspeed * xdir
|
25
|
+
y += yspeed * ydir
|
26
|
+
|
27
|
+
xdir *= -1 if x > 300 - size[0] || x.negative?
|
28
|
+
ydir *= -1 if y > 300 - size[1] || y.negative?
|
29
|
+
|
30
|
+
img.move x.to_i, y.to_i
|
31
|
+
end
|
32
|
+
pause = n
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Shoes Clock by Thomas Bell
|
4
|
+
# posted to the Shoes mailing list on 04 Dec 2007
|
5
|
+
#
|
6
|
+
Shoes.app height: 260, width: 250 do
|
7
|
+
@radius = 90
|
8
|
+
@centerx = 126
|
9
|
+
@centery = 140
|
10
|
+
animate(8) do
|
11
|
+
@time = Time.now
|
12
|
+
clear do
|
13
|
+
draw_background
|
14
|
+
stack do
|
15
|
+
background black
|
16
|
+
para @time.strftime("%a"),
|
17
|
+
span(@time.strftime(" %b %d, %Y "), stroke: "#ccc"),
|
18
|
+
strong(@time.strftime("%I:%M"), stroke: white),
|
19
|
+
@time.strftime(".%S"), align: "center", stroke: "#666",
|
20
|
+
margin: 4
|
21
|
+
end
|
22
|
+
clock_hand @time.sec + (@time.usec * 0.000001), 2, 30, red
|
23
|
+
clock_hand @time.min + (@time.sec / 60.0), 5
|
24
|
+
clock_hand @time.hour + (@time.min / 60.0), 8, 6
|
25
|
+
end
|
26
|
+
end
|
27
|
+
def draw_background
|
28
|
+
background rgb(230, 240, 200)
|
29
|
+
|
30
|
+
fill white
|
31
|
+
stroke black
|
32
|
+
strokewidth 4
|
33
|
+
oval @centerx - 102, @centery - 102, 204, 204
|
34
|
+
|
35
|
+
fill black
|
36
|
+
nostroke
|
37
|
+
oval @centerx - 5, @centery - 5, 10, 10
|
38
|
+
|
39
|
+
stroke black
|
40
|
+
strokewidth 1
|
41
|
+
line(@centerx, @centery - 102, @centerx, @centery - 95)
|
42
|
+
line(@centerx - 102, @centery, @centerx - 95, @centery)
|
43
|
+
line(@centerx + 95, @centery, @centerx + 102, @centery)
|
44
|
+
line(@centerx, @centery + 95, @centerx, @centery + 102)
|
45
|
+
end
|
46
|
+
|
47
|
+
def clock_hand(time, sw, unit = 30, color = black)
|
48
|
+
radius_local = unit == 30 ? @radius : @radius - 15
|
49
|
+
x = radius_local * Math.sin(time * Math::PI / unit)
|
50
|
+
y = radius_local * Math.cos(time * Math::PI / unit)
|
51
|
+
stroke color
|
52
|
+
strokewidth sw
|
53
|
+
line(@centerx, @centery, @centerx + x, @centery - y)
|
54
|
+
end
|
55
|
+
end
|