gamebox 0.4.1 → 0.5.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 +3 -2
- data/gamebox.gemspec +1 -1
- data/lib/gamebox/actors/collidable_debugger.rb +3 -4
- data/lib/gamebox/actors/label.rb +2 -0
- data/lib/gamebox/actors/score.rb +4 -25
- data/lib/gamebox/behaviors/animated_with_spritemap.rb +97 -0
- data/lib/gamebox/behaviors/collidable.rb +6 -14
- data/lib/gamebox/behaviors/collidable/aabb_collidable.rb +2 -3
- data/lib/gamebox/behaviors/graphical.rb +2 -1
- data/lib/gamebox/behaviors/physical.rb +1 -1
- data/lib/gamebox/behaviors/positioned.rb +10 -4
- data/lib/gamebox/core/actor.rb +1 -1
- data/lib/gamebox/core/actor_factory.rb +2 -0
- data/lib/gamebox/core/arbiter.rb +2 -0
- data/lib/gamebox/core/font_style.rb +2 -2
- data/lib/gamebox/core/input_mapper.rb +4 -4
- data/lib/gamebox/core/resource_manager.rb +2 -2
- data/lib/gamebox/core/viewport.rb +78 -54
- data/lib/gamebox/spec/helper.rb +2 -3
- data/lib/gamebox/tasks/gamebox_tasks.rake +1 -90
- data/lib/gamebox/version.rb +2 -2
- data/lib/gamebox/views/graphical_actor_view.rb +11 -6
- data/spec/acceptance/input_mapper_spec.rb +14 -14
- data/spec/actors/label_spec.rb +13 -4
- data/spec/behaviors/collidable_spec.rb +2 -2
- data/spec/behaviors/positioned_spec.rb +27 -30
- data/spec/core/actor_spec.rb +2 -2
- data/spec/core/input_mapper_spec.rb +1 -1
- data/spec/core/resource_manager_spec.rb +20 -4
- data/spec/core/viewport_spec.rb +202 -108
- data/spec/views/graphical_actor_view_spec.rb +4 -1
- data/templates/app/Gemfile.tt +3 -1
- data/templates/app/Rakefile +51 -0
- data/templates/app/config/environment.rb +2 -1
- data/templates/app/config/game.yml +0 -1
- data/templates/app/spec/helper.rb +1 -1
- data/templates/app/src/views/.gitkeep +0 -0
- metadata +51 -97
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 29d17db2fdbdf1732b5e68f6b8584d12270e8c3d
|
4
|
+
data.tar.gz: b955424dab5554402acf08f8dd425c1af86649c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 17cbdefcebc2f904c9ccfb4a4d44477b5ffc07a0a5eac840933fc7ff2e68da7fe7e343835eb3a69a98c52ec1fdd5d63d84a228dcebe55676690b883571c7c133
|
7
|
+
data.tar.gz: 1e3ac16757af09d3404decd43298a5509fbb0461fff5bfe1cbbcca7af86562ef6f6d5e6c60a88bdd82d8603bf40ae3b86e070400980445be80f5f9a6ecf1457f
|
data/README.md
CHANGED
@@ -3,12 +3,13 @@
|
|
3
3
|
[](http://travis-ci.org/shawn42/gamebox)
|
4
4
|
[](https://gemnasium.com/shawn42/gamebox)
|
5
5
|
[](https://codeclimate.com/github/shawn42/gamebox)
|
6
|
+
[](http://waffle.io/shawn42/gamebox)
|
6
7
|
|
7
8
|
* A **game template** for building and distributing Gosu games.
|
8
9
|
* Quickly **generate a game** and have it **up and running**.
|
9
10
|
* Provide **conventions and DSL** for building your game.
|
10
11
|
* Facilitate quickly building **distributable artifacts**.
|
11
|
-
* http://
|
12
|
+
* http://gamebox.io/
|
12
13
|
* see [gamebox on rubygems.org](https://rubygems.org/gems/gamebox) for the list of requirements
|
13
14
|
|
14
15
|
## Getting started with Gamebox
|
@@ -102,7 +103,7 @@ end
|
|
102
103
|
|
103
104
|
### Behaviors
|
104
105
|
|
105
|
-
Behaviors are what bring life to actors. They interact
|
106
|
+
Behaviors are what bring life to actors. They interact with the actor's internal data, input, audio, etc.
|
106
107
|
|
107
108
|
```ruby
|
108
109
|
define_behavior :projectile do
|
data/gamebox.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_dependency "thor"#, ">= 0.14.6"
|
27
27
|
s.add_dependency "require_all"
|
28
28
|
s.add_dependency "kvo", ">= 0.1.0"
|
29
|
-
s.add_dependency "listen", ">=
|
29
|
+
s.add_dependency "listen", ">= 2.4.0"
|
30
30
|
|
31
31
|
s.add_development_dependency "pry", '~>0.9.7'
|
32
32
|
s.add_development_dependency "pry-remote"
|
@@ -4,7 +4,7 @@ end
|
|
4
4
|
|
5
5
|
define_behavior :collider_container do
|
6
6
|
setup do
|
7
|
-
|
7
|
+
raise "collider required" unless actor.do_or_do_not(:collider)
|
8
8
|
actor.collider.when :remove do
|
9
9
|
actor.remove
|
10
10
|
end
|
@@ -14,13 +14,12 @@ end
|
|
14
14
|
define_actor_view :collidable_debugger_view do
|
15
15
|
|
16
16
|
setup do
|
17
|
-
@color = Color::WHITE
|
17
|
+
@color = actor.do_or_do_not(:color) || Color::WHITE
|
18
18
|
end
|
19
19
|
|
20
20
|
draw do |target,x_off,y_off,z|
|
21
21
|
collider = actor.collider
|
22
|
-
|
23
|
-
when :circle
|
22
|
+
if collider.shape_type == :circle
|
24
23
|
target.draw_circle x_off+collider.center_x, y_off+collider.center_y, collider.radius, @color, z
|
25
24
|
else
|
26
25
|
collider.cw_world_lines.each do |line|
|
data/lib/gamebox/actors/label.rb
CHANGED
data/lib/gamebox/actors/score.rb
CHANGED
@@ -2,42 +2,21 @@ define_behavior :score_keeper do
|
|
2
2
|
requires :backstage, :stage
|
3
3
|
|
4
4
|
setup do
|
5
|
-
clear if score.nil?
|
6
5
|
# TODO helper for "attached subactor"
|
7
6
|
label = stage.create_actor(:label, actor.attributes)
|
8
|
-
actor.has_attributes label: label
|
7
|
+
actor.has_attributes label: label, score: 0
|
9
8
|
actor.when :position_changed do
|
10
9
|
actor.label.x = actor.x
|
11
10
|
actor.label.y = actor.y
|
12
11
|
end
|
13
|
-
actor.when
|
14
|
-
|
15
|
-
end
|
12
|
+
actor.when(:remove_me) { label.remove }
|
13
|
+
actor.when(:score_changed) { update_text }
|
16
14
|
update_text
|
17
|
-
reacts_with :subtract, :add
|
18
15
|
end
|
19
16
|
|
20
17
|
helpers do
|
21
|
-
def score
|
22
|
-
backstage[:score]
|
23
|
-
end
|
24
|
-
|
25
|
-
def clear
|
26
|
-
backstage[:score] = 0
|
27
|
-
end
|
28
|
-
|
29
|
-
def add(amount)
|
30
|
-
backstage[:score] += amount
|
31
|
-
update_text
|
32
|
-
end
|
33
|
-
|
34
|
-
def subtract(amount)
|
35
|
-
backstage[:score] -= amount
|
36
|
-
update_text
|
37
|
-
end
|
38
|
-
|
39
18
|
def update_text
|
40
|
-
actor.label.text = score
|
19
|
+
actor.label.text = actor.score
|
41
20
|
end
|
42
21
|
end
|
43
22
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
define_behavior :animated_with_spritemap do
|
2
|
+
requires :resource_manager, :director
|
3
|
+
setup do
|
4
|
+
|
5
|
+
actor.has_attributes animation_file: opts[:file],
|
6
|
+
action: :idle,
|
7
|
+
animating: true,
|
8
|
+
image: nil,
|
9
|
+
width: 1,
|
10
|
+
height: 1
|
11
|
+
|
12
|
+
setup_animation if actor.animation_file?
|
13
|
+
|
14
|
+
actor.when :animation_file_changed do
|
15
|
+
setup_animation
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
remove do
|
21
|
+
actor.unsubscribe_all self
|
22
|
+
end
|
23
|
+
|
24
|
+
helpers do
|
25
|
+
def setup_animation
|
26
|
+
@frame_update_time = opts[:interval] || 60
|
27
|
+
@frame_time = 0
|
28
|
+
|
29
|
+
@frame_num = 0
|
30
|
+
|
31
|
+
file = actor.animation_file
|
32
|
+
rows, cols, actions = opts[:rows], opts[:cols], opts[:actions]
|
33
|
+
# @spritemap = resource_manager.load_image file
|
34
|
+
|
35
|
+
# negatives means rows/cols instead of w/h
|
36
|
+
# http://www.libgosu.org/rdoc/Gosu/Image.html#load_tiles-class_method
|
37
|
+
@sprites = resource_manager.load_tiles file, -cols, -rows
|
38
|
+
|
39
|
+
@frames = {}
|
40
|
+
actions.each do |action, frames|
|
41
|
+
frames = frames.to_a if frames.is_a?(Range)
|
42
|
+
images = Array.wrap(frames).map { |f| @sprites[f] }
|
43
|
+
@frames[action] = images
|
44
|
+
end
|
45
|
+
|
46
|
+
actor.when :action_changed do |old_action, new_action|
|
47
|
+
unless old_action == new_action
|
48
|
+
action_changed old_action, new_action
|
49
|
+
actor.animating = @frames[new_action].size > 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
action_changed nil, actor.action
|
54
|
+
|
55
|
+
director.when :update do |time|
|
56
|
+
if actor.animating
|
57
|
+
@frame_time += time
|
58
|
+
if @frame_time > @frame_update_time
|
59
|
+
next_frame
|
60
|
+
@frame_time = @frame_time-@frame_update_time
|
61
|
+
end
|
62
|
+
set_frame
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def next_frame
|
69
|
+
action_set = @frames[actor.action]
|
70
|
+
return unless action_set
|
71
|
+
@frame_num = @frame_num + 1
|
72
|
+
if @frame_num >= action_set.size
|
73
|
+
actor.emit :action_loop_complete
|
74
|
+
@frame_num = 0
|
75
|
+
end
|
76
|
+
# @frame_num = (@frame_num + 1) % action_set.size unless action_set.nil?
|
77
|
+
end
|
78
|
+
|
79
|
+
def action_changed(old_action, new_action)
|
80
|
+
@frame_num = 0
|
81
|
+
set_frame
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_frame
|
85
|
+
action_set = @frames[actor.action]
|
86
|
+
raise "unknown action set #{actor.action} for #{actor}" if action_set.nil?
|
87
|
+
|
88
|
+
image = action_set[@frame_num]
|
89
|
+
actor.image = image
|
90
|
+
actor.width = image.width
|
91
|
+
actor.height = image.height
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
@@ -15,24 +15,16 @@ Behavior.define :collidable do
|
|
15
15
|
y = (actor.do_or_do_not(:y) || 0) - hh
|
16
16
|
|
17
17
|
actor.has_attributes( shape_type: shape_type,
|
18
|
-
width: w,
|
19
|
-
height: h,
|
20
18
|
x: x,
|
21
|
-
y: y
|
19
|
+
y: y,
|
20
|
+
width: w,
|
21
|
+
height: h
|
22
|
+
)
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
when :circle
|
26
|
-
CircleCollidable.new actor, opts
|
27
|
-
when :aabb
|
28
|
-
AaBbCollidable.new actor, opts
|
29
|
-
when :polygon
|
30
|
-
PolygonCollidable.new actor, opts
|
31
|
-
end
|
24
|
+
shape_klass = shape_type.to_s.capitalize + "Collidable"
|
25
|
+
shape = Object.const_get(shape_klass).new actor, opts
|
32
26
|
shape.setup
|
33
27
|
|
34
|
-
actor.width = shape.width
|
35
|
-
actor.height = shape.height
|
36
28
|
bb = Rect.new
|
37
29
|
bb.x = actor.x
|
38
30
|
bb.y = actor.y
|
@@ -1,14 +1,13 @@
|
|
1
1
|
|
2
2
|
|
3
|
-
class
|
3
|
+
class AabbCollidable < CollidableShape
|
4
4
|
attr_accessor :cw_local_points
|
5
5
|
|
6
6
|
def setup
|
7
7
|
@shape_type = opts[:shape]
|
8
8
|
|
9
9
|
@cw_local_points = opts[:cw_local_points]
|
10
|
-
@cw_local_points ||= opts[:points] ||
|
11
|
-
@cw_world_points ||= build_aabb
|
10
|
+
@cw_local_points ||= opts[:points] || build_aabb
|
12
11
|
|
13
12
|
@radius = opts[:radius]
|
14
13
|
@radius ||= calculate_radius
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# data/graphics/classname.png
|
5
5
|
Behavior.define :graphical do
|
6
6
|
|
7
|
-
requires_behaviors :layered
|
7
|
+
requires_behaviors :layered, :positioned
|
8
8
|
requires :resource_manager
|
9
9
|
setup do
|
10
10
|
image = actor.do_or_do_not(:image) || resource_manager.load_actor_image(actor)
|
@@ -23,6 +23,7 @@ Behavior.define :graphical do
|
|
23
23
|
scale: scale,
|
24
24
|
x_scale: @opts[:x_scale] || scale,
|
25
25
|
y_scale: @opts[:y_scale] || scale,
|
26
|
+
anchor: @opts[:anchor] || :center,
|
26
27
|
rotation: 0.0 )
|
27
28
|
|
28
29
|
actor.when :image_changed do |old, new|
|
@@ -188,7 +188,7 @@ Behavior.define :physical do
|
|
188
188
|
|
189
189
|
def warp(new_p)
|
190
190
|
actor.body.p = new_p
|
191
|
-
physics_manager.space.
|
191
|
+
physics_manager.space.reindex_static if opts[:fixed]
|
192
192
|
end
|
193
193
|
|
194
194
|
# TODO use react_to to handle these requests?
|
@@ -1,11 +1,17 @@
|
|
1
1
|
define_behavior :positioned do
|
2
2
|
setup do
|
3
|
-
x = opts[:x] || 0
|
4
|
-
y = opts[:y] || 0
|
5
|
-
actor.has_attributes x: x, y: y
|
6
|
-
actor.has_attributes position: vec2(actor.x, actor.y)
|
3
|
+
x = opts[:x] || actor.do_or_do_not(:x) || 0
|
4
|
+
y = opts[:y] || actor.do_or_do_not(:y) || 0
|
5
|
+
actor.has_attributes position: vec2(x, y), x: x, y: y
|
7
6
|
actor.when(:x_changed) { actor.position = vec2(actor.x, actor.y) }
|
8
7
|
actor.when(:y_changed) { actor.position = vec2(actor.x, actor.y) }
|
8
|
+
|
9
|
+
actor.when(:position_changed) do
|
10
|
+
actor.update_attributes(
|
11
|
+
x: actor.position.x,
|
12
|
+
y: actor.position.y
|
13
|
+
)
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
17
|
end
|
data/lib/gamebox/core/actor.rb
CHANGED
data/lib/gamebox/core/arbiter.rb
CHANGED
@@ -7,10 +7,10 @@ class InputMapper
|
|
7
7
|
@action_ids = {}
|
8
8
|
end
|
9
9
|
|
10
|
-
#
|
10
|
+
# map_controls is to be setup outside of an actor and passed in at construction
|
11
11
|
# time ie:
|
12
12
|
#
|
13
|
-
# mapper.
|
13
|
+
# mapper.map_controls {
|
14
14
|
# '+a' => :jump, # emit jump when 'a' is _pressed_
|
15
15
|
# '-b' => :duck, # emit duck when 'b' is _released_
|
16
16
|
# 'c' => :block # emit block when 'c' is _pressed_ AND _released_
|
@@ -20,7 +20,7 @@ class InputMapper
|
|
20
20
|
# create_actor :fighter, input: mapper
|
21
21
|
#
|
22
22
|
# all of the actor's behaviors can / should use the input mapper instead of raw key bindings
|
23
|
-
def
|
23
|
+
def map_controls(input_hash)
|
24
24
|
input_hash.each do |input, actions|
|
25
25
|
if input.start_with? '-'
|
26
26
|
register_key_released(input[1..-1], actions)
|
@@ -35,7 +35,7 @@ class InputMapper
|
|
35
35
|
|
36
36
|
# unsubscribes for all input
|
37
37
|
def clear
|
38
|
-
input_manager.unsubscribe_all
|
38
|
+
input_manager.unsubscribe_all self
|
39
39
|
end
|
40
40
|
|
41
41
|
def method_missing(name, *args)
|
@@ -14,8 +14,8 @@ class ResourceManager
|
|
14
14
|
|
15
15
|
def load_actor_image(actor)
|
16
16
|
# use pngs only for now
|
17
|
-
|
18
|
-
return load_image("#{
|
17
|
+
image_name = actor.do_or_do_not(:image_name) || actor.actor_type
|
18
|
+
return load_image("#{image_name}.png")
|
19
19
|
end
|
20
20
|
|
21
21
|
def load_animation_set(actor, action)
|
@@ -10,6 +10,7 @@ class Viewport
|
|
10
10
|
:height, :x_offset_range, :y_offset_range, :boundary, :rotation
|
11
11
|
|
12
12
|
attr_reader :speed
|
13
|
+
alias :follow_target? :follow_target
|
13
14
|
|
14
15
|
def debug
|
15
16
|
"xoff:#{@x_offset} yoff:#{@y_offset}"
|
@@ -59,64 +60,29 @@ class Viewport
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def update(time)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
y = @follow_target.y
|
66
|
-
if @x_offset_range
|
67
|
-
x = @x_offset_range.min if @x_offset_range.min > x
|
68
|
-
x = @x_offset_range.max if @x_offset_range.max < x
|
69
|
-
end
|
70
|
-
if @y_offset_range
|
71
|
-
y = @y_offset_range.min if @y_offset_range.min > y
|
72
|
-
y = @y_offset_range.max if @y_offset_range.max < y
|
73
|
-
end
|
74
|
-
x_diff = @width/2 + @follow_offset_x - x - @x_offset
|
75
|
-
if x_diff.abs > @buffer_x
|
76
|
-
# move screen
|
77
|
-
if x_diff > 0
|
78
|
-
@x_offset += (x_diff - @buffer_x) * @speed
|
79
|
-
else
|
80
|
-
@x_offset += (x_diff + @buffer_x) * @speed
|
81
|
-
end
|
82
|
-
|
83
|
-
scrolled = true
|
84
|
-
end
|
85
|
-
|
86
|
-
y_diff = @height/2 + @follow_offset_y - y - @y_offset
|
87
|
-
if y_diff.abs > @buffer_y
|
88
|
-
# move screen
|
89
|
-
if y_diff > 0
|
90
|
-
@y_offset += (y_diff - @buffer_y) * @speed
|
91
|
-
else
|
92
|
-
@y_offset += (y_diff + @buffer_y) * @speed
|
93
|
-
end
|
94
|
-
scrolled = true
|
95
|
-
end
|
96
|
-
|
97
|
-
# constrain_x_offset
|
98
|
-
if @boundary
|
99
|
-
if @x_offset > 0 - @boundary[0] # Left-wall bump
|
100
|
-
@x_offset = @boundary[0]
|
101
|
-
elsif @x_offset < @width - @boundary[2] # right-wall bump
|
102
|
-
@x_offset = @width - @boundary[2]
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# constrain_y_offset
|
107
|
-
if @boundary
|
108
|
-
if @y_offset > 0 - @boundary[1]
|
109
|
-
@y_offset = @boundary[1]
|
110
|
-
elsif @y_offset < @height - @boundary[3]
|
111
|
-
@y_offset = @height - @boundary[3]
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
63
|
+
if follow_target?
|
64
|
+
scrolled = move_towards_target
|
65
|
+
clamp_to_boundary
|
115
66
|
fire :scrolled if scrolled
|
116
67
|
end
|
117
68
|
end
|
118
69
|
|
70
|
+
# Viewport will stay centered on the targets x,y
|
71
|
+
#
|
72
|
+
# args hash:
|
73
|
+
# :x_offset - keep the viewport centered on x + x_offset
|
74
|
+
# :y_offset - keep the viewport centered on y + y_offset
|
75
|
+
# :x_chain_length - allow this much x slack when following
|
76
|
+
# :y_chain_length - allow this much y slack when following
|
77
|
+
def stay_centered_on(target, args={})
|
78
|
+
offset_x = args[:x_offset] || 0
|
79
|
+
offset_y = args[:y_offset] || 0
|
80
|
+
x_chain_length = args[:x_chain_length] || 0
|
81
|
+
y_chain_length = args[:y_chain_length] || 0
|
82
|
+
follow target, [-offset_x, -offset_y], [x_chain_length, y_chain_length]
|
83
|
+
end
|
119
84
|
|
85
|
+
# deprecated; use #stay_centered_on
|
120
86
|
def follow(target, off=[0,0], buff=[0,0])
|
121
87
|
@follow_target = target
|
122
88
|
@follow_offset_x = off[0]
|
@@ -133,7 +99,65 @@ class Viewport
|
|
133
99
|
def bounds
|
134
100
|
left = -@x_offset
|
135
101
|
top = -@y_offset
|
136
|
-
Rect.new left, top, left + @width, top + @height
|
102
|
+
# Rect.new left, top, left + @width, top + @height
|
103
|
+
Rect.new left, top, @width, @height
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
def move_towards_target
|
108
|
+
scrolled = false
|
109
|
+
|
110
|
+
x = @follow_target.x
|
111
|
+
y = @follow_target.y
|
112
|
+
|
113
|
+
if @x_offset_range
|
114
|
+
x = @x_offset_range.min if @x_offset_range.min > x
|
115
|
+
x = @x_offset_range.max if @x_offset_range.max < x
|
116
|
+
end
|
117
|
+
if @y_offset_range
|
118
|
+
y = @y_offset_range.min if @y_offset_range.min > y
|
119
|
+
y = @y_offset_range.max if @y_offset_range.max < y
|
120
|
+
end
|
121
|
+
x_diff = @width/2 + @follow_offset_x - x - @x_offset
|
122
|
+
if x_diff.abs > @buffer_x
|
123
|
+
# move screen
|
124
|
+
if x_diff > 0
|
125
|
+
@x_offset += (x_diff - @buffer_x) * @speed
|
126
|
+
else
|
127
|
+
@x_offset += (x_diff + @buffer_x) * @speed
|
128
|
+
end
|
129
|
+
|
130
|
+
scrolled = true
|
131
|
+
end
|
132
|
+
|
133
|
+
y_diff = @height/2 + @follow_offset_y - y - @y_offset
|
134
|
+
if y_diff.abs > @buffer_y
|
135
|
+
# move screen
|
136
|
+
if y_diff > 0
|
137
|
+
@y_offset += (y_diff - @buffer_y) * @speed
|
138
|
+
else
|
139
|
+
@y_offset += (y_diff + @buffer_y) * @speed
|
140
|
+
end
|
141
|
+
scrolled = true
|
142
|
+
end
|
143
|
+
|
144
|
+
scrolled
|
145
|
+
end
|
146
|
+
|
147
|
+
def clamp_to_boundary
|
148
|
+
if @boundary
|
149
|
+
if @x_offset > 0 - @boundary[0] # Left-wall bump
|
150
|
+
@x_offset = @boundary[0]
|
151
|
+
elsif @x_offset < @width - @boundary[2] # right-wall bump
|
152
|
+
@x_offset = @width - @boundary[2]
|
153
|
+
end
|
154
|
+
|
155
|
+
if @y_offset > 0 - @boundary[1]
|
156
|
+
@y_offset = @boundary[1]
|
157
|
+
elsif @y_offset < @height - @boundary[3]
|
158
|
+
@y_offset = @height - @boundary[3]
|
159
|
+
end
|
160
|
+
end
|
137
161
|
end
|
138
162
|
|
139
163
|
end
|