shattered_controller 0.3.1 → 0.3.2
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.
- data/lib/actor/actor.rb +31 -15
- data/lib/base.rb +64 -4
- data/lib/keyboard_input/key_converter.rb +1 -1
- data/lib/keyboard_input/keyboard_input.rb +19 -12
- data/lib/mock_camera.rb +2 -2
- data/lib/runner.rb +1 -1
- data/lib/state.rb +11 -17
- metadata +2 -2
data/lib/actor/actor.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module ShatteredController
|
2
|
-
module Actor
|
2
|
+
module Actor #:nodoc:
|
3
3
|
def self.append_features(base)
|
4
4
|
super
|
5
5
|
base.extend(ClassMethods)
|
@@ -7,24 +7,36 @@ module ShatteredController
|
|
7
7
|
end
|
8
8
|
module ClassMethods
|
9
9
|
|
10
|
-
|
11
|
-
# With actors, you can send requests to each of the model, view and control
|
12
|
-
# objects, and even retrieve results from the MVC objects.
|
10
|
+
# An actor is the MVC encapsulated into one object.
|
13
11
|
#
|
14
12
|
# Here is how it works: You specify a actor in a game state with some starting
|
15
13
|
# attributes:
|
16
|
-
#
|
17
|
-
#
|
14
|
+
# class BattleState
|
15
|
+
# actor :player
|
16
|
+
# actor :bullet, :target => :player
|
17
|
+
# end
|
18
18
|
#
|
19
|
-
#
|
20
|
-
#
|
19
|
+
# With a model BulletModel defined as:
|
20
|
+
# class BulletModel
|
21
|
+
# attr_writer :target
|
22
|
+
# end
|
21
23
|
#
|
22
|
-
#
|
23
|
-
# - Model
|
24
|
-
# - View
|
25
|
-
# - Controller
|
24
|
+
# And our BulletModel will be created, with the target set to the player object.
|
26
25
|
#
|
27
|
-
#
|
26
|
+
# Setting values for the actors is done prior to initialization, so:
|
27
|
+
#
|
28
|
+
# class BulletModel
|
29
|
+
# attr_writer :target
|
30
|
+
# def initialize
|
31
|
+
# target.run_away_from(self)
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# Works fine.
|
36
|
+
#
|
37
|
+
# Actors delegate to ShatteredController::Base objects, and controllers delegate to Model and View.
|
38
|
+
#
|
39
|
+
# See ShatteredController::Base for more detail.
|
28
40
|
def actor( name, options = {} )
|
29
41
|
before_init_call( :actor, name, options )
|
30
42
|
end
|
@@ -32,11 +44,14 @@ module ShatteredController
|
|
32
44
|
end
|
33
45
|
module InstanceMethods
|
34
46
|
|
47
|
+
# This returns all of the actors created by this controller.
|
35
48
|
def actors
|
36
49
|
return @actors || []
|
37
50
|
end
|
38
51
|
|
39
|
-
#
|
52
|
+
# Same as ShatteredController::Actor::ClassMethods#actor
|
53
|
+
#
|
54
|
+
# Returns a newly created actor
|
40
55
|
def actor(name=nil, options={})
|
41
56
|
raise Error, "actor needs a name" if name.nil?
|
42
57
|
actor = Actor.new(name,load_actor_classes(name))
|
@@ -46,6 +61,7 @@ module ShatteredController
|
|
46
61
|
|
47
62
|
@actors ||= []
|
48
63
|
@actors << actor
|
64
|
+
return actor
|
49
65
|
end
|
50
66
|
|
51
67
|
private
|
@@ -68,7 +84,7 @@ module ShatteredController
|
|
68
84
|
end
|
69
85
|
|
70
86
|
# An actor is a delegator to a controller game object.
|
71
|
-
class Actor
|
87
|
+
class Actor #:nodoc:all
|
72
88
|
attr_reader :controller
|
73
89
|
def initialize( name, options = {} )
|
74
90
|
@actor_name = name
|
data/lib/base.rb
CHANGED
@@ -6,34 +6,94 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
6
6
|
require 'keyboard_input/keyboard_input'
|
7
7
|
require 'actor/actor'
|
8
8
|
|
9
|
-
module ShatteredController
|
9
|
+
module ShatteredController #:nodoc:
|
10
10
|
|
11
|
+
# Controllers tie together the Model and View. They are the only objects that know
|
12
|
+
# about both the model and the view, and as such have the responsibility of events.
|
13
|
+
#
|
14
|
+
# By default, when an unknown method is invoked on a controller object, it is delegated
|
15
|
+
# to the model and the view. IE:
|
16
|
+
#
|
17
|
+
# class BulletController < ...
|
18
|
+
# def known_method
|
19
|
+
# puts "This will not be delegated to the " + model.inspect + " or the " + view.inspect
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# class BattleState < ...
|
24
|
+
# actor :bullet
|
25
|
+
# def initialize
|
26
|
+
# bullet.known_method # This is not delegated
|
27
|
+
# bullet.unknown_method # This is delegated (and will throw an exception if unknown among the view/model)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# When obtaining a result from a delegated method, the result will be the a response in the following order
|
32
|
+
# - Model (first)
|
33
|
+
# - View (last)
|
34
|
+
#
|
35
|
+
# They are sorted so that you get the most useful response first.
|
11
36
|
class Base < ShatteredSupport::Base
|
12
37
|
attr_accessor :model, :view
|
38
|
+
|
39
|
+
before_init_call :disable_event
|
13
40
|
|
14
41
|
# Controller delegates all unknown methods to the view and model.
|
15
42
|
def method_missing(method_name, *args, &block)
|
43
|
+
return if disabled?
|
16
44
|
raise_no_method_error = true
|
17
45
|
result = nil
|
18
46
|
[view, model].each do |delegate|
|
19
47
|
if delegate.method_defined?(method_name)
|
20
|
-
result = delegate.send(method_name, *args, &block)
|
48
|
+
result = delegate.send(method_name, *args, &block)
|
21
49
|
raise_no_method_error = false
|
22
50
|
end
|
23
51
|
end
|
52
|
+
|
24
53
|
raise NoMethodError, "Model, View, and Controller have no method defined named '#{method_name}'" if raise_no_method_error
|
25
54
|
return result
|
26
55
|
end
|
27
56
|
|
28
57
|
|
29
|
-
def update_timer(time_elapsed)
|
58
|
+
def update_timer(time_elapsed)
|
59
|
+
return if @timer == :unloaded
|
30
60
|
timer.update(time_elapsed)
|
31
61
|
model.timer.update(time_elapsed)
|
32
62
|
view.timer.update(time_elapsed)
|
33
63
|
unless view.nil?
|
34
64
|
end
|
65
|
+
|
66
|
+
# This is called to the State every frame by the main game loop. All update events are now
|
67
|
+
# run through Timers.
|
68
|
+
def update_timers(time_elapsed) #:nodoc:
|
69
|
+
update_timer(time_elapsed)
|
70
|
+
actors.each { |actor| actor.update_timers(time_elapsed) }
|
71
|
+
end
|
72
|
+
|
73
|
+
# Unloading a controller will completely unload an object from the scene.
|
74
|
+
def unload!
|
75
|
+
super
|
76
|
+
end
|
77
|
+
|
78
|
+
# An object is disabled when it has been unloaded.
|
79
|
+
def disabled?
|
80
|
+
super
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def disable_event
|
86
|
+
when_unloaded do
|
87
|
+
@disabled = true
|
88
|
+
@timer=:unloaded
|
89
|
+
@model.send(:unload!) if @model
|
90
|
+
@model = nil
|
91
|
+
@view.send(:unload!) if @view
|
92
|
+
@view = nil
|
93
|
+
end
|
94
|
+
end
|
35
95
|
end
|
36
96
|
|
37
|
-
class Error < StandardError
|
97
|
+
class Error < StandardError #:nodoc:
|
38
98
|
end
|
39
99
|
end
|
40
100
|
|
@@ -4,7 +4,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
4
4
|
require 'key_converter'
|
5
5
|
|
6
6
|
module ShatteredController
|
7
|
-
module KeyboardInput
|
7
|
+
module KeyboardInput #:nodoc:
|
8
8
|
def self.append_features(base)
|
9
9
|
super
|
10
10
|
base.extend(ClassMethods)
|
@@ -44,38 +44,45 @@ module ShatteredController
|
|
44
44
|
super
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
47
|
+
def reaction_types
|
48
48
|
[:pressed, :released, :held]
|
49
49
|
end
|
50
50
|
# Given an input of:
|
51
51
|
# key :held=>:up, :action => :key_action
|
52
|
-
# This will return [:held, :
|
53
|
-
|
54
|
-
def reaction_from(options)
|
52
|
+
# This will return [:held, :key_action]
|
53
|
+
def reaction_from(options) #:nodoc:
|
55
54
|
# Define the method to send the actions when the keys are pressed/clicked/released.
|
56
|
-
|
57
|
-
|
55
|
+
reaction_types.each do |reaction_type|
|
56
|
+
if options.has_key?(reaction_type)
|
57
|
+
return [reaction_type, options[reaction_type]] if options[reaction_type].is_a? Array
|
58
|
+
return [reaction_type, [options[reaction_type]]]
|
59
|
+
end
|
58
60
|
end
|
59
61
|
raise Error, "Reaction to key input must be pressed, released, or held. #{options.inspect}" if options[:reaction].nil?
|
60
62
|
end
|
61
63
|
# See KeyboardInput::key
|
62
64
|
def key(actions={})
|
63
|
-
|
65
|
+
reaction, keys = reaction_from(actions)
|
66
|
+
keys.each { |key| key_actions << [reaction, key.to_sym, actions[:action] ] }
|
64
67
|
end
|
65
68
|
# Update_key will send each of the events to the actor object for whatever key options
|
66
69
|
# are defined.
|
67
|
-
def key_action(reaction, action, time_elapsed)
|
70
|
+
def key_action(reaction, action, time_elapsed) #:nodoc:
|
68
71
|
if reaction == :held
|
69
|
-
|
72
|
+
begin
|
73
|
+
send(action, time_elapsed)
|
74
|
+
rescue ArgumentError
|
75
|
+
send(action)
|
76
|
+
end
|
70
77
|
else
|
71
78
|
send(action)
|
72
79
|
end
|
73
80
|
end
|
74
|
-
def key_actions
|
81
|
+
def key_actions #:nodoc:
|
75
82
|
@key_actions ||= []
|
76
83
|
end
|
77
84
|
# update_input takes the input object, and sends the actor every key event this frame.
|
78
|
-
def update_input(time_elapsed, input)
|
85
|
+
def update_input(time_elapsed, input) #:nodoc:
|
79
86
|
key_actions.each do |reaction, key, action|
|
80
87
|
key_action( reaction, action, time_elapsed ) if input.key_event?(reaction,key)
|
81
88
|
end
|
data/lib/mock_camera.rb
CHANGED
data/lib/runner.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module ShatteredController
|
3
3
|
#The class Runner is present in model, view, and controller, and signifies the
|
4
4
|
#main entry point into the program. This is called by script/runner.rb
|
5
|
-
class Runner
|
5
|
+
class Runner #:nodoc:
|
6
6
|
def initialize( options = {} )
|
7
7
|
@@environment ||= options
|
8
8
|
@@environment[:input] = ShatteredController::KeyConverter.new(@@environment[:input])
|
data/lib/state.rb
CHANGED
@@ -9,7 +9,7 @@ module ShatteredController
|
|
9
9
|
# In order to set the initial position of the camera, and any other attributes you would like,
|
10
10
|
# use the following format.
|
11
11
|
# class CameraTestState < ShatteredController::Base
|
12
|
-
# camera :position =>
|
12
|
+
# camera :position => v(10,0,0), :orientation => [0.5, 0.5, 0.5, 0.5]
|
13
13
|
# end
|
14
14
|
#
|
15
15
|
# If you pass a symbol as a value, the symbol will be evaluated.
|
@@ -35,31 +35,25 @@ module ShatteredController
|
|
35
35
|
before_init_set( "self", { :"sky" => [type, options[:material]] })
|
36
36
|
end
|
37
37
|
end
|
38
|
+
# State is the entry point for your shattered game.
|
39
|
+
#
|
40
|
+
# States define the actors, communications between the actors, and control the camera.
|
41
|
+
# You can choose your starting state in config/environment.rb
|
38
42
|
class State < ShatteredController::Base
|
39
|
-
|
40
|
-
def
|
43
|
+
before_init_call :activate_state
|
44
|
+
def activate_state #:nodoc:
|
41
45
|
ShatteredSupport::Configuration.environment[:state] = self
|
42
|
-
super
|
43
46
|
end
|
44
|
-
|
47
|
+
|
48
|
+
# Returns the camera used in the state. See ShatteredController::ClassMethods#camera
|
49
|
+
def camera(*args)
|
45
50
|
if args.length == 0
|
46
51
|
return @camera ||= Runner.environment[:camera]
|
47
52
|
end
|
48
53
|
call_object_function_for_each_key(:camera, args[0])
|
49
54
|
end
|
50
55
|
|
51
|
-
|
52
|
-
# run through Timers.
|
53
|
-
def update_timers(time_elapsed)
|
54
|
-
update_timer(time_elapsed)
|
55
|
-
actors.each { |actor| actor.update_timer(time_elapsed) }
|
56
|
-
end
|
57
|
-
|
58
|
-
def unload!
|
59
|
-
actors.each { |actor| actor.unload! }
|
60
|
-
end
|
61
|
-
|
62
|
-
def sky=(type, material)
|
56
|
+
def sky=(type, material) #:nodoc:
|
63
57
|
Runner.environment[:scene].send("setSky#{type.to_s.capitalize}",material)
|
64
58
|
end
|
65
59
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: shattered_controller
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.3.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.3.2
|
7
|
+
date: 2006-06-04
|
8
8
|
summary: "Shattered Controller: Controls the game states and objects in Shattered."
|
9
9
|
require_paths:
|
10
10
|
- lib
|