chingu 0.5.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +21 -0
- data/LICENSE +504 -0
- data/Manifest.txt +72 -0
- data/README.rdoc +588 -0
- data/Rakefile +19 -0
- data/benchmarks/README.txt +1 -0
- data/benchmarks/benchmark.rb +6 -0
- data/benchmarks/benchmark3.rb +23 -0
- data/benchmarks/benchmark4.rb +71 -0
- data/benchmarks/benchmark5.rb +91 -0
- data/benchmarks/benchmark6.rb +23 -0
- data/benchmarks/meta_benchmark.rb +67 -0
- data/benchmarks/meta_benchmark2.rb +39 -0
- data/chingu.gemspec +34 -0
- data/examples/example1.rb +37 -0
- data/examples/example10.rb +75 -0
- data/examples/example11.rb +51 -0
- data/examples/example12.rb +67 -0
- data/examples/example2.rb +115 -0
- data/examples/example3.rb +40 -0
- data/examples/example4.rb +175 -0
- data/examples/example5.rb +107 -0
- data/examples/example6.rb +57 -0
- data/examples/example7.rb +133 -0
- data/examples/example8.rb +109 -0
- data/examples/example9.rb +106 -0
- data/examples/media/Parallax-scroll-example-layer-0.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-1.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-2.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-3.png +0 -0
- data/examples/media/background1.png +0 -0
- data/examples/media/fire_bullet.png +0 -0
- data/examples/media/fireball.png +0 -0
- data/examples/media/particle.png +0 -0
- data/examples/media/ruby.png +0 -0
- data/examples/media/spaceship.png +0 -0
- data/examples/media/stickfigure.bmp +0 -0
- data/examples/media/stickfigure.png +0 -0
- data/examples/media/video_games.png +0 -0
- data/lib/chingu.rb +32 -0
- data/lib/chingu/actor.rb +17 -0
- data/lib/chingu/animation.rb +142 -0
- data/lib/chingu/assets.rb +64 -0
- data/lib/chingu/basic_game_object.rb +132 -0
- data/lib/chingu/core_extensions.rb +53 -0
- data/lib/chingu/effects.rb +36 -0
- data/lib/chingu/fpscounter.rb +62 -0
- data/lib/chingu/game_object.rb +127 -0
- data/lib/chingu/game_object_list.rb +91 -0
- data/lib/chingu/game_state.rb +137 -0
- data/lib/chingu/game_state_manager.rb +284 -0
- data/lib/chingu/game_states/debug.rb +65 -0
- data/lib/chingu/game_states/fade_to.rb +91 -0
- data/lib/chingu/game_states/pause.rb +57 -0
- data/lib/chingu/gfx_helpers.rb +89 -0
- data/lib/chingu/helpers.rb +166 -0
- data/lib/chingu/inflector.rb +34 -0
- data/lib/chingu/input.rb +100 -0
- data/lib/chingu/named_resource.rb +254 -0
- data/lib/chingu/parallax.rb +83 -0
- data/lib/chingu/particle.rb +21 -0
- data/lib/chingu/rect.rb +612 -0
- data/lib/chingu/require_all.rb +133 -0
- data/lib/chingu/text.rb +56 -0
- data/lib/chingu/traits/collision_detection.rb +172 -0
- data/lib/chingu/traits/effect.rb +113 -0
- data/lib/chingu/traits/input.rb +38 -0
- data/lib/chingu/traits/retrofy.rb +53 -0
- data/lib/chingu/traits/rotation_center.rb +84 -0
- data/lib/chingu/traits/timer.rb +90 -0
- data/lib/chingu/traits/velocity.rb +67 -0
- data/lib/chingu/window.rb +170 -0
- metadata +162 -0
- metadata.gz.sig +1 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C)2009 Tony Arcieri
|
3
|
+
# You can redistribute this under the terms of the MIT license
|
4
|
+
# See file LICENSE for details
|
5
|
+
#++
|
6
|
+
|
7
|
+
module RequireAll
|
8
|
+
# A wonderfully simple way to load your code.
|
9
|
+
#
|
10
|
+
# The easiest way to use require_all is to just point it at a directory
|
11
|
+
# containing a bunch of .rb files. These files can be nested under
|
12
|
+
# subdirectories as well:
|
13
|
+
#
|
14
|
+
# require_all 'lib'
|
15
|
+
#
|
16
|
+
# This will find all the .rb files under the lib directory and load them.
|
17
|
+
# The proper order to load them in will be determined automatically.
|
18
|
+
#
|
19
|
+
# If the dependencies between the matched files are unresolvable, it will
|
20
|
+
# throw the first unresolvable NameError.
|
21
|
+
#
|
22
|
+
# You can also give it a glob, which will enumerate all the matching files:
|
23
|
+
#
|
24
|
+
# require_all 'lib/**/*.rb'
|
25
|
+
#
|
26
|
+
# It will also accept an array of files:
|
27
|
+
#
|
28
|
+
# require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
|
29
|
+
#
|
30
|
+
# Or if you want, just list the files directly as arguments:
|
31
|
+
#
|
32
|
+
# require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
|
33
|
+
#
|
34
|
+
def require_all(*args)
|
35
|
+
# Handle passing an array as an argument
|
36
|
+
args.flatten!
|
37
|
+
|
38
|
+
if args.size > 1
|
39
|
+
# If we got a list, those be are files!
|
40
|
+
files = args
|
41
|
+
else
|
42
|
+
arg = args.first
|
43
|
+
begin
|
44
|
+
# Try assuming we're doing plain ol' require compat
|
45
|
+
stat = File.stat(arg)
|
46
|
+
|
47
|
+
if stat.file?
|
48
|
+
files = [arg]
|
49
|
+
elsif stat.directory?
|
50
|
+
files = Dir.glob File.join(arg, '**', '*.rb')
|
51
|
+
else
|
52
|
+
raise ArgumentError, "#{arg} isn't a file or directory"
|
53
|
+
end
|
54
|
+
rescue Errno::ENOENT
|
55
|
+
# If the stat failed, maybe we have a glob!
|
56
|
+
files = Dir.glob arg
|
57
|
+
|
58
|
+
# Maybe it's an .rb file and the .rb was omitted
|
59
|
+
if File.file?(arg + '.rb')
|
60
|
+
require(arg + '.rb')
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
|
64
|
+
# If we ain't got no files, the glob failed
|
65
|
+
raise LoadError, "no such file to load -- #{arg}" if files.empty?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# If there's nothing to load, you're doing it wrong!
|
70
|
+
raise LoadError, "no files to load" if files.empty?
|
71
|
+
|
72
|
+
files.map! { |file| File.expand_path file }
|
73
|
+
|
74
|
+
begin
|
75
|
+
failed = []
|
76
|
+
first_name_error = nil
|
77
|
+
|
78
|
+
# Attempt to load each file, rescuing which ones raise NameError for
|
79
|
+
# undefined constants. Keep trying to successively reload files that
|
80
|
+
# previously caused NameErrors until they've all been loaded or no new
|
81
|
+
# files can be loaded, indicating unresolvable dependencies.
|
82
|
+
files.each do |file|
|
83
|
+
begin
|
84
|
+
require file
|
85
|
+
rescue NameError => ex
|
86
|
+
failed << file
|
87
|
+
first_name_error ||= ex
|
88
|
+
rescue ArgumentError => ex
|
89
|
+
# Work around ActiveSuport freaking out... *sigh*
|
90
|
+
#
|
91
|
+
# ActiveSupport sometimes throws these exceptions and I really
|
92
|
+
# have no idea why. Code loading will work successfully if these
|
93
|
+
# exceptions are swallowed, although I've run into strange
|
94
|
+
# nondeterministic behaviors with constants mysteriously vanishing.
|
95
|
+
# I've gone spelunking through dependencies.rb looking for what
|
96
|
+
# exactly is going on, but all I ended up doing was making my eyes
|
97
|
+
# bleed.
|
98
|
+
#
|
99
|
+
# FIXME: If you can understand ActiveSupport's dependencies.rb
|
100
|
+
# better than I do I would *love* to find a better solution
|
101
|
+
raise unless ex.message["is not missing constant"]
|
102
|
+
|
103
|
+
STDERR.puts "Warning: require_all swallowed ActiveSupport 'is not missing constant' error"
|
104
|
+
STDERR.puts ex.backtrace[0..9]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# If this pass didn't resolve any NameErrors, we've hit an unresolvable
|
109
|
+
# dependency, so raise one of the exceptions we encountered.
|
110
|
+
if failed.size == files.size
|
111
|
+
raise first_name_error
|
112
|
+
else
|
113
|
+
files = failed
|
114
|
+
end
|
115
|
+
end until failed.empty?
|
116
|
+
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
# Works like require_all, but paths are relative to the caller rather than
|
121
|
+
# the current working directory
|
122
|
+
def require_rel(*paths)
|
123
|
+
# Handle passing an array as an argument
|
124
|
+
paths.flatten!
|
125
|
+
|
126
|
+
source_directory = File.dirname caller.first.sub(/:\d+$/, '')
|
127
|
+
paths.each do |path|
|
128
|
+
require_all File.join(source_directory, path)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
include RequireAll
|
data/lib/chingu/text.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
module Chingu
|
2
|
+
#
|
3
|
+
# Text is a class to give the use of Gosu::Font more rubyish feel and fit it better into Chingu.
|
4
|
+
# Pure Gosu:
|
5
|
+
# @font = Gosu::Font.new($window, "verdana", 30)
|
6
|
+
# @font.draw("A Text", 200, 50, 55, 2.0)
|
7
|
+
#
|
8
|
+
# Chingu
|
9
|
+
# @text = Chingu::Text.new(:text => "A Text", :x => 200, :y => 50, :zorder => 55, :factor_x => 2.0)
|
10
|
+
# @text.draw # usually not needed as Text is a GameObject and therefore autodrawn
|
11
|
+
#
|
12
|
+
# @text comes with a number of changable properties, x,y,zorder,angle,factor_x,color,mode etc.
|
13
|
+
#
|
14
|
+
class Text < Chingu::GameObject
|
15
|
+
attr_accessor :text
|
16
|
+
attr_reader :height, :gosu_font
|
17
|
+
|
18
|
+
@@size = nil
|
19
|
+
@@font = nil
|
20
|
+
def self.font; @@font; end
|
21
|
+
def self.font=(value); @@font = value; end
|
22
|
+
|
23
|
+
def self.size; @@size; end
|
24
|
+
def self.size=(value); @@size = value; end
|
25
|
+
def self.height; @@size; end
|
26
|
+
def self.height=(value); @@size = value; end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Takes the standard GameObject-hash-arguments but also:
|
30
|
+
# - :text - a string of text
|
31
|
+
# - :font_name|:font - name of a systemfont (default: "verdana")
|
32
|
+
# - :height|size - how many pixels high should the text be
|
33
|
+
#
|
34
|
+
def initialize(options)
|
35
|
+
super(options)
|
36
|
+
@text = options[:text] || "-No text specified-"
|
37
|
+
@font = options[:font] || @@font || default_font_name()
|
38
|
+
@height = options[:height] || options[:size] || @@size || 15
|
39
|
+
|
40
|
+
@gosu_font = Gosu::Font.new($window, @font, @height)
|
41
|
+
end
|
42
|
+
|
43
|
+
def draw
|
44
|
+
@gosu_font.draw_rot(@text, @x.to_i, @y.to_i, @zorder, @angle, @factor_x, @factor_y, @color, @mode)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Returns the width, in pixels, the given text would occupy if drawn.
|
49
|
+
#
|
50
|
+
def width
|
51
|
+
@gosu_font.text_width(@text, @factor_x)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# Chingu -- Game framework built on top of the opengl accelerated gamelib Gosu
|
4
|
+
# Copyright (C) 2009 ippa / ippa@rubylicio.us
|
5
|
+
#
|
6
|
+
# This library is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
8
|
+
# License as published by the Free Software Foundation; either
|
9
|
+
# version 2.1 of the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
|
22
|
+
|
23
|
+
module Chingu
|
24
|
+
module Traits
|
25
|
+
#
|
26
|
+
# Research:
|
27
|
+
# 1) QuadTrees: http://lab.polygonal.de/2007/09/09/quadtree-demonstration/
|
28
|
+
# 2) Sweep and Prune
|
29
|
+
#
|
30
|
+
# SEE: http://www.shmup-dev.com/forum/index.php?board=65.0
|
31
|
+
#
|
32
|
+
# Makes use of 3 attributes
|
33
|
+
# @bounding_box - a Rect-instance, uses in bounding_box collisions
|
34
|
+
# @radius -
|
35
|
+
# @detect_collisions - [true|false], should object be checked for collisions with Object.each_collision
|
36
|
+
#
|
37
|
+
module CollisionDetection
|
38
|
+
attr_accessor :bounding_box, :radius
|
39
|
+
## attr_accessor :detect_collisions # slowed down example9 with 3 fps
|
40
|
+
|
41
|
+
def self.included(base)
|
42
|
+
base.extend(ClassMethods)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Automaticly try to set a bounding_box and radius. Don't overwrite if they already exists.
|
47
|
+
#
|
48
|
+
def setup_trait(options)
|
49
|
+
if @x and @y and @image
|
50
|
+
@bounding_box ||= Rect.new(@x, @y, @image.width, @image.height)
|
51
|
+
end
|
52
|
+
|
53
|
+
if @image
|
54
|
+
@radius ||= (@image.height + @image.width) / 2 * 0.80
|
55
|
+
end
|
56
|
+
|
57
|
+
## @detect_collisions = true
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# The standard method called when self needs to be checked for a collision with another object
|
63
|
+
# By default it calls bounding_box_collision? which will check for intersectons between the
|
64
|
+
# two objects "bounding_box" attributs (a Chingu::Rect instance)
|
65
|
+
#
|
66
|
+
def collides?(object2)
|
67
|
+
bounding_box_collision?(object2)
|
68
|
+
#radius_collision?(object2)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Collide self with a given game object by checking both objects bounding_box'es
|
73
|
+
# Returns true if colliding.
|
74
|
+
#
|
75
|
+
def bounding_box_collision?(object2)
|
76
|
+
self.bounding_box.collide_rect?(object2.bounding_box)
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Collide self using distance between 2 objects and their radius.
|
81
|
+
# Returns true if colliding.
|
82
|
+
#
|
83
|
+
def radius_collision?(object2)
|
84
|
+
distance(self.x, self.y, object2.x, object2.y) < self.radius + object2.radius
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Have bounding box follow game objects x/y
|
89
|
+
#
|
90
|
+
def update_trait
|
91
|
+
if defined?(@bounding_box) && @bounding_box.is_a?(Rect)
|
92
|
+
@bounding_box.x = self.x
|
93
|
+
@bounding_box.y = self.y
|
94
|
+
end
|
95
|
+
|
96
|
+
super
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# Collides self with all objects of given classes
|
101
|
+
# Yields self and the objects it collides with
|
102
|
+
#
|
103
|
+
def each_collision(klasses = [])
|
104
|
+
Array(klasses).each do |klass|
|
105
|
+
klass.all.each do |object|
|
106
|
+
yield(self, object) if collides?(object)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Works like each_collsion but with inline-code for speedups
|
113
|
+
#
|
114
|
+
def each_radius_collision(klasses = [])
|
115
|
+
Array(klasses).each do |klass|
|
116
|
+
klass.all.each do |object|
|
117
|
+
yield(self, object) if distance(@x, @y, object.x, object.y) < @radius + object.radius
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
module ClassMethods
|
125
|
+
|
126
|
+
#
|
127
|
+
# Works like each_collsion but with inline-code for speedups
|
128
|
+
#
|
129
|
+
def each_radius_collision(klasses = [])
|
130
|
+
Array(klasses).each do |klass|
|
131
|
+
object2_list = klass.all
|
132
|
+
#total_radius = object1.radius + object2.radius # possible optimization?
|
133
|
+
|
134
|
+
self.all.each do |object1|
|
135
|
+
object2_list.each do |object2|
|
136
|
+
next if object1 == object2 # Don't collide objects with themselves
|
137
|
+
yield object1, object2 if distance(object1.x, object1.y, object2.x, object2.y) < object1.radius + object2.radius
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
#
|
144
|
+
# Class method that will check for collisions between all instances of two classes
|
145
|
+
# and yield the 2 colliding game object instances.
|
146
|
+
#
|
147
|
+
# It will not collide objects with themselves.
|
148
|
+
#
|
149
|
+
# example:
|
150
|
+
#
|
151
|
+
# Enemy.each_collision(Bullet).each do |enemy, bullet| enemy.die!; end
|
152
|
+
#
|
153
|
+
#
|
154
|
+
def each_collision(klasses = [])
|
155
|
+
# Make sure klasses is always an array.
|
156
|
+
Array(klasses).each do |klass|
|
157
|
+
object2_list = klass.all
|
158
|
+
|
159
|
+
self.all.each do |object1|
|
160
|
+
object2_list.all.each do |object2|
|
161
|
+
next if object1 == object2 # Don't collide objects with themselves
|
162
|
+
yield object1, object2 if object1.collides?(object2)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# Chingu -- Game framework built on top of the opengl accelerated gamelib Gosu
|
4
|
+
# Copyright (C) 2009 ippa / ippa@rubylicio.us
|
5
|
+
#
|
6
|
+
# This library is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
8
|
+
# License as published by the Free Software Foundation; either
|
9
|
+
# version 2.1 of the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
#
|
20
|
+
#++
|
21
|
+
|
22
|
+
|
23
|
+
module Chingu
|
24
|
+
module Traits
|
25
|
+
module Effect
|
26
|
+
#
|
27
|
+
# Adds .rotating .fading and .zooming to any GameObject.
|
28
|
+
#
|
29
|
+
# TODO: better naming? suggestions:
|
30
|
+
#
|
31
|
+
# basic gosu unit <-> automation name
|
32
|
+
# ==============================================
|
33
|
+
# angle <-> rotation? rotating? automatic_angle?
|
34
|
+
# factor <-> growth? scale? automatic_zoom?
|
35
|
+
# alpha <-> fade
|
36
|
+
#
|
37
|
+
attr_accessor :rotating, :fading, :zooming
|
38
|
+
|
39
|
+
#def self.initialize_trait(options)
|
40
|
+
# @effect_options = {:debug => false}.merge(options)
|
41
|
+
# puts "Effect#initialize" if @effect_options[:debug]
|
42
|
+
# super
|
43
|
+
#end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Setup
|
47
|
+
#
|
48
|
+
def setup_trait(options)
|
49
|
+
@effect_options = {:debug => false}.merge(options)
|
50
|
+
puts "Effect#setup" if @effect_options[:debug]
|
51
|
+
|
52
|
+
@rotating = options[:rotating] || nil
|
53
|
+
@zooming = options[:zooming] || nil
|
54
|
+
@fading = options[:fading] || nil
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
def draw_trait
|
59
|
+
puts "Effect#draw" if @effect_options[:debug]
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def update_trait
|
64
|
+
puts "Effect#update" if @effect_options[:debug]
|
65
|
+
|
66
|
+
rotate(@rotating) if @rotating
|
67
|
+
fade(@fading) if @fading
|
68
|
+
zoom(@zooming) if @zooming
|
69
|
+
super
|
70
|
+
end
|
71
|
+
|
72
|
+
# Zoom - increase @factor_x and @factor_y at the same time.
|
73
|
+
def zoom(amount = 0.1)
|
74
|
+
@factor_x += amount
|
75
|
+
@factor_y += amount
|
76
|
+
end
|
77
|
+
|
78
|
+
# Zoom Out - decrease @factor_x and @factor_y at the same time.
|
79
|
+
def zoom_out(amount = 0.1)
|
80
|
+
@factor_x -= amount
|
81
|
+
@factor_y -= amount
|
82
|
+
end
|
83
|
+
|
84
|
+
# Rotate object 'amount' degrees
|
85
|
+
def rotate(amount = 1)
|
86
|
+
@angle += amount
|
87
|
+
end
|
88
|
+
|
89
|
+
# Fade object by decreasing/increasing color.alpha
|
90
|
+
def fade(amount = 1)
|
91
|
+
return if amount == 0
|
92
|
+
|
93
|
+
new_alpha = @color.alpha + amount
|
94
|
+
if amount < 0
|
95
|
+
@color.alpha = [0, new_alpha].max
|
96
|
+
else
|
97
|
+
@color.alpha = [0, new_alpha].min
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Fade out objects color by decreasing color.alpha
|
102
|
+
def fade_out(amount = 1)
|
103
|
+
fade(-amount)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Fade in objects color by increasing color.alpha
|
107
|
+
def fade_in(amount = 1)
|
108
|
+
fade(amount)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|