shattered_pack 0.3.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/lib/mock_objects/shattered_ogre/input.rb +6 -0
  2. data/lib/mock_objects/shattered_ogre/light.rb +4 -0
  3. data/lib/mock_objects/shattered_ogre/mesh.rb +17 -0
  4. data/lib/mock_objects/shattered_ogre/node.rb +17 -0
  5. data/lib/mock_objects/shattered_ogre/renderer.rb +11 -0
  6. data/lib/mock_objects/shattered_ogre/resource_handler.rb +9 -0
  7. data/lib/mock_objects/shattered_ogre/scene.rb +28 -0
  8. data/lib/mock_objects.rb +5 -0
  9. data/lib/shattered_controller/actor/actor.rb +14 -53
  10. data/lib/shattered_controller/runner.rb +10 -4
  11. data/lib/shattered_controller/state.rb +29 -4
  12. data/lib/shattered_controller.rb +3 -2
  13. data/lib/shattered_model/base.rb +81 -0
  14. data/lib/shattered_model.rb +2 -1
  15. data/lib/shattered_pack/base.rb +5 -3
  16. data/lib/shattered_pack/keyboard_input/key_converter.rb +51 -0
  17. data/lib/{shattered_controller → shattered_pack}/keyboard_input/keyboard_input.rb +6 -2
  18. data/lib/shattered_pack/pre_initialize/pre_initialize.rb +7 -5
  19. data/lib/shattered_pack/timer/timed_event.rb +36 -8
  20. data/lib/shattered_pack/timer/timer.rb +6 -11
  21. data/lib/shattered_pack.rb +2 -1
  22. data/lib/shattered_view/base.rb +23 -11
  23. data/lib/shattered_view/light.rb +5 -4
  24. data/lib/shattered_view/mesh/mesh.rb +22 -5
  25. data/lib/shattered_view/node.rb +0 -8
  26. data/lib/shattered_view/overlay.rb +20 -0
  27. data/lib/shattered_view/rmaterial.rb +2 -2
  28. data/lib/shattered_view/runner.rb +6 -6
  29. data/lib/shattered_view/vector.rb +18 -2
  30. data/lib/shattered_view.rb +3 -2
  31. metadata +13 -6
  32. data/lib/shattered_controller/base.rb +0 -108
  33. data/lib/shattered_controller/keyboard_input/key_converter.rb +0 -43
  34. data/lib/shattered_controller/mock_camera.rb +0 -9
@@ -0,0 +1,6 @@
1
+ module ShatteredOgre
2
+ class Input
3
+ def initialize
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module ShatteredOgre
2
+ class Light
3
+ end
4
+ end
@@ -0,0 +1,17 @@
1
+ module ShatteredOgre # :nodoc:all
2
+ class Mesh
3
+ def initialize(file_name)
4
+ end
5
+ def getPosition
6
+ v(0,0,0)
7
+ end
8
+ def setPosition(x)
9
+ end
10
+ def getNumberOfAnimations
11
+ 0
12
+ end
13
+ def setMaterial(material)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module ShatteredOgre #:nodoc:all
2
+ class Node
3
+ def attachTo(object)
4
+ end
5
+ def createChildNode()
6
+ end
7
+ def setPosition(v)
8
+ end
9
+ def scale(amount)
10
+ end
11
+ def setVisible(vis)
12
+ end
13
+ def rotate(axis, amount)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module ShatteredOgre
2
+ class Renderer
3
+ def initialize
4
+ end
5
+ def failed
6
+ false
7
+ end
8
+ def nextFrame
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module ShatteredOgre
2
+ class ResourceHandler
3
+ def self.getSingleton
4
+ @@resource_handler ||= ResourceHandler.new
5
+ end
6
+ def addCustomMaterial(name, material)
7
+ end
8
+ end
9
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ path = File.dirname(__FILE__) + "/mock_objects/shattered_ogre"
2
+ Dir.foreach(path) do |mock_object|
3
+ path_to_mock = "#{path}/#{mock_object}"
4
+ require path_to_mock if mock_object.ends_with? ".rb"
5
+ end
@@ -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
- # This returns all of the actors created by this controller.
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=nil, options={})
56
- raise Error, "actor needs a name" if name.nil?
57
- actor = Actor.new(name,load_actor_classes(name))
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
- call_object_function_for_each_key( name.to_sym, options )
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] = ShatteredController::KeyConverter.new(@@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] = MockCamera.new
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", { :"sky" => [type, options[:material]] })
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 < ShatteredController::Base
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
+
@@ -1,3 +1,4 @@
1
- %w(runner base state mock_camera).each do |dependency|
2
- require "shattered_controller/#{dependency}"
1
+ %w(runner state).each do |dependency|
2
+ dependency = "shattered_controller/#{dependency}"
3
+ require dependency
3
4
  end
@@ -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
+
@@ -1,3 +1,4 @@
1
1
  %w(base fuzzy_logic linear_interpolator).each do |dependency|
2
- require "shattered_model/#{dependency}"
2
+ dependency = "shattered_model/#{dependency}"
3
+ require dependency
3
4
  end
@@ -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(*options) #:nodoc
16
+ def self.new(options={}) #:nodoc
16
17
  new_base = allocate
17
- new_base.pre_initialize
18
- new_base.send(:initialize, *options)
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 ShatteredController
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? Symbol #|| (params.length == 1 && params[0].is_a?(Symbol)) this will allow substitution in before_init_call. This may not be intended behavior.
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
- @events_remaining << TimedEvent.new(seconds, &block)
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
- @events_remaining << ContinuousTimedEvent.new(seconds,&block)
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(:timer_in, time, action) unless options[:in].nil?
39
- before_init_call(:timer_every, time, action) unless options[:every].nil?
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 timer_in(time, action)
48
- timer.in(time) do |time_elapsed|
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 == :"wrong number of arguments (0 for 1)"
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
@@ -1,7 +1,8 @@
1
1
  $: << File.expand_path(File.dirname(__FILE__))
2
2
 
3
3
  %w( base runner ).each do |component|
4
- require "shattered_pack/#{component}"
4
+ dependency = "shattered_pack/#{component}"
5
+ require dependency
5
6
  end
6
7
 
7
8
  require 'shattered_support'
@@ -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
- # :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
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
- # :direction: the direction light emanates from
57
- # : other : same as point light above.
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
- attr_reader :meshes
82
- attr_accessor :model
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
@@ -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.to_v)
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.to_v)
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
- end
72
-
73
- def meshes
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(:"#{mesh.name}.#{name}", options)
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
@@ -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 = :"@#{ name }"
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/views", "/media")
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? Vector
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
@@ -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
- require "shattered_view/#{dependency}"
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.3.3
7
- date: 2006-07-18 00:00:00 -06:00
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/shattered_controller/base.rb
36
- - lib/shattered_controller/mock_camera.rb
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
@@ -1,9 +0,0 @@
1
-
2
- module ShatteredController
3
- class MockCamera #:nodoc:
4
- attr_reader :position
5
- def position=(x,y,z)
6
- @position=[x,y,z]
7
- end
8
- end
9
- end