gamebox 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gamebox Build Status](https://secure.travis-ci.org/shawn42/gamebox.png)](http://travis-ci.org/shawn42/gamebox)
|
4
4
|
[![Gamebox Deps Status](https://gemnasium.com/shawn42/gamebox.png)](https://gemnasium.com/shawn42/gamebox)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/shawn42/gamebox.png)](https://codeclimate.com/github/shawn42/gamebox)
|
6
|
+
[![Stories in Ready](https://badge.waffle.io/shawn42/gamebox.png)](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
|