steering_behaviors 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,207 @@
1
+ Copyright 2013, Prylis Incorporated.
2
+
3
+ Please contact the author <cpowell@prylis.com> for questions about licensing or for specific
4
+ licensing needs.
5
+
6
+ The Ruby Steering Behaviors Library is free software: you can redistribute it and/or modify it under
7
+ the terms of the GNU Lesser General Public License as published by the Free Software Foundation,
8
+ either version 3 of the License, or (at your option) any later version.
9
+
10
+ The Ruby Steering Behaviors Library is distributed in the hope that it will be useful, but WITHOUT
11
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
+ PURPOSE. See the GNU Lesser General Public License for more details.
13
+
14
+ A copy of the GNU Lesser General Public License is at the end of this file, or see
15
+ <http://www.gnu.org/licenses/lgpl.html>.
16
+
17
+ ----
18
+
19
+ The examples (*only* the examples) provided in the Ruby Steering Behaviors Library source code
20
+ repository depend on LWJGL and Slick2D to operate. These products have their own licenses as follows.
21
+
22
+ The Slick2D license:
23
+ Copyright (c) 2012, Slick 2D All rights reserved.
24
+
25
+ Redistribution and use in source and binary forms, with or without modification, are permitted
26
+ provided that the following conditions are met:
27
+
28
+ Redistributions of source code must retain the above copyright notice, this list of conditions and
29
+ the following disclaimer.
30
+
31
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions
32
+ and the following disclaimer in the documentation and/or other materials provided with the
33
+ distribution.
34
+
35
+ Neither the name of the Slick 2D nor the names of its contributors may be used to endorse or promote
36
+ products derived from this software without specific prior written permission.
37
+
38
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR
39
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
40
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
44
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
45
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46
+
47
+ The LWJGL license:
48
+ Copyright (c) 2002-2007 Lightweight Java Game Library Project All rights reserved.
49
+
50
+ Redistribution and use in source and binary forms, with or without modification, are permitted
51
+ provided that the following conditions are met:
52
+
53
+ * Redistributions of source code must retain the above copyright notice, this list of conditions
54
+ and the following disclaimer.
55
+
56
+ * Redistributions in binary form must reproduce the above copyright notice, this list of
57
+ conditions and the following disclaimer in the documentation and/or other materials provided with
58
+ the distribution.
59
+
60
+ * Neither the name of 'Light Weight Java Game Library' nor the names of its contributors may be
61
+ used to endorse or promote products derived from this software without specific prior written
62
+ permission.
63
+
64
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
65
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
66
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
67
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
69
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
70
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
71
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72
+
73
+ ----
74
+ GNU LESSER GENERAL PUBLIC LICENSE
75
+ Version 3, 29 June 2007
76
+
77
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
78
+ Everyone is permitted to copy and distribute verbatim copies of this license document, but
79
+ changing it is not allowed.
80
+
81
+
82
+ This version of the GNU Lesser General Public License incorporates the terms and conditions of
83
+ version 3 of the GNU General Public License, supplemented by the additional permissions listed
84
+ below.
85
+
86
+ 0. Additional Definitions.
87
+
88
+ As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and
89
+ the "GNU GPL" refers to version 3 of the GNU General Public License.
90
+
91
+ "The Library" refers to a covered work governed by this License, other than an Application or a
92
+ Combined Work as defined below.
93
+
94
+ An "Application" is any work that makes use of an interface provided by the Library, but which is
95
+ not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed
96
+ a mode of using an interface provided by the Library.
97
+
98
+ A "Combined Work" is a work produced by combining or linking an Application with the Library. The
99
+ particular version of the Library with which the Combined Work was made is also called the "Linked
100
+ Version".
101
+
102
+ The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the
103
+ Combined Work, excluding any source code for portions of the Combined Work that, considered in
104
+ isolation, are based on the Application, and not on the Linked Version.
105
+
106
+ The "Corresponding Application Code" for a Combined Work means the object code and/or source code
107
+ for the Application, including any data and utility programs needed for reproducing the Combined
108
+ Work from the Application, but excluding the System Libraries of the Combined Work.
109
+
110
+ 1. Exception to Section 3 of the GNU GPL.
111
+
112
+ You may convey a covered work under sections 3 and 4 of this License without being bound by
113
+ section 3 of the GNU GPL.
114
+
115
+ 2. Conveying Modified Versions.
116
+
117
+ If you modify a copy of the Library, and, in your modifications, a facility refers to a function
118
+ or data to be supplied by an Application that uses the facility (other than as an argument passed
119
+ when the facility is invoked), then you may convey a copy of the modified version:
120
+
121
+ a) under this License, provided that you make a good faith effort to ensure that, in the event an
122
+ Application does not supply the function or data, the facility still operates, and performs
123
+ whatever part of its purpose remains meaningful, or
124
+
125
+ b) under the GNU GPL, with none of the additional permissions of this License applicable to that
126
+ copy.
127
+
128
+ 3. Object Code Incorporating Material from Library Header Files.
129
+
130
+ The object code form of an Application may incorporate material from a header file that is part of
131
+ the Library. You may convey such object code under terms of your choice, provided that, if the
132
+ incorporated material is not limited to numerical parameters, data structure layouts and accessors,
133
+ or small macros, inline functions and templates (ten or fewer lines in length), you do both of the
134
+ following:
135
+
136
+ a) Give prominent notice with each copy of the object code that the Library is used in it and
137
+ that the Library and its use are covered by this License.
138
+
139
+ b) Accompany the object code with a copy of the GNU GPL and this license document.
140
+
141
+ 4. Combined Works.
142
+
143
+ You may convey a Combined Work under terms of your choice that, taken together, effectively do not
144
+ restrict modification of the portions of the Library contained in the Combined Work and reverse
145
+ engineering for debugging such modifications, if you also do each of the following:
146
+
147
+ a) Give prominent notice with each copy of the Combined Work that the Library is used in it and
148
+ that the Library and its use are covered by this License.
149
+
150
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
151
+
152
+ c) For a Combined Work that displays copyright notices during execution, include the copyright
153
+ notice for the Library among these notices, as well as a reference directing the user to the
154
+ copies of the GNU GPL and this license document.
155
+
156
+ d) Do one of the following:
157
+
158
+ 0) Convey the Minimal Corresponding Source under the terms of this License, and the
159
+ Corresponding Application Code in a form suitable for, and under terms that permit, the user
160
+ to recombine or relink the Application with a modified version of the Linked Version to
161
+ produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for
162
+ conveying Corresponding Source.
163
+
164
+ 1) Use a suitable shared library mechanism for linking with the Library. A suitable
165
+ mechanism is one that (a) uses at run time a copy of the Library already present on the
166
+ user's computer system, and (b) will operate properly with a modified version of the Library
167
+ that is interface-compatible with the Linked Version.
168
+
169
+ e) Provide Installation Information, but only if you would otherwise be required to provide such
170
+ information under section 6 of the GNU GPL, and only to the extent that such information is
171
+ necessary to install and execute a modified version of the Combined Work produced by recombining
172
+ or relinking the Application with a modified version of the Linked Version. (If you use option
173
+ 4d0, the Installation Information must accompany the Minimal Corresponding Source and
174
+ Corresponding Application Code. If you use option 4d1, you must provide the Installation
175
+ Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding
176
+ Source.)
177
+
178
+ 5. Combined Libraries.
179
+
180
+ You may place library facilities that are a work based on the Library side by side in a single
181
+ library together with other library facilities that are not Applications and are not covered by this
182
+ License, and convey such a combined library under terms of your choice, if you do both of the
183
+ following:
184
+
185
+ a) Accompany the combined library with a copy of the same work based on the Library, uncombined
186
+ with any other library facilities, conveyed under the terms of this License.
187
+
188
+ b) Give prominent notice with the combined library that part of it is a work based on the
189
+ Library, and explaining where to find the accompanying uncombined form of the same work.
190
+
191
+ 6. Revised Versions of the GNU Lesser General Public License.
192
+
193
+ The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General
194
+ Public License from time to time. Such new versions will be similar in spirit to the present
195
+ version, but may differ in detail to address new problems or concerns.
196
+
197
+ Each version is given a distinguishing version number. If the Library as you received it specifies
198
+ that a certain numbered version of the GNU Lesser General Public License "or any later version"
199
+ applies to it, you have the option of following the terms and conditions either of that published
200
+ version or of any later version published by the Free Software Foundation. If the Library as you
201
+ received it does not specify a version number of the GNU Lesser General Public License, you may
202
+ choose any version of the GNU Lesser General Public License ever published by the Free Software
203
+ Foundation.
204
+
205
+ If the Library as you received it specifies that a proxy can decide whether future versions of the
206
+ GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any
207
+ version is permanent authorization for you to choose that version for the Library.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Steering Behaviors for Autonomous Game Agents in Ruby
2
+
3
+ If you're building a game, you need your game agents and characters to move on their own. A standard way of doing this is with 'steering behaviors'.
4
+
5
+ The seminal paper by Craig Reynolds established a core set of steering behaviors that could be utilized for a variety of common movement tasks. This Ruby library can accomplish many/most of those tasks for your Ruby / JRuby game.
6
+
7
+ The basic behaviors can be layered for more complicated and advanced behaviors, such as flocking and crowd movement.
8
+
9
+ ## How it works
10
+
11
+ The steering behaviors expect to operate on a 'kinematic' thing. That is, the steerable object must expose several required parameters such as position vector, velocity vector, etc. These vectors are altered by the steering force, and then your movement engine simply repositions the object accordingly.
12
+
13
+ ## Supported stering behaviors
14
+
15
+ The library supports these steering behaviors:
16
+
17
+ * Seek: aim for and reach the specified point at top speed
18
+ * Flee: head away from the specified point at top speed (the opposite of Seek)
19
+ * Arrive: aim for and reach the specified point, decelerating gracefully to arrive with zero velocity
20
+ * Pursue: given a moving target, anticipate its future position and intercept the target intelligently
21
+ * Evade: given a moving target, anticipate its future position and avoid the target intelligently (the opposite of Pursue)
22
+ * Wander: move about the plain in a 'random walk' way
23
+
24
+ These are all standard steering behaviors documented at Craig Reynold's website (see References, below).
25
+
26
+ Additionally, this library supports some other useful behaviors:
27
+
28
+ * Align: align my course with the target's course, without altering my speed
29
+ * Match: match my course and speed to those of the target
30
+ * Broadside: expose my side to the target in the manner of a ship's broadside; useful for orbiting or exposing weapons, say
31
+ * Orthogonal: steer for a course that is 90 degrees from the target's
32
+
33
+ ## Project status
34
+
35
+ This is working, functional software, suitable for use in your own game or application.
36
+
37
+ Additional steering behaviors, such as flocking and following, are planned.
38
+
39
+ Watch the [changelog](http://github.com/cpowell/steering-behaviors/blob/master/CHANGELOG.md) for news.
40
+
41
+ ## Gem installation
42
+
43
+ I recommend you clone the Git repository and browse the examples and source code to fully understand how the behaviors work.
44
+
45
+ But if / when you want to use this in your own project, the easiest way to do so is via the Gem:
46
+ ```
47
+ gem install steering_behaviors
48
+ ```
49
+
50
+ Then in your code:
51
+ ```
52
+ require 'steering_behaviors'
53
+ ```
54
+
55
+ The gem is fully namespaced to prevent collisions. See the examples for usage details.
56
+
57
+ ## Included examples
58
+
59
+ The `examples` directory contains working examples of each of the behaviors. The examples themselves are, of course, graphical and leverage Slick2D and JRuby. All the necessary libraries to run the examples are included in this Git repository; you'll just need to install JRuby. (I recommend rvm.)
60
+ ```
61
+ rvm install jruby
62
+ ```
63
+
64
+ Then, to run the examples:
65
+ ```
66
+ ./examples/run_examples.sh
67
+ ```
68
+
69
+ Note that JRuby is not a dependency for the Steering Behaviors themselves, only for the bundled examples which rely on JRuby / Slick2D for animation.
70
+
71
+ By the way, the examples are not DRY at all and are highly repetitive from one example to the next; this is by design. They are intended to each be somewhat self-contained and readable without you having to flip between too many files to gain an understanding of what is going on.
72
+
73
+ ## References used in the creation of this software
74
+ * "Autonomous Behaviors for Autonomous Characters" by Craig Reynolds [(Explanation and demos)](http://www.red3d.com/cwr/steer/)
75
+ * "Programming Game AI by Example" by Mat Buckland [(Amazon link)](http://www.amazon.com/Programming-Game-Example-Mat-Buckland/dp/1556220782)
76
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ task :default => [:test]
4
+
5
+ desc "Run the test suite once"
6
+ task :test do
7
+ ruby "test/all_suite.rb"
8
+ end
@@ -0,0 +1,17 @@
1
+ class SteeringBehaviors
2
+ end
3
+
4
+ require 'steering_behaviors/common.rb'
5
+
6
+ require 'steering_behaviors/align.rb'
7
+ require 'steering_behaviors/arrive.rb'
8
+ require 'steering_behaviors/broadside.rb'
9
+ require 'steering_behaviors/evade.rb'
10
+ require 'steering_behaviors/flee.rb'
11
+ require 'steering_behaviors/match.rb'
12
+ require 'steering_behaviors/orthogonal.rb'
13
+ require 'steering_behaviors/pursue.rb'
14
+ require 'steering_behaviors/seek.rb'
15
+ require 'steering_behaviors/steering.rb'
16
+ require 'steering_behaviors/vector.rb'
17
+ require 'steering_behaviors/wander.rb'
@@ -0,0 +1,26 @@
1
+ ##
2
+ # Copyright 2013, Prylis Incorporated.
3
+ #
4
+ # This file is part of The Ruby Steering Behaviors Library.
5
+ # http://github.com/cpowell/steering-behaviors
6
+ # You can redistribute and/or modify this software only in accordance with
7
+ # the terms found in the "LICENSE" file included with the framework.
8
+
9
+ class SteeringBehaviors::Align
10
+
11
+ # Align with a moving target by observing its course.
12
+ #
13
+ # * *Args* :
14
+ # - +hunter_kinematic+ -> pursuing kinematic
15
+ # - +quarry_kinematic+ -> kinematic of the target
16
+ # * *Returns* :
17
+ # -
18
+ #
19
+ def self.steer(hunter_kinematic, quarry_kinematic)
20
+ course_diff = ( ( quarry_kinematic.heading_vec.radians - hunter_kinematic.heading_vec.radians + 3*Math::PI ) % (2*Math::PI) ) - Math::PI
21
+
22
+ target_local = SteeringBehaviors::Vector.new(course_diff * hunter_kinematic.speed, 0)
23
+ target_local.rotate!(hunter_kinematic.heading_vec.radians)
24
+ end
25
+
26
+ end
@@ -0,0 +1,34 @@
1
+ ##
2
+ # Copyright 2013, Prylis Incorporated.
3
+ #
4
+ # This file is part of The Ruby Steering Behaviors Library.
5
+ # http://github.com/cpowell/steering-behaviors
6
+ # You can redistribute and/or modify this software only in accordance with
7
+ # the terms found in the "LICENSE" file included with the framework.
8
+
9
+ class SteeringBehaviors::Arrive
10
+
11
+ # Arrive 'gently' at the goal position by decelerating smoothly.
12
+ #
13
+ # * *Args* :
14
+ # - +kinematic+ -> the thing that is moving and arriving
15
+ # - +goal_position+ -> a Vector of position
16
+ # - +gentleness+ -> higher values will make the arrival more gradual and 'gentle'
17
+ # * *Returns* :
18
+ # - a steering force
19
+ #
20
+ def self.steer(kinematic, goal_position, gentleness=0.8)
21
+ to_target = goal_position - kinematic.position_vec
22
+ dist = to_target.length
23
+
24
+ if dist > 0
25
+ desired_speed = dist / gentleness
26
+ desired_speed = [desired_speed, kinematic.max_speed].min
27
+
28
+ desired_velocity = to_target.normalize * desired_speed
29
+ return desired_velocity - kinematic.velocity_vec
30
+ else
31
+ return SteeringBehaviors::Vector.new(0,0)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ ##
2
+ # Copyright 2013, Prylis Incorporated.
3
+ #
4
+ # This file is part of The Ruby Steering Behaviors Library.
5
+ # http://github.com/cpowell/steering-behaviors
6
+ # You can redistribute and/or modify this software only in accordance with
7
+ # the terms found in the "LICENSE" file included with the framework.
8
+
9
+ class SteeringBehaviors::Broadside
10
+
11
+ # Always face one's side (i.e. a ship's broadside) to the target. Can be used for
12
+ # exposing weapons, orbiting, etc.
13
+ #
14
+ # * *Args* :
15
+ # - +hunter_kinematic+ -> pursuing kinematic
16
+ # - +quarry_kinematic+ -> kinematic of the target
17
+ # * *Returns* :
18
+ # - a steering force
19
+ #
20
+ def self.steer(hunter_kinematic, quarry_kinematic)
21
+ to_quarry = (quarry_kinematic.position_vec - hunter_kinematic.position_vec).normalize
22
+ option_a = SteeringBehaviors::Vector.new(to_quarry.y, -to_quarry.x)
23
+ option_b = SteeringBehaviors::Vector.new(-to_quarry.y, to_quarry.x)
24
+
25
+ da = option_a.delta(hunter_kinematic.heading_vec)
26
+ db = option_b.delta(hunter_kinematic.heading_vec)
27
+
28
+ best_hdg_vec = (da < db ? option_a : option_b)
29
+
30
+ desired_velocity = best_hdg_vec * hunter_kinematic.velocity_vec.length
31
+ end
32
+
33
+ end
@@ -0,0 +1,77 @@
1
+ ##
2
+ # Copyright 2013, Prylis Incorporated.
3
+ #
4
+ # This file is part of The Ruby Steering Behaviors Library.
5
+ # http://github.com/cpowell/steering-behaviors
6
+ # You can redistribute and/or modify this software only in accordance with
7
+ # the terms found in the "LICENSE" file included with the framework.
8
+
9
+ module SteeringBehaviors::Common
10
+
11
+ # A support routine used by Pursue and Evade. Observes how 'forward' the
12
+ # target is, and how 'parallel' its course is to our own.
13
+ #
14
+ # * *Args* :
15
+ # - +forwardness+ -> how forward a target is to the observer
16
+ # - +parallelness+ -> how parallel the target's course is to the observer's
17
+ # * *Returns* :
18
+ # - array of [general language description, steering force]
19
+ #
20
+ def compute_time_factor(forwardness, parallelness)
21
+ f = interval_comparison(forwardness, -0.707, 0.707)
22
+ p = interval_comparison(parallelness, -0.707, 0.707)
23
+
24
+ # Break the pursuit/evasion into nine cases, the cross product of the
25
+ # quarry being [ahead, aside, or behind] us
26
+ # and heading [parallel, perpendicular, or anti-parallel] to us.
27
+ case f
28
+ when 1
29
+ case p
30
+ when 1
31
+ gen="ahead, parallel"
32
+ tf = 1.8
33
+ when 0
34
+ gen="ahead, perpendicular"
35
+ tf = 1.35
36
+ when -1
37
+ gen="ahead, anti-parallel"
38
+ tf = 1.10
39
+ end
40
+ when 0
41
+ case p
42
+ when 1
43
+ gen="aside, parallel"
44
+ tf = 1.20
45
+ when 0
46
+ gen="aside, perpedicular"
47
+ tf = 1.20
48
+ when -1
49
+ gen="aside, anti-parallel"
50
+ tf = 1.20
51
+ end
52
+ when -1
53
+ case p
54
+ when 1
55
+ gen="behind, parallel"
56
+ tf = 1.20
57
+ when 0
58
+ gen="behind, perpendicular"
59
+ tf = 1.20
60
+ when -1
61
+ gen="behind, anti-parallel"
62
+ tf = 1.20
63
+ end
64
+ end
65
+
66
+ return [gen, tf]
67
+ end
68
+
69
+ #=============================================================
70
+ private
71
+
72
+ def interval_comparison(x, lower_bound, upper_bound)
73
+ return -1 if x < lower_bound
74
+ return 1 if x > upper_bound
75
+ return 0
76
+ end
77
+ end