gamebox 0.2.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -8
- data/Rakefile +13 -37
- data/TODO.txt +27 -27
- data/docs/getting_started.rdoc +2 -2
- data/gamebox.gemspec +33 -191
- data/lib/gamebox.rb +18 -14
- data/lib/gamebox/actor.rb +37 -27
- data/lib/gamebox/actor_factory.rb +4 -5
- data/lib/gamebox/actor_view.rb +8 -0
- data/lib/gamebox/actors/collidable_debugger.rb +2 -2
- data/lib/gamebox/actors/curtain.rb +3 -3
- data/lib/gamebox/actors/emitter.rb +51 -0
- data/lib/gamebox/actors/label.rb +27 -7
- data/lib/gamebox/actors/logo.rb +1 -1
- data/lib/gamebox/actors/spatial_debugger.rb +25 -10
- data/lib/gamebox/arbiter.rb +61 -34
- data/lib/gamebox/behavior.rb +3 -3
- data/lib/gamebox/behaviors/animated.rb +1 -1
- data/lib/gamebox/behaviors/audible.rb +1 -1
- data/lib/gamebox/behaviors/collidable.rb +9 -4
- data/lib/gamebox/behaviors/collidable/aabb_collidable.rb +26 -1
- data/lib/gamebox/behaviors/collidable/circle_collidable.rb +3 -3
- data/lib/gamebox/behaviors/collidable/polygon_collidable.rb +1 -1
- data/lib/gamebox/behaviors/graphical.rb +30 -4
- data/lib/gamebox/behaviors/layered.rb +1 -1
- data/lib/gamebox/behaviors/physical.rb +113 -30
- data/lib/gamebox/behaviors/timed.rb +33 -0
- data/lib/gamebox/behaviors/updatable.rb +1 -1
- data/lib/gamebox/class_finder.rb +1 -21
- data/lib/gamebox/console_app.rb +33 -31
- data/lib/gamebox/constants.rb +481 -0
- data/lib/gamebox/data/config/objects.yml +7 -0
- data/lib/gamebox/gamebox_application.rb +10 -33
- data/lib/gamebox/gamebox_generator.rb +32 -32
- data/lib/gamebox/input_manager.rb +73 -32
- data/lib/gamebox/lib/inflector.rb +1 -1
- data/lib/gamebox/lib/range_ext.rb +5 -0
- data/lib/gamebox/lib/rect.rb +548 -548
- data/lib/gamebox/lib/sorted_list.rb +1 -1
- data/lib/gamebox/lib/symbol_ext.rb +8 -0
- data/lib/gamebox/physical_director.rb +1 -1
- data/lib/gamebox/physical_stage.rb +3 -3
- data/lib/gamebox/physics.rb +0 -3
- data/lib/gamebox/resource_manager.rb +22 -17
- data/lib/gamebox/sound_manager.rb +3 -2
- data/lib/gamebox/spatial_hash.rb +60 -31
- data/lib/gamebox/spatial_stagehand.rb +30 -6
- data/lib/gamebox/spec/helper.rb +7 -7
- data/lib/gamebox/stage.rb +18 -19
- data/lib/gamebox/stage_manager.rb +33 -23
- data/lib/gamebox/stagehand.rb +3 -0
- data/lib/gamebox/svg_document.rb +1 -1
- data/lib/gamebox/tasks/gamebox_tasks.rake +133 -0
- data/lib/gamebox/templates/actor.erb +0 -2
- data/lib/gamebox/templates/actor_view.erb +1 -3
- data/lib/gamebox/templates/template_app/Gemfile +3 -2
- data/lib/gamebox/templates/template_app/Rakefile +3 -8
- data/lib/gamebox/templates/template_app/config/environment.rb +7 -39
- data/lib/gamebox/templates/template_app/src/demo_stage.rb +1 -2
- data/lib/gamebox/templates/template_app/src/my_actor.rb +0 -3
- data/lib/gamebox/version.rb +2 -2
- data/lib/gamebox/viewport.rb +44 -8
- data/lib/gamebox/views/graphical_actor_view.rb +22 -16
- data/lib/gamebox/wrapped_screen.rb +9 -1
- data/script/perf_spatial_hash.rb +49 -58
- data/script/perf_struct_vs_array.rb +32 -0
- data/spec/actor_factory_spec.rb +61 -0
- data/spec/actor_spec.rb +24 -18
- data/spec/actor_view_spec.rb +51 -6
- data/spec/animated_spec.rb +27 -6
- data/spec/arbiter_spec.rb +12 -24
- data/spec/backstage_spec.rb +1 -1
- data/spec/behavior_spec.rb +3 -3
- data/spec/class_finder_spec.rb +13 -0
- data/spec/collidable_spec.rb +30 -10
- data/spec/emitter_spec.rb +20 -0
- data/spec/helper.rb +5 -21
- data/spec/input_manager_spec.rb +134 -0
- data/spec/label_spec.rb +0 -1
- data/spec/physical_spec.rb +114 -5
- data/spec/resource_manager_spec.rb +1 -2
- data/spec/spatial_hash_spec.rb +23 -7
- data/spec/spatial_stagehand_spec.rb +97 -0
- data/spec/stage_manager_spec.rb +0 -1
- data/spec/stage_spec.rb +2 -2
- data/spec/viewport_spec.rb +92 -48
- metadata +223 -119
- data/.gitignore +0 -11
- data/History.txt +0 -80
- data/VERSION +0 -1
- data/lib/gamebox/event_compat.rb +0 -285
- data/lib/gamebox/lib/diy.rb +0 -371
- data/lib/gamebox/lib/numbers_ext.rb +0 -3
- data/lib/gamebox/tasks/gamebox_tasks.rb +0 -61
- data/load_paths.rb +0 -20
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'inflector'
|
2
|
-
require 'stage'
|
3
1
|
class StageManager
|
4
2
|
|
5
3
|
constructor :resource_manager, :actor_factory, :input_manager,
|
@@ -53,6 +51,10 @@ class StageManager
|
|
53
51
|
stage_instance.when :restart_stage do |*args|
|
54
52
|
restart_stage *args
|
55
53
|
end
|
54
|
+
stage_instance.when :change_stage do |stage_name, *args|
|
55
|
+
switch_to_stage stage_name, *args
|
56
|
+
end
|
57
|
+
|
56
58
|
|
57
59
|
stage_instance
|
58
60
|
end
|
@@ -63,10 +65,8 @@ class StageManager
|
|
63
65
|
puts "last stage, exiting"
|
64
66
|
exit
|
65
67
|
end
|
66
|
-
stage = @stages.delete @stage_names[index+1]
|
67
|
-
@input_manager.clear_hooks stage
|
68
68
|
|
69
|
-
|
69
|
+
switch_to_stage @stage_names[index+1], *args
|
70
70
|
end
|
71
71
|
|
72
72
|
def prev_stage(*args)
|
@@ -75,33 +75,22 @@ class StageManager
|
|
75
75
|
puts "first stage, exiting"
|
76
76
|
exit
|
77
77
|
end
|
78
|
-
|
79
|
-
@
|
80
|
-
change_stage_to @stage_names[index-1], *args
|
78
|
+
|
79
|
+
switch_to_stage @stage_names[index-1], *args
|
81
80
|
end
|
82
81
|
|
83
82
|
def restart_stage(*args)
|
84
83
|
current_stage.curtain_dropping *args
|
85
84
|
index = @stage_names.index @stage
|
86
85
|
|
87
|
-
|
88
|
-
@input_manager.clear_hooks stage
|
89
|
-
|
90
|
-
change_stage_to @stage, *args
|
86
|
+
switch_to_stage @stage, *args
|
91
87
|
end
|
92
88
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
96
|
-
@prev_stage.curtain_dropping *args
|
97
|
-
end
|
98
|
-
@stage = stage
|
99
|
-
@stage_args = args
|
100
|
-
unless @stages[@stage]
|
101
|
-
@stages[@stage] = create_stage(@stage, @stage_opts[@stage_names.index(@stage)])
|
102
|
-
end
|
103
|
-
@stages[@stage].curtain_raising *args
|
89
|
+
def switch_to_stage(stage_name, *args)
|
90
|
+
shutdown_current_stage *args
|
91
|
+
activate_new_stage stage_name, *args
|
104
92
|
end
|
93
|
+
alias :change_stage_to :switch_to_stage
|
105
94
|
|
106
95
|
def current_stage
|
107
96
|
@stages[@stage]
|
@@ -114,4 +103,25 @@ class StageManager
|
|
114
103
|
def draw(target)
|
115
104
|
@stages[@stage].draw target unless @stages[@stage].nil?
|
116
105
|
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def activate_new_stage(stage_name, *args)
|
110
|
+
@stage = stage_name
|
111
|
+
@stage_args = args
|
112
|
+
@stages[@stage] = create_stage(@stage, @stage_opts[@stage_names.index(@stage)])
|
113
|
+
@stages[@stage].curtain_raising *args
|
114
|
+
end
|
115
|
+
|
116
|
+
def shutdown_current_stage(*args)
|
117
|
+
if @stage and @stages and @stages[@stage]
|
118
|
+
current_stage = @stages[@stage]
|
119
|
+
current_stage.curtain_dropping *args
|
120
|
+
@input_manager.clear_hooks(current_stage)
|
121
|
+
@stages.delete @stage
|
122
|
+
@stage = nil
|
123
|
+
@stage_args = nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
117
127
|
end
|
data/lib/gamebox/stagehand.rb
CHANGED
data/lib/gamebox/svg_document.rb
CHANGED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'gamebox/lib/platform'
|
2
|
+
|
3
|
+
desc "Run the game"
|
4
|
+
task :run do |t|
|
5
|
+
sh "bundle exec ruby src/app.rb"
|
6
|
+
end
|
7
|
+
task :default => :run
|
8
|
+
|
9
|
+
desc "Report code statistics (KLOCs, etc) from the application"
|
10
|
+
task :stats do
|
11
|
+
require 'gamebox/lib/code_statistics'
|
12
|
+
CodeStatistics.new(*STATS_DIRECTORIES).to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
desc "Run the game with debug server"
|
17
|
+
task :debug do |t|
|
18
|
+
sh "ruby src/app.rb -debug-server"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Bundle in all required gems"
|
22
|
+
task :bundle do |t|
|
23
|
+
sh "bundle package"
|
24
|
+
sh "bundle install vendor/bundle --disable-shared-gems"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Run specs"
|
28
|
+
task :spec do
|
29
|
+
begin
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
|
32
|
+
RSpec::Core::RakeTask.new(:specz) do |t|
|
33
|
+
# t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
34
|
+
# Put spec opts in a file named .rspec in root
|
35
|
+
end
|
36
|
+
Rake::Task[:specz].execute
|
37
|
+
rescue LoadError
|
38
|
+
puts "warning: rspec not installed"
|
39
|
+
puts "install with gem install rspec"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
namespace :dist do
|
45
|
+
desc "Build a .app for your gamebox game"
|
46
|
+
task :mac do
|
47
|
+
GAME_NAME = "UntitledGame" unless defined?(GAME_NAME)
|
48
|
+
# DL template os x app
|
49
|
+
remote_file = "gosu-mac-wrapper-#{Gosu::VERSION}.tar.gz"
|
50
|
+
mac_build = "build/mac"
|
51
|
+
local_file = "#{mac_build}/#{remote_file}"
|
52
|
+
|
53
|
+
require 'net/http'
|
54
|
+
mkdir_p mac_build
|
55
|
+
# if false
|
56
|
+
Net::HTTP.start("www.libgosu.org") do |http|
|
57
|
+
resp = http.get("/downloads/#{remote_file}")
|
58
|
+
open(local_file, "wb") { |file| file.write(resp.body) }
|
59
|
+
end
|
60
|
+
# end
|
61
|
+
|
62
|
+
# Expand it
|
63
|
+
root = pwd
|
64
|
+
cd mac_build
|
65
|
+
`tar xzf #{remote_file}`
|
66
|
+
app_name = "#{GAME_NAME}.app"
|
67
|
+
contents = "#{app_name}/Contents"
|
68
|
+
resources = "#{contents}/Resources"
|
69
|
+
dot_app_lib = "#{resources}/lib"
|
70
|
+
gem_vendored = "#{mac_build}/#{resources}/gems"
|
71
|
+
|
72
|
+
mv 'RubyGosu App.app', app_name
|
73
|
+
%w(config data src).each do |src|
|
74
|
+
cp_r "../../#{src}", resources
|
75
|
+
end
|
76
|
+
|
77
|
+
# TODO remove chingu / chipmunk / etc
|
78
|
+
clean_em_out = %w(chingu chingu.rb).map{|it| "#{dot_app_lib}/#{it}"}
|
79
|
+
rm_rf clean_em_out#, :verbose => true, :noop => true
|
80
|
+
|
81
|
+
cd root
|
82
|
+
p `bundle --system package`
|
83
|
+
p `bundle package`
|
84
|
+
p `bundle --deployment`
|
85
|
+
mkdir_p gem_vendored
|
86
|
+
rejects = %w(chipmunk gosu)
|
87
|
+
Dir["vendor/bundle/ruby/**/gems/**/lib"].each do |gemmy|
|
88
|
+
cp_r gemmy, gem_vendored unless rejects.any?{|exclude| gemmy.match exclude}
|
89
|
+
end
|
90
|
+
|
91
|
+
cd mac_build
|
92
|
+
File.open "#{resources}/Main.rb", "w+" do |main|
|
93
|
+
main.puts <<-EOS
|
94
|
+
$: << "\#{File.dirname(__FILE__)}/config"
|
95
|
+
|
96
|
+
$: << "\#{File.dirname(__FILE__)}/gems/lib"
|
97
|
+
|
98
|
+
rejects = %w(spec src/app.rb vendor Main.rb)
|
99
|
+
ok_dirs = %w(config gems src)
|
100
|
+
REQUIRE_ALLS = ok_dirs.map{|dir| Dir.glob("\#{dir}/*.rb").reject{ |f| rejects.any?{|exclude| f.match exclude}}}.flatten
|
101
|
+
|
102
|
+
require 'environment'
|
103
|
+
|
104
|
+
GameboxApp.run ARGV, ENV
|
105
|
+
EOS
|
106
|
+
end
|
107
|
+
|
108
|
+
# modify plist file
|
109
|
+
# UntitledGame
|
110
|
+
cd "#{GAME_NAME}.app/Contents"
|
111
|
+
plist = File.open("Info.plist").read
|
112
|
+
File.open("Info.plist", 'w+') do |f|
|
113
|
+
f.puts plist.gsub "UntitledGame", GAME_NAME
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
task :win do
|
118
|
+
# create dist dir
|
119
|
+
FileUtils.mkdir "dist" unless File.exist? "dist"
|
120
|
+
# pull down windows app shell
|
121
|
+
# expand into place
|
122
|
+
sh 'cd dist; wget http://github.com/downloads/shawn42/gamebox/gamebox_app.zip; unzip gamebox_app.zip; mv gamebox_app/* .; rm gamebox_app.zip; rm -rf gamebox_app'
|
123
|
+
|
124
|
+
# copy config/src/lib/data into dist/src
|
125
|
+
%w{vendor config data }.each do |dir|
|
126
|
+
FileUtils.cp_r dir, File.join('dist','src', dir) if File.exist? dir
|
127
|
+
end
|
128
|
+
FileUtils.cp_r 'src', File.join('dist', 'src')
|
129
|
+
|
130
|
+
# create zip of dist?
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
@@ -4,18 +4,13 @@ confdir = File.dirname(__FILE__)+"/config"
|
|
4
4
|
$: << confdir
|
5
5
|
|
6
6
|
require 'environment'
|
7
|
-
|
7
|
+
$: << GAMEBOX_PATH
|
8
|
+
load "tasks/gamebox_tasks.rake"
|
8
9
|
STATS_DIRECTORIES = [
|
9
10
|
%w(Source src/),
|
10
11
|
%w(Config config/),
|
11
12
|
%w(Maps maps/),
|
12
13
|
%w(Unit\ tests specs/),
|
13
14
|
%w(Libraries lib/),
|
14
|
-
].collect { |name, dir| [ name, "#{dir}" ] }.select { |name, dir| File.directory?(dir) }
|
15
|
-
|
16
|
-
desc "Report code statistics (KLOCs, etc) from the application"
|
17
|
-
task :stats do
|
18
|
-
require 'code_statistics'
|
19
|
-
CodeStatistics.new(*STATS_DIRECTORIES).to_s
|
20
|
-
end
|
15
|
+
].collect { |name, dir| [ name, "#{APP_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) }
|
21
16
|
|
@@ -1,29 +1,4 @@
|
|
1
|
-
|
2
|
-
unless ENV['OCRA_EXECUTABLE'].nil?
|
3
|
-
APP_ROOT = "#{File.join(File.dirname($0),"..")}/"
|
4
|
-
Dir.chdir(File.join(File.dirname($0),"..",'src'))
|
5
|
-
else
|
6
|
-
APP_ROOT = "#{File.join(File.dirname($0),"..")}/"
|
7
|
-
end
|
8
|
-
|
9
|
-
gems = Dir[APP_ROOT+"vendor/gems/*"]
|
10
|
-
gems.each do |bundled_gem|
|
11
|
-
$:.unshift bundled_gem+"/lib"
|
12
|
-
end
|
13
|
-
|
14
|
-
ADDITIONAL_LOAD_PATHS = []
|
15
|
-
ADDITIONAL_LOAD_PATHS.concat %w(
|
16
|
-
src
|
17
|
-
lib
|
18
|
-
config
|
19
|
-
../../lib
|
20
|
-
).map { |dir| File.join(APP_ROOT,dir) }
|
21
|
-
|
22
|
-
ADDITIONAL_LOAD_PATHS.each do |path|
|
23
|
-
$:.unshift path
|
24
|
-
end
|
25
|
-
|
26
|
-
|
1
|
+
APP_ROOT = "#{File.join(File.dirname(__FILE__),"..")}/"
|
27
2
|
|
28
3
|
CONFIG_PATH = APP_ROOT + "config/"
|
29
4
|
DATA_PATH = APP_ROOT + "data/"
|
@@ -32,24 +7,17 @@ MUSIC_PATH = APP_ROOT + "data/music/"
|
|
32
7
|
GFX_PATH = APP_ROOT + "data/graphics/"
|
33
8
|
FONTS_PATH = APP_ROOT + "data/fonts/"
|
34
9
|
|
35
|
-
require '
|
10
|
+
require 'gamebox'
|
36
11
|
|
37
|
-
|
38
|
-
|
39
|
-
begin
|
40
|
-
ENV['BUNDLE_GEMFILE'] = gemfile
|
41
|
-
require 'bundler'
|
42
|
-
Bundler.setup
|
43
|
-
rescue Bundler::GemNotFound => e
|
44
|
-
STDERR.puts e.message
|
45
|
-
STDERR.puts "Try running `bundle install`."
|
46
|
-
exit!
|
47
|
-
end if File.exist?(gemfile)
|
12
|
+
[GAMEBOX_PATH, APP_ROOT, File.join(APP_ROOT,'src')].each{|path| $: << path }
|
13
|
+
require "gamebox_application"
|
48
14
|
|
49
|
-
|
15
|
+
require_all Dir.glob("**/*.rb").reject{ |f| f.match("spec") || f.match("src/app.rb")}
|
50
16
|
|
51
17
|
GAMEBOX_DATA_PATH = GAMEBOX_PATH + "data/"
|
52
18
|
GAMEBOX_SOUND_PATH = GAMEBOX_PATH + "data/sounds/"
|
53
19
|
GAMEBOX_MUSIC_PATH = GAMEBOX_PATH + "data/music/"
|
54
20
|
GAMEBOX_GFX_PATH = GAMEBOX_PATH + "data/graphics/"
|
55
21
|
GAMEBOX_FONTS_PATH = GAMEBOX_PATH + "data/fonts/"
|
22
|
+
|
23
|
+
GAME_NAME = "UntitledGame"
|
data/lib/gamebox/version.rb
CHANGED
data/lib/gamebox/viewport.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'numbers_ext'
|
2
|
-
require 'publisher'
|
3
|
-
|
4
1
|
# Viewport represents the current "camera" location. Essensially it translates from
|
5
2
|
# world to screen coords and from screen coords to world coords.
|
6
3
|
class Viewport
|
@@ -8,13 +5,16 @@ class Viewport
|
|
8
5
|
can_fire :scrolled
|
9
6
|
|
10
7
|
attr_accessor :x_offset, :y_offset, :follow_target, :width,
|
11
|
-
:height, :x_offset_range, :y_offset_range
|
8
|
+
:height, :x_offset_range, :y_offset_range, :boundary
|
9
|
+
|
10
|
+
attr_reader :speed
|
12
11
|
|
13
12
|
def debug
|
14
13
|
"xoff:#{@x_offset} yoff:#{@y_offset}"
|
15
14
|
end
|
16
15
|
|
17
16
|
def initialize(width, height)
|
17
|
+
@speed = 1
|
18
18
|
@x_offset = 0
|
19
19
|
@y_offset = 0
|
20
20
|
|
@@ -29,6 +29,16 @@ class Viewport
|
|
29
29
|
fire :scrolled
|
30
30
|
end
|
31
31
|
|
32
|
+
def speed=(new_speed)
|
33
|
+
if new_speed > 1
|
34
|
+
@speed = 1
|
35
|
+
elsif new_speed < 0
|
36
|
+
@speed = 0
|
37
|
+
else
|
38
|
+
@speed = new_speed
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
def x_offset(layer=1)
|
33
43
|
return 0 if layer == Float::INFINITY
|
34
44
|
return @x_offset if layer == 1
|
@@ -58,10 +68,11 @@ class Viewport
|
|
58
68
|
if x_diff.abs > @buffer_x
|
59
69
|
# move screen
|
60
70
|
if x_diff > 0
|
61
|
-
@x_offset += x_diff - @buffer_x
|
71
|
+
@x_offset += (x_diff - @buffer_x) * @speed
|
62
72
|
else
|
63
|
-
@x_offset += x_diff + @buffer_x
|
73
|
+
@x_offset += (x_diff + @buffer_x) * @speed
|
64
74
|
end
|
75
|
+
|
65
76
|
scrolled = true
|
66
77
|
end
|
67
78
|
|
@@ -70,17 +81,36 @@ class Viewport
|
|
70
81
|
if y_diff.abs > @buffer_y
|
71
82
|
# move screen
|
72
83
|
if y_diff > 0
|
73
|
-
@y_offset += y_diff - @buffer_y
|
84
|
+
@y_offset += (y_diff - @buffer_y) * @speed
|
74
85
|
else
|
75
|
-
@y_offset += y_diff + @buffer_y
|
86
|
+
@y_offset += (y_diff + @buffer_y) * @speed
|
76
87
|
end
|
77
88
|
scrolled = true
|
78
89
|
end
|
79
90
|
|
91
|
+
# constrain_x_offset
|
92
|
+
if @boundary
|
93
|
+
if @x_offset > 0 - @boundary[0] # Left-wall bump
|
94
|
+
@x_offset = @boundary[0]
|
95
|
+
elsif @x_offset < @width - @boundary[2] # right-wall bump
|
96
|
+
@x_offset = @width - @boundary[2]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# constrain_y_offset
|
101
|
+
if @boundary
|
102
|
+
if @y_offset > 0 - @boundary[1]
|
103
|
+
@y_offset = @boundary[1]
|
104
|
+
elsif @y_offset < @height - @boundary[3]
|
105
|
+
@y_offset = @height - @boundary[3]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
80
109
|
fire :scrolled if scrolled
|
81
110
|
end
|
82
111
|
end
|
83
112
|
|
113
|
+
|
84
114
|
def follow(target, off=[0,0], buff=[0,0])
|
85
115
|
@follow_target = target
|
86
116
|
@follow_offset_x = off[0]
|
@@ -94,4 +124,10 @@ class Viewport
|
|
94
124
|
fire :scrolled
|
95
125
|
end
|
96
126
|
|
127
|
+
def bounds
|
128
|
+
left = -@x_offset
|
129
|
+
top = -@y_offset
|
130
|
+
[left, top, left + @width, top + @height]
|
131
|
+
end
|
132
|
+
|
97
133
|
end
|