shattered_controller 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|