shattered_pack 0.3.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mock_objects/shattered_ogre/input.rb +6 -0
- data/lib/mock_objects/shattered_ogre/light.rb +4 -0
- data/lib/mock_objects/shattered_ogre/mesh.rb +17 -0
- data/lib/mock_objects/shattered_ogre/node.rb +17 -0
- data/lib/mock_objects/shattered_ogre/renderer.rb +11 -0
- data/lib/mock_objects/shattered_ogre/resource_handler.rb +9 -0
- data/lib/mock_objects/shattered_ogre/scene.rb +28 -0
- data/lib/mock_objects.rb +5 -0
- data/lib/shattered_controller/actor/actor.rb +14 -53
- data/lib/shattered_controller/runner.rb +10 -4
- data/lib/shattered_controller/state.rb +29 -4
- data/lib/shattered_controller.rb +3 -2
- data/lib/shattered_model/base.rb +81 -0
- data/lib/shattered_model.rb +2 -1
- data/lib/shattered_pack/base.rb +5 -3
- data/lib/shattered_pack/keyboard_input/key_converter.rb +51 -0
- data/lib/{shattered_controller → shattered_pack}/keyboard_input/keyboard_input.rb +6 -2
- data/lib/shattered_pack/pre_initialize/pre_initialize.rb +7 -5
- data/lib/shattered_pack/timer/timed_event.rb +36 -8
- data/lib/shattered_pack/timer/timer.rb +6 -11
- data/lib/shattered_pack.rb +2 -1
- data/lib/shattered_view/base.rb +23 -11
- data/lib/shattered_view/light.rb +5 -4
- data/lib/shattered_view/mesh/mesh.rb +22 -5
- data/lib/shattered_view/node.rb +0 -8
- data/lib/shattered_view/overlay.rb +20 -0
- data/lib/shattered_view/rmaterial.rb +2 -2
- data/lib/shattered_view/runner.rb +6 -6
- data/lib/shattered_view/vector.rb +18 -2
- data/lib/shattered_view.rb +3 -2
- metadata +13 -6
- data/lib/shattered_controller/base.rb +0 -108
- data/lib/shattered_controller/keyboard_input/key_converter.rb +0 -43
- data/lib/shattered_controller/mock_camera.rb +0 -9
@@ -0,0 +1,28 @@
|
|
1
|
+
module ShatteredOgre
|
2
|
+
class Scene
|
3
|
+
def initialize(*args)
|
4
|
+
end
|
5
|
+
def createMesh(*args)
|
6
|
+
Mesh.new("fake")
|
7
|
+
end
|
8
|
+
def self.getSingleton
|
9
|
+
new
|
10
|
+
end
|
11
|
+
def createSceneNode
|
12
|
+
Node.new
|
13
|
+
end
|
14
|
+
def getRootSceneNode
|
15
|
+
Node.new
|
16
|
+
end
|
17
|
+
def createLight
|
18
|
+
ShatteredOgre::Light.new
|
19
|
+
end
|
20
|
+
def hideOverlay(name)
|
21
|
+
end
|
22
|
+
def showOverlay(name)
|
23
|
+
end
|
24
|
+
def getCamera
|
25
|
+
Node.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/mock_objects.rb
ADDED
@@ -38,70 +38,31 @@ module ShatteredController
|
|
38
38
|
#
|
39
39
|
# See ShatteredController::Base for more detail.
|
40
40
|
def actor( name, options = {} )
|
41
|
-
before_init_call( :actor, name, options )
|
41
|
+
before_init_call( :actor, name, options, true )
|
42
42
|
end
|
43
43
|
|
44
44
|
end
|
45
45
|
module InstanceMethods
|
46
|
-
|
47
|
-
|
48
|
-
def actors
|
49
|
-
return @actors || []
|
50
|
-
end
|
46
|
+
|
47
|
+
private
|
51
48
|
|
52
49
|
# Same as ShatteredController::Actor::ClassMethods#actor
|
53
50
|
#
|
54
51
|
# Returns a newly created actor
|
55
|
-
def actor(name
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
def actor(name, options={}, created_by_meta_function=false )
|
53
|
+
unless created_by_meta_function
|
54
|
+
raise Error, "Use #{name.to_s.camelize}.new instead of actor :#{name} at the instance level"
|
55
|
+
end
|
56
|
+
begin
|
57
|
+
actor = eval(name.to_s.camelize).new(options)
|
58
|
+
rescue NameError
|
59
|
+
raise Error, "Actor #{name.to_s.camelize} is not defined."
|
60
|
+
end
|
59
61
|
attr_reader(name.to_sym, actor)
|
60
|
-
|
61
|
-
|
62
|
-
@actors ||= []
|
63
|
-
@actors << actor
|
62
|
+
|
64
63
|
return actor
|
65
64
|
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def load_actor_classes(name)
|
70
|
-
actor_options={}
|
71
|
-
['model', 'view', 'controller'].each do |type|
|
72
|
-
evaled_class = nil
|
73
|
-
begin
|
74
|
-
evaled_class = eval("#{name.to_s.camelize}#{type.camelize}")
|
75
|
-
rescue NameError
|
76
|
-
next
|
77
|
-
end
|
78
|
-
actor_options[type.to_sym] = evaled_class.new
|
79
|
-
end
|
80
|
-
raise Error, "No Model, View, or Controller defined for Actor #{name}." if actor_options.empty?
|
81
|
-
return actor_options
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
# An actor is a delegator to a controller game object.
|
87
|
-
class Actor #:nodoc:all
|
88
|
-
attr_reader :controller
|
89
|
-
def initialize( name, options = {} )
|
90
|
-
@actor_name = name
|
91
|
-
@controller = (options[:controller] || ShatteredController::Base.new)
|
92
|
-
@controller.model = options[:model]
|
93
|
-
@controller.view = options[:view]
|
94
|
-
@controller.view.model = options[:model] unless @controller.view.nil?
|
95
|
-
|
96
|
-
if options[:view].nil? && options[:model].nil? && @controller.nil? && !options[:testing]
|
97
|
-
raise NameError, "No model view or controller found for actor #{name}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Delegate to controller
|
102
|
-
def method_missing(name, *args, &block)
|
103
|
-
@controller.send(name, *args, &block)
|
104
|
-
end
|
65
|
+
|
105
66
|
end
|
106
67
|
end
|
107
68
|
end
|
@@ -5,28 +5,34 @@ module ShatteredController
|
|
5
5
|
class Runner #:nodoc:
|
6
6
|
def initialize( options = {} )
|
7
7
|
@@environment ||= options
|
8
|
-
@@environment[:input] =
|
8
|
+
@@environment[:input] = ShatteredPack::KeyConverter.new(@@environment[:input])
|
9
9
|
end
|
10
|
+
|
10
11
|
#Every time this exits, a game dies.
|
11
|
-
def start_game
|
12
|
+
def start_game(env)
|
13
|
+
@@environment = env
|
12
14
|
each_frame do |time_elapsed|
|
13
15
|
@@environment[:state].update_timers(time_elapsed)
|
14
16
|
@@environment[:input].flush
|
17
|
+
@@environment[:renderer].quit if @@environment[:quit]
|
15
18
|
end
|
16
19
|
end
|
20
|
+
|
17
21
|
def each_frame
|
18
22
|
yield @@environment[:renderer].timeSinceLastFrame while @@environment[:renderer].nextFrame
|
19
23
|
end
|
24
|
+
|
20
25
|
def self.environment
|
21
26
|
begin
|
22
27
|
return @@environment
|
23
28
|
rescue NameError
|
24
|
-
return mock_environment
|
29
|
+
return @@environment = mock_environment
|
25
30
|
end
|
26
31
|
end
|
32
|
+
|
27
33
|
def self.mock_environment
|
28
34
|
retv = {}
|
29
|
-
retv[:camera] =
|
35
|
+
retv[:camera] = ShatteredView::Node.new
|
30
36
|
return retv
|
31
37
|
end
|
32
38
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/actor/actor'
|
2
|
+
|
1
3
|
module ShatteredController
|
2
4
|
def self.append_features(base)
|
3
5
|
super
|
@@ -30,30 +32,53 @@ module ShatteredController
|
|
30
32
|
# This blurs the lines between view and controller.
|
31
33
|
# Valid types are [:box]
|
32
34
|
def sky(type, options = {})
|
33
|
-
before_init_set( "self", { :
|
35
|
+
before_init_set( "self", { :sky => [type, options[:material]] })
|
34
36
|
end
|
35
37
|
end
|
36
38
|
# State is the entry point for your shattered game.
|
37
39
|
#
|
38
40
|
# States define the actors, communications between the actors, and control the camera.
|
39
41
|
# You can choose your starting state in config/environment.rb
|
40
|
-
class State <
|
42
|
+
class State < ShatteredPack::Base
|
41
43
|
before_init_call :activate_state
|
44
|
+
attr_reader :actors
|
45
|
+
|
42
46
|
def activate_state #:nodoc:
|
43
47
|
ShatteredPack::Configuration.environment[:state] = self
|
48
|
+
@actors = []
|
49
|
+
end
|
50
|
+
|
51
|
+
# This is called to the State every frame by the main game loop. All update events are now
|
52
|
+
# run through Timers.
|
53
|
+
def update_timers(time_elapsed) #:nodoc:
|
54
|
+
actors.each { |actor| actor.update_timer(time_elapsed) }
|
55
|
+
self.time_elapsed = time_elapsed
|
56
|
+
timer.update(time_elapsed)
|
44
57
|
end
|
45
58
|
|
46
59
|
# Returns the camera used in the state. See ShatteredController::ClassMethods#camera
|
47
60
|
def camera(*args)
|
48
61
|
if args.length == 0
|
49
|
-
return @camera ||= Runner.environment[:camera]
|
50
|
-
end
|
62
|
+
return @camera ||= Runner.environment[:camera]
|
63
|
+
end
|
51
64
|
call_object_function_for_each_key(:camera, args[0])
|
52
65
|
end
|
53
66
|
|
54
67
|
def sky=(type, material) #:nodoc:
|
55
68
|
Runner.environment[:scene].send("setSky#{type.to_s.capitalize}",material)
|
56
69
|
end
|
70
|
+
|
71
|
+
def quit
|
72
|
+
Runner.environment[:quit]=true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Error < StandardError # :nodoc:
|
57
77
|
end
|
58
78
|
end
|
59
79
|
|
80
|
+
|
81
|
+
ShatteredController::State.class_eval do
|
82
|
+
include ShatteredController::Actor
|
83
|
+
end
|
84
|
+
|
data/lib/shattered_controller.rb
CHANGED
data/lib/shattered_model/base.rb
CHANGED
@@ -12,7 +12,86 @@ module ShatteredModel #:nodoc:
|
|
12
12
|
#
|
13
13
|
# Models are useful for unit tests and for making game rules.
|
14
14
|
# They are where all logic (AI/collisions/etc) go.
|
15
|
+
#
|
16
|
+
# They can also specify keyboard input.
|
15
17
|
class Base < ShatteredPack::Base
|
18
|
+
attr_accessor :view
|
19
|
+
before_init_call :setup_view
|
20
|
+
before_init_call :register_with_state
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Registers an actor with a state, Called when the model is created
|
25
|
+
def register_with_state
|
26
|
+
return if state.nil?
|
27
|
+
state.actors << self
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Creates a view object and ties it directly into the model through method redefiniton
|
32
|
+
def setup_view
|
33
|
+
@view = eval("#{self.class}View").new if eval("defined? #{self.class}View")
|
34
|
+
|
35
|
+
methods.each do |method|
|
36
|
+
next if( method =~ /^model_/ || Base.instance_methods.include?(method))
|
37
|
+
redefine_method_for_view(method)
|
38
|
+
end
|
39
|
+
|
40
|
+
@view.model = self if @view
|
41
|
+
end
|
42
|
+
|
43
|
+
# Uses meta-programming to redefine methods to also call view methods
|
44
|
+
# old methods are aliased to model_#{method}
|
45
|
+
def redefine_method_for_view(method)
|
46
|
+
self.class.instance_eval do
|
47
|
+
@@model_method ||= {}
|
48
|
+
|
49
|
+
module_eval <<-EOF
|
50
|
+
unless @@model_method[:#{method}]
|
51
|
+
@@model_method[:#{method}] = instance_method(:#{method})
|
52
|
+
def #{method}(*args, &block)
|
53
|
+
retv = @@model_method[:#{method}].bind(self).call(*args, &block)
|
54
|
+
view.send(:#{method},*args, &block) if (!view.nil? && view.class.method_defined?(:#{method}))
|
55
|
+
return retv
|
56
|
+
end
|
57
|
+
end
|
58
|
+
EOF
|
59
|
+
# We cannot use this method because we will lose the power of blocks inside our code.
|
60
|
+
# This should be fixed in Ruby 1.9, but for now we use eval (evil) and string interpolation
|
61
|
+
# define_method(method) do |*args|
|
62
|
+
# retv = model_method.bind(self).call(*args)
|
63
|
+
# view.send(method,*args) if (!view.nil? && view.class.method_defined?(method))
|
64
|
+
# return retv
|
65
|
+
# end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
public
|
70
|
+
|
71
|
+
# Propogates events to view as well.
|
72
|
+
def update_timer(time_elapsed)#:nodoc:
|
73
|
+
return if @timer == :unloaded
|
74
|
+
[self, view].each do |base|
|
75
|
+
next if base.nil?
|
76
|
+
base.time_elapsed = time_elapsed
|
77
|
+
base.timer.update(time_elapsed)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Unloading a controller will completely unload an object from the scene.
|
82
|
+
def unload!
|
83
|
+
super
|
84
|
+
@disabled = true
|
85
|
+
@timer=:unloaded
|
86
|
+
@view.send(:unload!) if @view
|
87
|
+
self.view = nil
|
88
|
+
end
|
89
|
+
|
90
|
+
# An object is disabled when it has been unloaded.
|
91
|
+
def disabled?
|
92
|
+
super
|
93
|
+
end
|
94
|
+
|
16
95
|
def fuzzy_logic=(file) #:nodoc:
|
17
96
|
@fuzzy_logic = FuzzyLogic.new
|
18
97
|
@fuzzy_logic.parse_fuzzy_file(File.dirname(__FILE__)+"/#{file}")
|
@@ -20,5 +99,7 @@ module ShatteredModel #:nodoc:
|
|
20
99
|
def update_fuzzy_logic #:nodoc:
|
21
100
|
@fuzzy_logic.update(self)
|
22
101
|
end
|
102
|
+
|
23
103
|
end
|
24
104
|
end
|
105
|
+
|
data/lib/shattered_model.rb
CHANGED
data/lib/shattered_pack/base.rb
CHANGED
@@ -4,6 +4,7 @@ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname
|
|
4
4
|
|
5
5
|
require 'timer/timer'
|
6
6
|
require 'pre_initialize/pre_initialize'
|
7
|
+
require 'keyboard_input/keyboard_input'
|
7
8
|
|
8
9
|
module ShatteredPack #:nodoc:
|
9
10
|
|
@@ -12,10 +13,10 @@ module ShatteredPack #:nodoc:
|
|
12
13
|
alias_method :per_second, :time_elapsed
|
13
14
|
|
14
15
|
# This is overwritten to allow for a pre_initialize before initialize
|
15
|
-
def self.new(
|
16
|
+
def self.new(options={}) #:nodoc
|
16
17
|
new_base = allocate
|
17
|
-
new_base.pre_initialize
|
18
|
-
new_base.send(:initialize
|
18
|
+
new_base.pre_initialize(options)
|
19
|
+
new_base.send(:initialize)
|
19
20
|
return new_base
|
20
21
|
end
|
21
22
|
|
@@ -124,4 +125,5 @@ end
|
|
124
125
|
ShatteredPack::Base.class_eval do
|
125
126
|
include ShatteredPack::Timer
|
126
127
|
include ShatteredPack::PreInitialize
|
128
|
+
include ShatteredPack::KeyboardInput
|
127
129
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ShatteredPack
|
2
|
+
# This is a wrapper around Ogre's input listener.
|
3
|
+
# It allows us to query the status of each device every frame.
|
4
|
+
class KeyConverter #:nodoc:
|
5
|
+
|
6
|
+
def initialize( ogre_input )
|
7
|
+
@ogre_input = ogre_input
|
8
|
+
end
|
9
|
+
|
10
|
+
def key_event?( type, key_symbol )
|
11
|
+
ogre_key_method = "isKey#{type.to_s.capitalize}".to_sym
|
12
|
+
return @ogre_input.send(ogre_key_method, self.class.convert(key_symbol))
|
13
|
+
end
|
14
|
+
|
15
|
+
def flush
|
16
|
+
@ogre_input.flush
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.back_conversions
|
20
|
+
@@back_conversions ||= conversions.invert
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.conversions
|
24
|
+
begin
|
25
|
+
return @@conversions
|
26
|
+
rescue NameError
|
27
|
+
end
|
28
|
+
@@conversions = {}
|
29
|
+
ShatteredOgre.constants.each do |constant|
|
30
|
+
kc_evaled = eval("ShatteredOgre::#{constant}")
|
31
|
+
@@conversions[kc_evaled] = symbolize(constant[3..-1].downcase) if constant.to_s =~ /^KC_/
|
32
|
+
end
|
33
|
+
return @@conversions
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.convert( kc_character )
|
37
|
+
return self.conversions[kc_character] if kc_character.is_a? Fixnum
|
38
|
+
return self.back_conversions[kc_character]
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.symbolize( name )
|
44
|
+
exceptions = { 'pgdown' => :page_down,
|
45
|
+
'pgup' => :page_up }
|
46
|
+
return name.to_sym if exceptions[name] == nil
|
47
|
+
return exceptions[name]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -3,7 +3,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
3
3
|
|
4
4
|
require 'key_converter'
|
5
5
|
|
6
|
-
module
|
6
|
+
module ShatteredPack
|
7
7
|
module KeyboardInput #:nodoc:
|
8
8
|
def self.append_features(base)
|
9
9
|
super
|
@@ -36,7 +36,7 @@ module ShatteredController
|
|
36
36
|
end
|
37
37
|
|
38
38
|
module InstanceMethods
|
39
|
-
def pre_initialize
|
39
|
+
def pre_initialize(options)
|
40
40
|
# update our keyboard input
|
41
41
|
timer.every(:frame) do |time_elapsed|
|
42
42
|
update_input(time_elapsed, ShatteredController::Runner.environment[:input])
|
@@ -72,20 +72,24 @@ module ShatteredController
|
|
72
72
|
return [action, []] unless action.is_a? Hash
|
73
73
|
return [action.keys[0], action.values[0]]
|
74
74
|
end
|
75
|
+
|
75
76
|
# See KeyboardInput::key
|
76
77
|
def key(actions={})
|
77
78
|
reaction, keys = reaction_from(actions)
|
78
79
|
action, params = action_from(actions)
|
79
80
|
keys.each { |key| key_actions << [reaction, key.to_sym, action, params ] }
|
80
81
|
end
|
82
|
+
|
81
83
|
# Update_key will send each of the events to the actor object for whatever key options
|
82
84
|
# are defined.
|
83
85
|
def key_action(reaction, action, time_elapsed, params) #:nodoc:
|
84
86
|
send(action, *params)
|
85
87
|
end
|
88
|
+
|
86
89
|
def key_actions #:nodoc:
|
87
90
|
@key_actions ||= []
|
88
91
|
end
|
92
|
+
|
89
93
|
# update_input takes the input object, and sends the actor every key event this frame.
|
90
94
|
def update_input(time_elapsed, input) #:nodoc:
|
91
95
|
key_actions.each do |reaction, key, action, params|
|
@@ -44,9 +44,11 @@ module ShatteredPack
|
|
44
44
|
# This function is called after an object is allocated, but before it's initialized.
|
45
45
|
#
|
46
46
|
# See ShatteredPack::ClassMethods#before_init_call for usage.
|
47
|
-
def pre_initialize #:nodoc:
|
47
|
+
def pre_initialize(options) #:nodoc:
|
48
48
|
pre_initialize_set
|
49
49
|
pre_initialize_call
|
50
|
+
# Set the options for new(...) without evaluating symbols
|
51
|
+
call_object_function_for_each_key("self",options, false)
|
50
52
|
end
|
51
53
|
|
52
54
|
# Used in pre_initialize
|
@@ -72,15 +74,15 @@ module ShatteredPack
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
def call_object_function_for_each_key( actor, options )
|
77
|
+
def call_object_function_for_each_key( actor, options, evaluate_symbols=true )
|
76
78
|
options.each_pair do |action, params|
|
77
|
-
call_object_function actor, "#{action}=", params
|
79
|
+
call_object_function actor, "#{action}=", params, evaluate_symbols
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
81
|
-
def call_object_function(actor, action, params)
|
83
|
+
def call_object_function(actor, action, params, evaluate_symbols=true)
|
82
84
|
begin
|
83
|
-
if params.is_a?
|
85
|
+
if params.is_a?(Symbol) && evaluate_symbols
|
84
86
|
params = eval(params.to_s)
|
85
87
|
end
|
86
88
|
rescue NameError
|
@@ -3,14 +3,19 @@ module ShatteredPack
|
|
3
3
|
|
4
4
|
class Timer
|
5
5
|
attr_reader :events_remaining
|
6
|
-
def initialize
|
6
|
+
def initialize(context)
|
7
7
|
@events_remaining = []
|
8
|
+
@context = context
|
8
9
|
end
|
9
|
-
def in(seconds, &block)
|
10
|
-
|
10
|
+
def in(seconds, options = {}, &block)
|
11
|
+
event = TimedEvent.new(@context, seconds, options, &block)
|
12
|
+
@events_remaining << event
|
13
|
+
return event
|
11
14
|
end
|
12
|
-
def every(seconds, &block)
|
13
|
-
|
15
|
+
def every(seconds, options = {}, &block)
|
16
|
+
event = ContinuousTimedEvent.new(@context, seconds, options, &block)
|
17
|
+
@events_remaining << event
|
18
|
+
return event
|
14
19
|
end
|
15
20
|
def update(time_elapsed)
|
16
21
|
events_for_update = @events_remaining.dup
|
@@ -23,8 +28,10 @@ module ShatteredPack
|
|
23
28
|
|
24
29
|
class TimedEvent
|
25
30
|
attr_accessor :time_remaining
|
26
|
-
def initialize(seconds, &block)
|
31
|
+
def initialize(context, seconds, options={}, &block)
|
32
|
+
@context=context
|
27
33
|
@event = block
|
34
|
+
@options = options
|
28
35
|
if(seconds != :frame)
|
29
36
|
@time_remaining = seconds
|
30
37
|
@initial_time = @time_remaining
|
@@ -34,7 +41,7 @@ module ShatteredPack
|
|
34
41
|
end
|
35
42
|
end
|
36
43
|
def update(time_elapsed)
|
37
|
-
return if processed?
|
44
|
+
return if processed? || stopped?
|
38
45
|
@time_remaining -= time_elapsed
|
39
46
|
if time_up?
|
40
47
|
process_event
|
@@ -47,17 +54,38 @@ module ShatteredPack
|
|
47
54
|
def reset
|
48
55
|
@time_remaining = @initial_time
|
49
56
|
end
|
57
|
+
# Stop the timer
|
58
|
+
def stop
|
59
|
+
@stopped = true
|
60
|
+
end
|
61
|
+
def stopped?
|
62
|
+
!@stopped.nil?
|
63
|
+
end
|
50
64
|
private
|
51
65
|
def process_event
|
52
|
-
@event.call(@initial_time - @time_remaining)
|
66
|
+
@event.call(@initial_time - @time_remaining) if satisfies_condition?
|
53
67
|
end
|
54
68
|
def time_up?
|
55
69
|
return @time_remaining <= 0
|
56
70
|
end
|
71
|
+
def satisfies_condition?
|
72
|
+
return true if(@options[:if].nil? && @options[:unless].nil?)
|
73
|
+
unless @options[:if].nil?
|
74
|
+
result=@options[:if]
|
75
|
+
result=@context.send(result) if(result.is_a? Symbol)
|
76
|
+
return result
|
77
|
+
end
|
78
|
+
unless @options[:unless].nil?
|
79
|
+
result=@options[:unless]
|
80
|
+
result=@context.send(result) if(result.is_a? Symbol)
|
81
|
+
return !result
|
82
|
+
end
|
83
|
+
end
|
57
84
|
end
|
58
85
|
|
59
86
|
class ContinuousTimedEvent < TimedEvent
|
60
87
|
def update(time_elapsed)
|
88
|
+
return if stopped?
|
61
89
|
@time_remaining -= time_elapsed
|
62
90
|
if(time_up?)
|
63
91
|
process_event
|
@@ -35,22 +35,17 @@ module ShatteredPack
|
|
35
35
|
end
|
36
36
|
time = options[:in] || options[:every]
|
37
37
|
action = options[:action]
|
38
|
-
before_init_call(:
|
39
|
-
before_init_call(:
|
38
|
+
before_init_call(:create_timer, :in, time, action, options) unless options[:in].nil?
|
39
|
+
before_init_call(:create_timer, :every, time, action, options) unless options[:every].nil?
|
40
40
|
end
|
41
41
|
end
|
42
42
|
module InstanceMethods
|
43
43
|
def timer
|
44
|
-
@timer ||= Timer.new
|
44
|
+
@timer ||= Timer.new(self)
|
45
45
|
end
|
46
46
|
private
|
47
|
-
def
|
48
|
-
timer.
|
49
|
-
timer_enactment(action, time_elapsed)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
def timer_every(time, action)
|
53
|
-
timer.every(time) do |time_elapsed|
|
47
|
+
def create_timer(type, time, action, options)
|
48
|
+
timer.send(type, time, options) do |time_elapsed|
|
54
49
|
timer_enactment(action, time_elapsed)
|
55
50
|
end
|
56
51
|
end
|
@@ -66,7 +61,7 @@ module ShatteredPack
|
|
66
61
|
send(action.to_sym)
|
67
62
|
end
|
68
63
|
rescue ArgumentError => argument_error
|
69
|
-
raise argument_error unless argument_error.message.to_sym ==
|
64
|
+
raise argument_error unless argument_error.message.to_sym == "wrong number of arguments (0 for 1)".to_sym
|
70
65
|
send(action.to_sym,time_elapsed)
|
71
66
|
end
|
72
67
|
end
|
data/lib/shattered_pack.rb
CHANGED
data/lib/shattered_view/base.rb
CHANGED
@@ -42,10 +42,10 @@ module ShatteredView #:nodoc:
|
|
42
42
|
# directions equally.
|
43
43
|
# Example: light :fireplace, :position => [0,-5,20], :diffuse => [1,0.5,0.5], :specular => [1,0,0], :attenuation => [8000,0,4,0.3]
|
44
44
|
# Parameters:
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
45
|
+
# position:: the x,y,z position or vector position
|
46
|
+
# diffuse:: the r,g,b value of the diffuse color
|
47
|
+
# specular:: the r,g,b value of the specular color
|
48
|
+
# attenuation:: arguments are range, constant, linear, quadratic
|
49
49
|
# range is how far the light will extend
|
50
50
|
# constant The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation
|
51
51
|
# linear The linear factor in the attenuation formula: 1 means attenuate evenly over the distance
|
@@ -53,18 +53,19 @@ module ShatteredView #:nodoc:
|
|
53
53
|
#
|
54
54
|
# Directional Light - this light is like the positional light, except instead of position it has only direction
|
55
55
|
# Example: light :sun, :direction => [0,-1,-1], :diffuse => [1,1,1], :specular => [1,1,1]
|
56
|
-
#
|
57
|
-
#
|
56
|
+
# direction:: the direction light emanates from
|
57
|
+
# other:: same as point light above.
|
58
58
|
#
|
59
|
+
# Note: The following type of light is not currently implemented in shattered.
|
59
60
|
# Spotlight - this light has both a direction and a position, as well as other factors.
|
60
61
|
# Example: light :flashlight...
|
61
|
-
# TODO: This type of light is not currently implemented in shattered.
|
62
62
|
|
63
63
|
def light(name, options = {})
|
64
64
|
before_init_set "self", {:new_light => [name]}
|
65
65
|
before_init_set name, options
|
66
66
|
end
|
67
67
|
|
68
|
+
# The following is not yet implemented:
|
68
69
|
# Particle systems are defined in .particle files
|
69
70
|
# - This works for first order particle systems --
|
70
71
|
# - We need to look into second and third order particle systems
|
@@ -78,8 +79,12 @@ module ShatteredView #:nodoc:
|
|
78
79
|
end
|
79
80
|
|
80
81
|
class Base < ShatteredPack::Base
|
81
|
-
|
82
|
-
|
82
|
+
attr_accessor :controller, :model
|
83
|
+
attr_reader :lights
|
84
|
+
|
85
|
+
def visible=(visible)
|
86
|
+
node.visible=(visible)
|
87
|
+
end
|
83
88
|
|
84
89
|
def rotate(vector, amount)
|
85
90
|
node.rotate(vector, amount)
|
@@ -107,13 +112,20 @@ module ShatteredView #:nodoc:
|
|
107
112
|
end
|
108
113
|
|
109
114
|
def new_light=(name)
|
110
|
-
define_accessor("@lights", ShatteredView::Light.new, name)
|
115
|
+
#define_accessor("@lights", ShatteredView::Light.new, name)
|
116
|
+
@lights ||= {}
|
117
|
+
name = name.to_sym
|
118
|
+
@lights[name] = Light.new
|
119
|
+
self.class.send(:define_method, name) do
|
120
|
+
@lights[name]
|
121
|
+
end
|
111
122
|
end
|
112
123
|
|
113
124
|
def new_particle_system=(name, template)
|
114
125
|
define_accessor("@particle_systems", ShatteredView::ParticleSystem.new(template), name)
|
115
126
|
end
|
116
|
-
|
117
127
|
|
128
|
+
|
129
|
+
|
118
130
|
#Return all of the children attached to this view's scene node
|
119
131
|
def children
|
120
132
|
node.children
|
data/lib/shattered_view/light.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
module ShatteredView
|
2
|
+
|
2
3
|
class Light
|
3
4
|
def light
|
4
|
-
@light ||= Scene.getSingleton().createLight
|
5
|
+
@light ||= ShatteredOgre::Scene.getSingleton().createLight
|
5
6
|
end
|
6
7
|
def direction=(*direction)
|
7
8
|
light.setType(ShatteredOgre::Light::LT_DIRECTIONAL)
|
8
|
-
light.setDirection(direction.
|
9
|
+
light.setDirection(direction.to_v3)
|
9
10
|
end
|
10
11
|
def diffuse=(r,g,b)
|
11
12
|
light.setDiffuseColour(r,g,b)
|
@@ -15,10 +16,10 @@ module ShatteredView
|
|
15
16
|
end
|
16
17
|
def position=(pos)
|
17
18
|
light.setType(ShatteredOgre::Light::LT_POINT)
|
18
|
-
light.setPosition(pos.
|
19
|
+
light.setPosition(pos.to_v3)
|
19
20
|
end
|
20
21
|
def ambient=(r,g,b)
|
21
|
-
Scene.getSingleton().setAmbientLight(r,g,b);
|
22
|
+
ShatteredOgre::Scene.getSingleton().setAmbientLight(r,g,b);
|
22
23
|
end
|
23
24
|
def attenuation=(range, const, linear, quad)
|
24
25
|
light.setType(ShatteredOgre::Light::LT_POINT)
|
@@ -35,6 +35,7 @@ module ShatteredView
|
|
35
35
|
before_init_call( :mesh, file, options )
|
36
36
|
end
|
37
37
|
|
38
|
+
# Note: The following is broken in 0.4
|
38
39
|
# Animations declare helper functions for mesh animations.
|
39
40
|
#
|
40
41
|
# class AnimatedRubyView < ...
|
@@ -59,6 +60,14 @@ module ShatteredView
|
|
59
60
|
|
60
61
|
module InstanceMethods
|
61
62
|
|
63
|
+
public
|
64
|
+
|
65
|
+
#TODO - Should it be a list like this, or a hash with the name as the index?
|
66
|
+
def meshes
|
67
|
+
# children.collect { |child| child if child.is_a? Mesh }
|
68
|
+
@meshes
|
69
|
+
end
|
70
|
+
|
62
71
|
private
|
63
72
|
def mesh(file, options={})
|
64
73
|
mesh = Mesh.new(file)
|
@@ -68,10 +77,9 @@ module ShatteredView
|
|
68
77
|
call_object_function_for_each_key(name, options)
|
69
78
|
#keep track of the meshes we create
|
70
79
|
mesh.attach_to(node)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
children.collect { |child| child.is_a? Mesh }
|
80
|
+
@meshes ||= []
|
81
|
+
@meshes << mesh
|
82
|
+
mesh
|
75
83
|
end
|
76
84
|
|
77
85
|
def animation(name, options={})
|
@@ -83,7 +91,7 @@ module ShatteredView
|
|
83
91
|
end
|
84
92
|
end
|
85
93
|
EOF
|
86
|
-
call_object_function_for_each_key(
|
94
|
+
call_object_function_for_each_key("#{mesh.name}.#{name}".to_sym, options)
|
87
95
|
end
|
88
96
|
end
|
89
97
|
|
@@ -114,6 +122,15 @@ module ShatteredView
|
|
114
122
|
return @animations[animation]
|
115
123
|
end
|
116
124
|
|
125
|
+
#Set the material on this mesh. Accepts a string or a rmaterial
|
126
|
+
def material=( material )
|
127
|
+
if material.is_a? RMaterial
|
128
|
+
scene_node.generateTangents if material.tangent_space
|
129
|
+
material = material.name
|
130
|
+
end
|
131
|
+
scene_node.setMaterial(material.to_s)
|
132
|
+
end
|
133
|
+
|
117
134
|
# Remove the Ogre Mesh from the scene
|
118
135
|
def remove_from_scene
|
119
136
|
scene_node.removeFromScene
|
data/lib/shattered_view/node.rb
CHANGED
@@ -90,14 +90,6 @@ module ShatteredView
|
|
90
90
|
scene_node.scale amount
|
91
91
|
end
|
92
92
|
|
93
|
-
def material=( material )
|
94
|
-
if material.is_a? RMaterial
|
95
|
-
scene_node.generateTangents if material.tangent_space
|
96
|
-
material = material.name
|
97
|
-
end
|
98
|
-
scene_node.setMaterial(material.to_s)
|
99
|
-
end
|
100
|
-
|
101
93
|
def visible=(visible)
|
102
94
|
scene_node.setVisible(visible)
|
103
95
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ShatteredView
|
2
|
+
class Overlay
|
3
|
+
attr_reader :name
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
hide
|
7
|
+
end
|
8
|
+
def show
|
9
|
+
ShatteredOgre::Scene::getSingleton.showOverlay(name)
|
10
|
+
@visible = true
|
11
|
+
end
|
12
|
+
def hide
|
13
|
+
ShatteredOgre::Scene::getSingleton.hideOverlay(name)
|
14
|
+
@visible = false
|
15
|
+
end
|
16
|
+
def visible?
|
17
|
+
@visible
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -14,7 +14,7 @@ module ShatteredView
|
|
14
14
|
ShatteredOgre::ResourceHandler.getSingleton.addCustomMaterial(name.to_s, result)
|
15
15
|
end
|
16
16
|
def create_ogre_material=(*args)
|
17
|
-
load!("#{SHATTERED_ROOT}/media/templates/#{template}.rmaterial")
|
17
|
+
load!("#{SHATTERED_ROOT}/app/media/common/templates/#{template}.rmaterial")
|
18
18
|
create_ogre_material!
|
19
19
|
end
|
20
20
|
def method_missing(name, *args)
|
@@ -22,7 +22,7 @@ module ShatteredView
|
|
22
22
|
if name.to_s[-1].chr == "="
|
23
23
|
name = name.to_s[0...-1].to_sym
|
24
24
|
# Set the instance variable to the sent variable
|
25
|
-
ivar =
|
25
|
+
ivar = "@#{ name }".to_sym
|
26
26
|
instance_variable_set(ivar, args[0])
|
27
27
|
else
|
28
28
|
begin
|
@@ -4,14 +4,14 @@ module ShatteredView
|
|
4
4
|
class Runner #:nodoc:
|
5
5
|
def initialize(options = {})
|
6
6
|
generate_plugin_config
|
7
|
-
Resources.instance.add_resource_paths("/app/
|
7
|
+
Resources.instance.add_resource_paths("/media", "/app/media", "/app/views")
|
8
8
|
@renderer = ShatteredOgre::Renderer.new
|
9
9
|
raise Error, "Renderer failed to initialize Ogre" if @renderer.failed
|
10
10
|
@scene = ShatteredOgre::Scene.new(translate_to_scene_type(options[:scene_manager]))
|
11
11
|
end
|
12
12
|
def generate_plugin_config
|
13
|
-
plugin_directory = SHATTERED_ROOT+"/config/"
|
14
|
-
generated_plugin = plugin_directory+ "plugins."
|
13
|
+
plugin_directory = SHATTERED_ROOT+"/config/"
|
14
|
+
generated_plugin = plugin_directory+ "plugins."
|
15
15
|
generator = plugin_directory + "ogre_plugins.rcfg"
|
16
16
|
if PLATFORM =~ /mswin/
|
17
17
|
generated_plugin += "win32"
|
@@ -22,13 +22,13 @@ module ShatteredView
|
|
22
22
|
end
|
23
23
|
process_plugin(generator, generated_plugin+".cfg")
|
24
24
|
end
|
25
|
-
def process_plugin(base, generate_to)
|
25
|
+
def process_plugin(base, generate_to)
|
26
26
|
puts "Generating #{generate_to} from #{base}, #{File.exists?(base)}"
|
27
27
|
return unless File.exists?(base)
|
28
28
|
generated_banner = "\n\r//=== This file is generated. Modify the .rcfg instead. ===\n\r\n\r"
|
29
29
|
to_write = generated_banner + ERB.new(File.open(base,"r").read).result + generated_banner
|
30
|
-
output = File.open(generate_to, "w")
|
31
|
-
output.syswrite(to_write)
|
30
|
+
output = File.open(generate_to, "w")
|
31
|
+
output.syswrite(to_write)
|
32
32
|
output.close
|
33
33
|
end
|
34
34
|
def translate_to_scene_type( symbol )
|
@@ -36,6 +36,11 @@ class Symbol #:nodoc:
|
|
36
36
|
def *(number)
|
37
37
|
return to_v * number
|
38
38
|
end
|
39
|
+
|
40
|
+
# Addition for vectors
|
41
|
+
def +(number)
|
42
|
+
return to_v + number
|
43
|
+
end
|
39
44
|
end
|
40
45
|
|
41
46
|
class Array #:nodoc:
|
@@ -223,18 +228,29 @@ class Vector
|
|
223
228
|
# Equality test. This method will return true if all components of both vectors are
|
224
229
|
# indentical.
|
225
230
|
def ==(vector)
|
231
|
+
vector = vector.to_v if vector.is_a?(Symbol)
|
226
232
|
vector.kind_of?(Vector) &&
|
227
233
|
x == vector.x &&
|
228
234
|
y == vector.y &&
|
229
235
|
z == vector.z
|
230
236
|
end
|
231
237
|
|
238
|
+
# Create a unique identifier based on x, y and z.
|
239
|
+
def hash
|
240
|
+
return self.to_a.hash
|
241
|
+
end
|
242
|
+
|
243
|
+
# Equality test for hash indexes.
|
244
|
+
def eql?(other)
|
245
|
+
return self.to_a.eql?(other.to_a)
|
246
|
+
end
|
247
|
+
|
232
248
|
private
|
233
249
|
|
234
250
|
def convert_args_to_vector(*args)
|
235
251
|
args.flatten!
|
236
|
-
if args.first.is_a?
|
237
|
-
args.first
|
252
|
+
if(args.first.is_a?(Vector) || args.first.is_a?(Symbol))
|
253
|
+
args.first.to_v
|
238
254
|
else
|
239
255
|
args.to_v
|
240
256
|
end
|
data/lib/shattered_view.rb
CHANGED
@@ -2,6 +2,7 @@ require 'shattered_ogre'
|
|
2
2
|
require 'shattered_pack'
|
3
3
|
raise( ShatteredPack::Error, "Could not find ShatteredOgre (a ShatteredView dependency)" ) unless defined? ShatteredOgre
|
4
4
|
|
5
|
-
%w(vector utilities node camera extensions runner rmaterial base resources).each do |dependency|
|
6
|
-
|
5
|
+
%w(vector utilities node camera overlay light extensions runner rmaterial base resources).each do |dependency|
|
6
|
+
dependency = "shattered_view/#{dependency}"
|
7
|
+
require dependency
|
7
8
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: shattered_pack
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-
|
6
|
+
version: "0.4"
|
7
|
+
date: 2006-09-10 00:00:00 -06:00
|
8
8
|
summary: "Shattered Pack: The combination of model/view/controllers and the domain specific language for each."
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -28,22 +28,28 @@ cert_chain:
|
|
28
28
|
authors: []
|
29
29
|
|
30
30
|
files:
|
31
|
+
- lib/mock_objects.rb
|
31
32
|
- lib/shattered_controller.rb
|
32
33
|
- lib/shattered_model.rb
|
33
34
|
- lib/shattered_pack.rb
|
34
35
|
- lib/shattered_view.rb
|
35
|
-
- lib/
|
36
|
-
- lib/
|
36
|
+
- lib/mock_objects/shattered_ogre/input.rb
|
37
|
+
- lib/mock_objects/shattered_ogre/light.rb
|
38
|
+
- lib/mock_objects/shattered_ogre/mesh.rb
|
39
|
+
- lib/mock_objects/shattered_ogre/node.rb
|
40
|
+
- lib/mock_objects/shattered_ogre/renderer.rb
|
41
|
+
- lib/mock_objects/shattered_ogre/resource_handler.rb
|
42
|
+
- lib/mock_objects/shattered_ogre/scene.rb
|
37
43
|
- lib/shattered_controller/runner.rb
|
38
44
|
- lib/shattered_controller/state.rb
|
39
45
|
- lib/shattered_controller/actor/actor.rb
|
40
|
-
- lib/shattered_controller/keyboard_input/key_converter.rb
|
41
|
-
- lib/shattered_controller/keyboard_input/keyboard_input.rb
|
42
46
|
- lib/shattered_model/base.rb
|
43
47
|
- lib/shattered_model/fuzzy_logic.rb
|
44
48
|
- lib/shattered_model/linear_interpolator.rb
|
45
49
|
- lib/shattered_pack/base.rb
|
46
50
|
- lib/shattered_pack/runner.rb
|
51
|
+
- lib/shattered_pack/keyboard_input/key_converter.rb
|
52
|
+
- lib/shattered_pack/keyboard_input/keyboard_input.rb
|
47
53
|
- lib/shattered_pack/pre_initialize/pre_initialize.rb
|
48
54
|
- lib/shattered_pack/timer/timed_event.rb
|
49
55
|
- lib/shattered_pack/timer/timer.rb
|
@@ -52,6 +58,7 @@ files:
|
|
52
58
|
- lib/shattered_view/extensions.rb
|
53
59
|
- lib/shattered_view/light.rb
|
54
60
|
- lib/shattered_view/node.rb
|
61
|
+
- lib/shattered_view/overlay.rb
|
55
62
|
- lib/shattered_view/resources.rb
|
56
63
|
- lib/shattered_view/rmaterial.rb
|
57
64
|
- lib/shattered_view/runner.rb
|
@@ -1,108 +0,0 @@
|
|
1
|
-
|
2
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
3
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
4
|
-
|
5
|
-
require 'keyboard_input/keyboard_input'
|
6
|
-
require 'actor/actor'
|
7
|
-
|
8
|
-
module ShatteredController #:nodoc:
|
9
|
-
|
10
|
-
# Controllers tie together the Model and View. They are the only objects that know
|
11
|
-
# about both the model and the view, and as such have the responsibility of events.
|
12
|
-
#
|
13
|
-
# By default, when an unknown method is invoked on a controller object, it is delegated
|
14
|
-
# to the model and the view. IE:
|
15
|
-
#
|
16
|
-
# class BulletController < ...
|
17
|
-
# def known_method
|
18
|
-
# puts "This will not be delegated to the " + model.inspect + " or the " + view.inspect
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# class BattleState < ...
|
23
|
-
# actor :bullet
|
24
|
-
# def initialize
|
25
|
-
# bullet.known_method # This is not delegated
|
26
|
-
# bullet.unknown_method # This is delegated (and will throw an exception if unknown among the view/model)
|
27
|
-
# end
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# When obtaining a result from a delegated method, the result will be the a response in the following order
|
31
|
-
# - Model (first)
|
32
|
-
# - View (last)
|
33
|
-
#
|
34
|
-
# They are sorted so that you get the most useful response first.
|
35
|
-
class Base < ShatteredPack::Base
|
36
|
-
attr_accessor :model, :view
|
37
|
-
|
38
|
-
before_init_call :disable_event
|
39
|
-
|
40
|
-
def quit
|
41
|
-
end
|
42
|
-
|
43
|
-
# Controller delegates all unknown methods to the view and model.
|
44
|
-
def method_missing(method_name, *args, &block)
|
45
|
-
return if disabled?
|
46
|
-
raise_no_method_error = true
|
47
|
-
result = nil
|
48
|
-
[view, model].each do |delegate|
|
49
|
-
if delegate.class.method_defined?(method_name)
|
50
|
-
result = delegate.send(method_name, *args, &block)
|
51
|
-
raise_no_method_error = false
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
raise NoMethodError, "Model, View, and Controller have no method defined named '#{method_name}'" if raise_no_method_error
|
56
|
-
return result
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
|
-
def update_timer(time_elapsed)#:nodoc:
|
61
|
-
return if @timer == :unloaded
|
62
|
-
[self, model, view].each do |base|
|
63
|
-
next if base.nil?
|
64
|
-
base.time_elapsed = time_elapsed
|
65
|
-
base.timer.update(time_elapsed)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# This is called to the State every frame by the main game loop. All update events are now
|
70
|
-
# run through Timers.
|
71
|
-
def update_timers(time_elapsed) #:nodoc:
|
72
|
-
update_timer(time_elapsed)
|
73
|
-
actors.each { |actor| actor.update_timers(time_elapsed) }
|
74
|
-
end
|
75
|
-
|
76
|
-
# Unloading a controller will completely unload an object from the scene.
|
77
|
-
def unload!
|
78
|
-
super
|
79
|
-
end
|
80
|
-
|
81
|
-
# An object is disabled when it has been unloaded.
|
82
|
-
def disabled?
|
83
|
-
super
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
|
88
|
-
def disable_event
|
89
|
-
when_unloaded do
|
90
|
-
@disabled = true
|
91
|
-
@timer=:unloaded
|
92
|
-
@model.send(:unload!) if @model
|
93
|
-
@model = nil
|
94
|
-
@view.send(:unload!) if @view
|
95
|
-
@view = nil
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
class Error < StandardError #:nodoc:
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
ShatteredController::Base.class_eval do
|
105
|
-
include ShatteredController::KeyboardInput
|
106
|
-
include ShatteredController::Actor
|
107
|
-
end
|
108
|
-
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module ShatteredController
|
2
|
-
# This is a wrapper around Ogre's input listener.
|
3
|
-
# It allows us to query the status of each device every frame.
|
4
|
-
class KeyConverter #:nodoc:
|
5
|
-
|
6
|
-
def initialize( ogre_input )
|
7
|
-
@ogre_input = ogre_input
|
8
|
-
end
|
9
|
-
def key_event?( type, key_symbol )
|
10
|
-
return @ogre_input.send(:"isKey#{type.to_s.capitalize}", self.class.convert(key_symbol))
|
11
|
-
end
|
12
|
-
def flush
|
13
|
-
@ogre_input.flush
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.back_conversions
|
17
|
-
@@back_conversions ||= conversions.invert
|
18
|
-
end
|
19
|
-
def self.conversions
|
20
|
-
begin
|
21
|
-
return @@conversions
|
22
|
-
rescue NameError
|
23
|
-
end
|
24
|
-
@@conversions = {}
|
25
|
-
ShatteredOgre.constants.each do |constant|
|
26
|
-
kc_evaled = eval("ShatteredOgre::#{constant}")
|
27
|
-
@@conversions[kc_evaled] = symbolize(constant[3..-1].downcase) if constant.to_s =~ /^KC_/
|
28
|
-
end
|
29
|
-
return @@conversions
|
30
|
-
end
|
31
|
-
def self.convert( kc_character )
|
32
|
-
return self.conversions[kc_character] if kc_character.is_a? Fixnum
|
33
|
-
return self.back_conversions[kc_character]
|
34
|
-
end
|
35
|
-
private
|
36
|
-
def self.symbolize( name )
|
37
|
-
exceptions = { 'pgdown' => :page_down,
|
38
|
-
'pgup' => :page_up }
|
39
|
-
return name.to_sym if exceptions[name] == nil
|
40
|
-
return exceptions[name]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|