tween 0.1

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.
data/Manifest ADDED
@@ -0,0 +1,5 @@
1
+ Manifest
2
+ README.markdown
3
+ Rakefile
4
+ examples/demo.rb
5
+ lib/tween.rb
data/README.markdown ADDED
@@ -0,0 +1,21 @@
1
+ # Tween
2
+
3
+ Tween is a library for doing fluid motion in Ruby. It's primarily a port of
4
+ Robert Penner's easing calculations to Ruby. It has no dependencies, but it was
5
+ written for using with Gosu.
6
+
7
+ ### What do they do?
8
+
9
+ Tweening is a technique for fluid animation. It will find a number of steps
10
+ between two points, allows something to transition smoothly between point A and
11
+ point B. While it's easy to code a linear interpolation yourself, there are a
12
+ number of **easings** in this library you can use.
13
+
14
+ An **easing** is a method of transitioning between two points *more* smoothly
15
+ than linear interpolation. Linear interpolation has sudden starts and stops,
16
+ and a constant velocity. Using an easing such as **Tween::Quart::InOut** will
17
+ make the object start moving slowly, accelerate, decelerate and arrive at its
18
+ destination gracefully.
19
+
20
+ For usage and a visual demonstration of what this really is, install Gosu
21
+ and run demo.rb in the examples directory.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('tween', '0.1') do |p|
6
+ p.description = "Fluid motion using tweens for Ruby"
7
+ p.url = "http://ruby.about.com/"
8
+ p.author = "Michael Morin"
9
+ p.email = "michael.c.morin@gmail.com"
10
+ p.ignore_pattern = %w{ examples/Rakefile examples/images/* }
11
+ end
data/examples/demo.rb ADDED
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'gosu'
4
+ require 'yaml'
5
+ require 'tempfile'
6
+ require 'base64'
7
+ require 'tween'
8
+
9
+
10
+ $data = YAML.parse(DATA.read)
11
+
12
+ def with_data(key,&block)
13
+ Tempfile.open(File.basename(__FILE__)) do |tmp|
14
+ tmp.binmode
15
+ tmp.write( Base64.decode64($data[key].value) )
16
+ tmp.close
17
+
18
+ block.call(tmp.path)
19
+ end
20
+ end
21
+
22
+
23
+
24
+ module Z
25
+ Background, Graph, Text, Ball = (1..100).to_a
26
+ end
27
+
28
+ class MyWindow < Gosu::Window
29
+ WIDTH = 640
30
+ HEIGHT = 480
31
+ TITLE = "Tween Demo"
32
+
33
+ TOP_COLOR = Gosu::Color.new(0xFFF5F5F5)
34
+ BOTTOM_COLOR = Gosu::Color.new(0xFFBEBEBE)
35
+ GRAPH_COLOR = Gosu::Color::BLACK
36
+
37
+
38
+
39
+ def initialize
40
+ super(WIDTH, HEIGHT, false)
41
+ self.caption = TITLE
42
+
43
+ @last_frame = Gosu::milliseconds
44
+
45
+ with_data('globe.png') do |png|
46
+ @ball = Gosu::Image.new(self, png, false)
47
+ end
48
+
49
+ @font = Gosu::Font.new(self, Gosu::default_font_name, 20)
50
+ @smallfont = Gosu::Font.new(self, Gosu::default_font_name, 15)
51
+
52
+ @x, @y = width / 2, height / 2
53
+ @tween = nil
54
+ @easer = Tween::EASERS[0]
55
+ end
56
+
57
+
58
+
59
+ def update
60
+ calculate_delta
61
+ end
62
+
63
+ def calculate_delta
64
+ @this_frame = Gosu::milliseconds
65
+ @delta = (@this_frame - @last_frame) / 1000.0
66
+
67
+ # Update game objects here
68
+ unless @tween.nil? or @tween.done
69
+ @tween.update(@delta)
70
+ @x, @y = @tween.x, @tween.y
71
+ end
72
+
73
+ @last_frame = @this_frame
74
+ end
75
+
76
+
77
+
78
+ def draw
79
+ draw_background
80
+ draw_graph
81
+ draw_easer_name
82
+ draw_instructions
83
+ draw_ball
84
+ end
85
+
86
+ def draw_ball
87
+ @ball.draw(
88
+ @x - (@ball.width / 2),
89
+ @y - (@ball.height / 2),
90
+ Z::Ball
91
+ )
92
+ end
93
+
94
+ def draw_background
95
+ draw_quad(
96
+ 0, 0, TOP_COLOR,
97
+ WIDTH, 0, TOP_COLOR,
98
+ 0, HEIGHT, BOTTOM_COLOR,
99
+ WIDTH, HEIGHT, BOTTOM_COLOR,
100
+ Z::Background)
101
+ end
102
+
103
+ def draw_graph
104
+ left = width * 0.2
105
+ right = left + width * 0.6
106
+ bottom = height * 0.8
107
+ top = bottom - height * 0.6
108
+
109
+ draw_line(
110
+ left, top, GRAPH_COLOR,
111
+ left, bottom + 20, GRAPH_COLOR,
112
+ Z::Graph
113
+ )
114
+
115
+ draw_line(
116
+ left - 20, bottom, GRAPH_COLOR,
117
+ right, bottom, GRAPH_COLOR,
118
+ Z::Graph
119
+ )
120
+
121
+ graph = (0..100).map do |idx|
122
+ @easer.ease(idx, bottom, top - bottom, 100.0)
123
+ end
124
+
125
+ (1..99).map do |idx|
126
+ draw_line(
127
+ left + Tween::Linear.ease(idx - 1, 0, right - left, 100),
128
+ graph[idx - 1],
129
+ GRAPH_COLOR,
130
+
131
+ left + Tween::Linear.ease(idx, 0, right - left, 100),
132
+ graph[idx],
133
+ GRAPH_COLOR,
134
+
135
+ Z::Graph
136
+ )
137
+ end
138
+ end
139
+
140
+ def draw_easer_name
141
+ @font.draw(
142
+ @easer.to_s,
143
+ 10, 10, Z::Text,
144
+ 1.0, 1.0,
145
+ GRAPH_COLOR
146
+ )
147
+ end
148
+
149
+ def draw_instructions
150
+ @smallfont.draw(
151
+ "Click to move globe, press left and right to change easer",
152
+ 20, height - 20, Z::Text,
153
+ 1.0, 1.0,
154
+ GRAPH_COLOR
155
+ )
156
+ end
157
+
158
+
159
+ def needs_cursor?
160
+ true
161
+ end
162
+
163
+ def button_down(id)
164
+ case id
165
+ when Gosu::MsLeft
166
+ @tween = Tween.new(
167
+ [@x.to_f, @y.to_f],
168
+ [mouse_x.to_f, mouse_y.to_f],
169
+ @easer,
170
+ 1
171
+ )
172
+
173
+ when Gosu::KbEscape
174
+ close
175
+
176
+ when Gosu::KbRight
177
+ next_easer
178
+
179
+ when Gosu::KbLeft
180
+ last_easer
181
+ end
182
+ end
183
+
184
+
185
+ def next_easer
186
+ idx = Tween::EASERS.index(@easer) + 1
187
+
188
+ if idx == Tween::EASERS.length
189
+ idx = 0
190
+ end
191
+
192
+ @easer = Tween::EASERS[idx]
193
+ end
194
+
195
+ def last_easer
196
+ idx = Tween::EASERS.index(@easer) - 1
197
+
198
+ if idx == -1
199
+ idx = Tween::EASERS.length - 1
200
+ end
201
+
202
+ @easer = Tween::EASERS[idx]
203
+ end
204
+ end
205
+
206
+ MyWindow.new.show
207
+
208
+ __END__
209
+ ---
210
+ globe.png: |
211
+ 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
320
+
data/lib/tween.rb ADDED
@@ -0,0 +1,383 @@
1
+ # This is a tweening library for Ruby. It has no dependencies, but was
2
+ # designed with Gosu in mind.
3
+
4
+ # This is mostly an implementation of Robert Penner's easing equations
5
+ # More information on the equations can be found here:
6
+ # http://www.robertpenner.com/easing/
7
+ #
8
+ # UziMonkey <michael.c.morin@gmail.com>
9
+
10
+ class Tween
11
+ attr_reader :done
12
+ attr_reader :easer
13
+
14
+ def initialize(start, finish, easer, duration)
15
+ @start, @finish = start, finish
16
+ @easer, @duration = easer, duration
17
+
18
+ @time = 0
19
+ @done = false
20
+ end
21
+
22
+ def update(delta)
23
+ @time += delta
24
+ if @time > @duration
25
+ @time = @duration
26
+ @done = true
27
+ end
28
+ end
29
+
30
+ def [](idx)
31
+ @easer.ease(
32
+ @time,
33
+ @start[idx],
34
+ (@finish[idx] - @start[idx]),
35
+ @duration
36
+ )
37
+ end
38
+
39
+ def x; self[0]; end
40
+ def y; self[1]; end
41
+ def z; self[2]; end
42
+
43
+ # In the following ease methods:
44
+ # st = start
45
+ # t = time
46
+ # d = duration
47
+ # ch = change
48
+
49
+ # I know, these are quite messy. I don't know 100% what's going on in many
50
+ # of them, but they're translated from Penner's ActionScript code which was
51
+ # uncommented and rather indecipherable.
52
+ module Linear
53
+ def self.ease(t, st, ch, d)
54
+ ch * t / d + st
55
+ end
56
+ end
57
+
58
+ module Sine
59
+ module In
60
+ def self.ease(t, st, ch, d)
61
+ -ch * Math.cos(t / d * (Math::PI / 2)) + ch + st
62
+ end
63
+ end
64
+
65
+ module Out
66
+ def self.ease(t, st, ch, d)
67
+ ch * Math.sin(t / d * (Math::PI / 2)) + st
68
+ end
69
+ end
70
+
71
+ module InOut
72
+ def self.ease(t, st, ch, d)
73
+ -ch / 2 * (Math.cos(Math::PI * t / d) - 1) + st
74
+ end
75
+ end
76
+ end
77
+
78
+ module Circ
79
+ module In
80
+ def self.ease(t, st, ch, d)
81
+ -ch * (Math.sqrt(1 - (t/d) * t/d) - 1) + st
82
+ end
83
+ end
84
+
85
+ module Out
86
+ def self.ease(t, st, ch, d)
87
+ t = t/d - 1
88
+ ch * Math.sqrt(1 - t * t) + st
89
+ end
90
+ end
91
+
92
+ module InOut
93
+ def self.ease(t, st, ch, d)
94
+ if (t /= d/2.0) < 1
95
+ return -ch / 2 * (Math.sqrt(1 - t*t) - 1) + st
96
+ else
97
+ return ch / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + st
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ module Bounce
104
+ module Out
105
+ def self.ease(t, st, ch, d)
106
+ if (t /= d) < (1/2.75)
107
+ ch * (7.5625 * t * t) + st
108
+ elsif t < (2 / 2.75)
109
+ ch * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + st
110
+ elsif t < (2.5 / 2.75)
111
+ ch * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + st
112
+ else
113
+ ch * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + st
114
+ end
115
+ end
116
+ end
117
+
118
+ module In
119
+ def self.ease(t, st, ch, d)
120
+ ch - Tween::Bounce::Out.ease(d-t, 0, ch, d) + st
121
+ end
122
+ end
123
+
124
+ module InOut
125
+ def self.ease(t, st, ch, d)
126
+ if t < d/2.0
127
+ Tween::Bounce::In.ease(t*2.0, 0, ch, d) * 0.5 + st
128
+ else
129
+ Tween::Bounce::Out.ease(t*2.0 - d, 0, ch, d) * 0.5 + ch * 0.5 + st
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ module Back
136
+ module In
137
+ def self.ease(t, st, ch, d, s=1.70158)
138
+ ch * (t/=d) * t * ((s+1) * t - s) + st
139
+ end
140
+ end
141
+
142
+ module Out
143
+ def self.ease(t, st, ch, d, s=1.70158)
144
+ ch * ((t=t/d-1) * t * ((s+1) * t + s) + 1) + st
145
+ end
146
+ end
147
+
148
+ module InOut
149
+ def self.ease(t, st, ch, d, s=1.70158)
150
+ if (t /= d/2.0) < 1
151
+ ch / 2.0 * (t * t * (((s *= (1.525)) + 1) * t - s)) + st
152
+ else
153
+ ch / 2.0 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + st
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ module Cubic
160
+ module In
161
+ def self.ease(t, st, ch, d)
162
+ ch * (t /= d) * t * t + st
163
+ end
164
+ end
165
+
166
+ module Out
167
+ def self.ease(t, st, ch, d)
168
+ ch * ((t = t / d.to_f - 1) * t * t + 1) + st
169
+ end
170
+ end
171
+
172
+ module InOut
173
+ def self.ease(t, st, ch, d)
174
+ if (t /= d / 2.0) < 1
175
+ ch / 2.0 * t * t * t + st
176
+ else
177
+ ch / 2.0 * ((t -= 2) * t * t + 2) + st
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ module Expo
184
+ module In
185
+ def self.ease(t, st, ch, d)
186
+ if t == 0
187
+ st
188
+ else
189
+ ch * (2 ** (10 * (t / d.to_f - 1))) + st
190
+ end
191
+ end
192
+ end
193
+
194
+ module Out
195
+ def self.ease(t, st, ch, d)
196
+ if t == d
197
+ st + ch
198
+ else
199
+ ch * (-(2 ** (-10 * t / d.to_f)) + 1) + st
200
+ end
201
+ end
202
+ end
203
+
204
+ module InOut
205
+ def self.ease(t, st, ch, d)
206
+ if t == 0
207
+ st
208
+ elsif t == d
209
+ st + ch
210
+ elsif (t /= d / 2.0) < 1
211
+ ch / 2.0 * (2 ** (10 * (t - 1))) + st
212
+ else
213
+ ch / 2.0 * (-(2 ** (-10 * (t -= 1))) + 2) + st
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ module Quad
220
+ module In
221
+ def self.ease(t, st, ch, d)
222
+ ch * (t /= d.to_f) * t + st
223
+ end
224
+ end
225
+
226
+ module Out
227
+ def self.ease(t, st, ch, d)
228
+ -ch * (t /= d.to_f) * (t - 2) + st
229
+ end
230
+ end
231
+
232
+ module InOut
233
+ def self.ease(t, st, ch, d)
234
+ if (t /= d / 2.0) < 1
235
+ ch / 2.0 * t * t + st
236
+ else
237
+ -ch / 2.0 * ((t -= 1) * (t - 2) - 1) + st
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ module Quart
244
+ module In
245
+ def self.ease(t, st, ch, d)
246
+ ch * (t /= d.to_f) * t * t * t + st
247
+ end
248
+ end
249
+
250
+ module Out
251
+ def self.ease(t, st, ch, d)
252
+ -ch * ((t = t / d.to_f - 1) * t * t * t - 1) + st
253
+ end
254
+ end
255
+
256
+ module InOut
257
+ def self.ease(t, st, ch, d)
258
+ if (t /= d / 2.0) < 1
259
+ ch / 2.0 * t * t * t * t + st
260
+ else
261
+ -ch / 2.0 * ((t -= 2) * t * t * t - 2) + st
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ module Quint
268
+ module In
269
+ def self.ease(t, st, ch, d)
270
+ ch * (t /= d.to_f) * t * t * t * t + st
271
+ end
272
+ end
273
+
274
+ module Out
275
+ def self.ease(t, st, ch, d)
276
+ ch * ((t = t / d.to_f - 1) * t * t *t * t + 1) + st
277
+ end
278
+ end
279
+
280
+ module InOut
281
+ def self.ease(t, st, ch, d)
282
+ if (t /= d / 2.0) < 1
283
+ ch / 2.0 * t * t *t * t * t + st
284
+ else
285
+ ch / 2.0 * ((t -= 2) * t * t * t * t + 2) + st
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ module Elastic
292
+ module In
293
+ def self.ease(t, st, ch, d, a = 5, p = 0)
294
+ s = 0
295
+
296
+ if t == 0
297
+ return st
298
+ elsif (t /= d.to_f) >= 1
299
+ return st + ch
300
+ end
301
+
302
+ p = d * 0.3 if p == 0
303
+
304
+ if (a == 0) || (a < ch.abs)
305
+ a = ch
306
+ s = p / 4.0
307
+ else
308
+ s = p / (2 * Math::PI) * Math.asin(ch / a.to_f)
309
+ end
310
+
311
+ -(a * (2 ** (10 * (t -= 1))) * Math.sin( (t * d - s) * (2 * Math::PI) / p)) + st
312
+ end
313
+ end
314
+
315
+ module Out
316
+ def self.ease(t, st, ch, d, a = 0.1, p = 0)
317
+ s = 0
318
+
319
+ if t == 0
320
+ return st
321
+ elsif (t /= d.to_f) >= 1
322
+ return st + ch
323
+ end
324
+
325
+ p = d * 0.3 if p == 0
326
+
327
+ if (a == 0) || (a < ch.abs)
328
+ a = ch
329
+ s = p / 4.0
330
+ else
331
+ s = p / (2 * Math::PI) * Math.asin(ch / a.to_f)
332
+ end
333
+
334
+ a * (2 ** (-10 * t)) * Math.sin((t * d - s) * (2 * Math::PI) / p.to_f) + ch + st
335
+ end
336
+ end
337
+ end
338
+
339
+ # This is mostly for use by demo.rb
340
+ EASERS = [
341
+ Linear,
342
+
343
+ Sine::In,
344
+ Sine::Out,
345
+ Sine::InOut,
346
+
347
+ Circ::In,
348
+ Circ::Out,
349
+ Circ::InOut,
350
+
351
+ Bounce::Out,
352
+ Bounce::In,
353
+ Bounce::InOut,
354
+
355
+ Back::In,
356
+ Back::Out,
357
+ Back::InOut,
358
+
359
+ Cubic::In,
360
+ Cubic::Out,
361
+ Cubic::InOut,
362
+
363
+ Expo::In,
364
+ Expo::Out,
365
+ Expo::InOut,
366
+
367
+ Quad::In,
368
+ Quad::Out,
369
+ Quad::InOut,
370
+
371
+ Quart::In,
372
+ Quart::Out,
373
+ Quart::InOut,
374
+
375
+ Quint::In,
376
+ Quint::Out,
377
+ Quint::InOut,
378
+
379
+ Elastic::In,
380
+ Elastic::Out
381
+ ]
382
+
383
+ end
data/tween.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{tween}
5
+ s.version = "0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Michael Morin"]
9
+ s.date = %q{2010-10-01}
10
+ s.description = %q{Fluid motion using tweens for Ruby}
11
+ s.email = %q{michael.c.morin@gmail.com}
12
+ s.extra_rdoc_files = ["README.markdown", "lib/tween.rb"]
13
+ s.files = ["Manifest", "README.markdown", "Rakefile", "examples/demo.rb", "lib/tween.rb", "tween.gemspec"]
14
+ s.homepage = %q{http://ruby.about.com/}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Tween", "--main", "README.markdown"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{tween}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Fluid motion using tweens for Ruby}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tween
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ version: "0.1"
9
+ platform: ruby
10
+ authors:
11
+ - Michael Morin
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-10-01 00:00:00 -04:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: Fluid motion using tweens for Ruby
21
+ email: michael.c.morin@gmail.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files:
27
+ - README.markdown
28
+ - lib/tween.rb
29
+ files:
30
+ - Manifest
31
+ - README.markdown
32
+ - Rakefile
33
+ - examples/demo.rb
34
+ - lib/tween.rb
35
+ - tween.gemspec
36
+ has_rdoc: true
37
+ homepage: http://ruby.about.com/
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --line-numbers
43
+ - --inline-source
44
+ - --title
45
+ - Tween
46
+ - --main
47
+ - README.markdown
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 1
65
+ - 2
66
+ version: "1.2"
67
+ requirements: []
68
+
69
+ rubyforge_project: tween
70
+ rubygems_version: 1.3.7
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Fluid motion using tweens for Ruby
74
+ test_files: []
75
+