metro 0.0.3 → 0.0.5

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.
@@ -0,0 +1,24 @@
1
+ class Gosu::Color
2
+
3
+ alias_method :gosu_initialize, :initialize
4
+
5
+ #
6
+ # Monkey-patching the initialize to allow for another Gosu::Color
7
+ # and Strings.
8
+ #
9
+ def initialize(*args)
10
+ if args.length == 1
11
+ value = args.first
12
+ if value.is_a? Gosu::Color
13
+ gosu_initialize value.alpha, value.red, value.green, value.blue
14
+ elsif value.is_a? String
15
+ gosu_initialize value.to_i(16)
16
+ else
17
+ gosu_initialize value
18
+ end
19
+ else
20
+ gosu_initialize *args
21
+ end
22
+ end
23
+
24
+ end
data/lib/metro.rb CHANGED
@@ -1,11 +1,15 @@
1
1
  require 'gosu'
2
+ require 'gosu_ext/color'
3
+
2
4
  require 'logger'
3
5
 
6
+
4
7
  require 'metro/version'
5
8
  require 'metro/window'
6
9
  require 'metro/game'
7
- require 'metro/model'
8
10
  require 'metro/scene'
11
+ require 'metro/models/model'
12
+ require 'metro/models/generic'
9
13
 
10
14
  def asset_path(name)
11
15
  File.join Dir.pwd, "assets", name
@@ -50,7 +54,6 @@ module Metro
50
54
  $LOAD_PATH.unshift(Dir.pwd) unless $LOAD_PATH.include?(Dir.pwd)
51
55
  Dir['models/*.rb'].each {|model| require model }
52
56
  Dir['scenes/*.rb'].each {|scene| require scene }
53
- Dir['drawers/*.rb'].each {|drawer| require drawer }
54
57
  end
55
58
 
56
59
  def load_game_configuration(filename)
@@ -62,6 +65,7 @@ module Metro
62
65
 
63
66
  def start_game
64
67
  window = Window.new Game.width, Game.height, Game.fullscreen?
68
+ window.caption = Game.name
65
69
  window.scene = Scenes.generate(Game.first_scene)
66
70
  window.show
67
71
  end
@@ -1,65 +1,94 @@
1
- class Animation
2
-
3
- attr_reader :current_step
4
-
5
- def initialize(options)
6
- @current_step = 0
7
-
8
- options.each do |key,value|
9
- send :instance_variable_set, "@#{key}".to_sym, value
10
- self.class.send :define_method, key do
11
- instance_variable_get("@#{key}")
1
+ module Metro
2
+
3
+ #
4
+ # Animation is the motion that gives a system it's life. An animation
5
+ # in this case is a really a mechanism that allows for an action to
6
+ # be repeated for a given interval of time.
7
+ #
8
+ class Animation
9
+
10
+ def initialize(options)
11
+ @current_step = 0
12
+
13
+ options.each do |key,value|
14
+ send :instance_variable_set, "@#{key}".to_sym, value
15
+ self.class.send :define_method, key do
16
+ instance_variable_get("@#{key}")
17
+ end
12
18
  end
19
+ after_initialize
13
20
  end
14
- after_initialize
15
- end
16
-
17
- def completed?
18
- current_step >= interval
19
- end
20
21
 
21
- def step!
22
- return if completed?
23
-
24
- execute_step
25
- next_step
22
+ #
23
+ # Sets the action that happens with each step of the animation.
24
+ #
25
+ def on_step(&block)
26
+ @step_block = block
27
+ end
26
28
 
27
- complete! if completed?
28
- end
29
+ #
30
+ # Sets the action that happens when the animation is completed.
31
+ #
32
+ def on_complete(&block)
33
+ @complete_block = block
34
+ end
29
35
 
30
- def next_step
31
- @current_step = current_step + step_interval
32
- end
36
+ #
37
+ # Perform a step of an animation, if it hasn't already been completed.
38
+ #
39
+ def update
40
+ return if completed?
33
41
 
34
- def step_interval
35
- 1
36
- end
42
+ execute_step
43
+ next_step
37
44
 
38
- def execute_block_in_context(block_name)
39
- if respond_to? block_name
40
- block_to_execute = send(block_name)
41
- context.instance_eval(&block_to_execute)
42
- else
43
- instance_variable_get("@#{block_name}").call
45
+ complete! if completed?
46
+ end
47
+
48
+ #
49
+ # @return the current step of the animation.
50
+ #
51
+ attr_reader :current_step
52
+
53
+ attr_reader :step_block, :complete_block
54
+
55
+ #
56
+ # Move to the next step in the animation.
57
+ #
58
+ def next_step
59
+ @current_step = current_step + step_interval
44
60
  end
45
- end
46
61
 
47
- def execute_step
48
- execute_block_in_context(:step_block)
49
- end
62
+ #
63
+ # @return the interval at which the animation take place.
64
+ #
65
+ def step_interval
66
+ 1
67
+ end
68
+
69
+ #
70
+ # @return true if the animation has completed all the actions, false
71
+ # if there are remaining actions.
72
+ #
73
+ def completed?
74
+ current_step >= interval
75
+ end
50
76
 
51
- def complete!
52
- execute_block_in_context(:completed)
53
- end
77
+ #
78
+ # Perform the action that happens with each step of the animation.
79
+ #
80
+ def execute_step
81
+ context.instance_eval(&@step_block) if step_block and context
82
+ end
54
83
 
55
- def step(&block)
56
- @step_block = block if block
57
- end
84
+ #
85
+ # Perform the action that happens when the animation is completed.
86
+ #
87
+ def complete!
88
+ context.instance_eval(&@complete_block) if complete_block and context
89
+ end
58
90
 
59
- def completed(&block)
60
- @completed = block if block
61
91
  end
62
-
63
92
  end
64
93
 
65
94
  require_relative 'implicit_animation'
@@ -1,28 +1,31 @@
1
- module Easing
2
- module Linear
3
- extend self
1
+ module Metro
2
+ module Easing
4
3
 
5
- def linear(moment,start,change,interval)
6
- change * moment / interval + start
7
- end
4
+ module Linear
5
+ extend self
6
+
7
+ def linear(moment,start,change,interval)
8
+ change * moment / interval + start
9
+ end
8
10
 
9
- def calculate(start,final,interval)
10
- change = final - start
11
- (1..interval).map { |time| linear(time,start,change,interval) }
11
+ def calculate(start,final,interval)
12
+ change = final - start
13
+ (1..interval).map { |time| linear(time.to_f,start,change,interval) }
14
+ end
12
15
  end
13
- end
14
16
 
15
- module EaseIn
16
- extend self
17
+ module EaseIn
18
+ extend self
17
19
 
18
- def ease_in_quad(moment,start,change,interval)
19
- change * (moment = moment / interval) * moment + start
20
- end
20
+ def ease_in_quad(moment,start,change,interval)
21
+ change * (moment = moment / interval) * moment + start
22
+ end
21
23
 
22
- def calculate(start,final,interval)
23
- change = final - start
24
- (1..interval).map { |time| ease_in_quad(time,start,change,interval) }
24
+ def calculate(start,final,interval)
25
+ change = final - start
26
+ (1..interval).map { |time| ease_in_quad(time.to_f,start,change,interval) }
27
+ end
25
28
  end
29
+
26
30
  end
27
31
  end
28
-
@@ -1,43 +1,102 @@
1
1
  require_relative 'easing'
2
2
 
3
- class ImplicitAnimation < Animation
3
+ module Metro
4
4
 
5
- attr_reader :attributes
6
- attr_reader :deltas
5
+ #
6
+ # An Implicit Animation is an animation without all the work.
7
+ # This little animation will take care of figuring out moving an
8
+ # actor from one position to another, the rotation, the alpha,
9
+ # etc.
10
+ #
11
+ # @example Creating an explicit animation that moves a player
12
+ #
13
+ # animation = ImplicitAnimation.new actor: player,
14
+ # to: { x: final_x, y: final_y },
15
+ # interval: 80,
16
+ # easing: :ease_in,
17
+ # context: scene
18
+ #
19
+ # animation.on_complete do
20
+ # transition_to :main
21
+ # end
22
+ #
23
+ # Here an animation is created that will move the player to the
24
+ # position (final_x,final_y), specified in the :to hash that is
25
+ # provided, over the interval of 80 steps. Additionally the movement
26
+ # is done with an easing in.
27
+ #
28
+ # @note The actor object must respond to setter methods that match
29
+ # the specified attributes (e.g. x, y).
30
+ #
31
+ # The context provided is the context that the 'on_complete' block
32
+ # is executed. In this case, upon completition, transition the scene
33
+ # from the current one to the main scene.
34
+ #
35
+ class ImplicitAnimation < Animation
7
36
 
8
- def delta_for_step(attribute)
9
- deltas[attribute].at(current_step)
10
- end
37
+ #
38
+ # @return the array of attributes that are being animated.
39
+ #
40
+ attr_reader :attributes
11
41
 
12
- def stepping(stepping)
13
- @steppings ||= begin
14
- hash = Hash.new(Easing::Linear)
15
- hash.merge! linear: Easing::Linear,
16
- ease_in: Easing::EaseIn
17
- end
18
- @steppings[stepping]
19
- end
42
+ #
43
+ # @return a Hash that contains all the animation step deltas
44
+ # for each attribute.
45
+ #
46
+ attr_reader :deltas
20
47
 
21
- def easing
22
- @easing || :linear
23
- end
48
+ #
49
+ # @return the type of easing that the implicit animation should employ.
50
+ # By default it uses linear but can be overridden when the easing is
51
+ # configured.
52
+ #
53
+ attr_reader :easing
24
54
 
25
- def after_initialize
26
- @deltas = {}
55
+ #
56
+ # Additional initializion is required to calculate the attributes
57
+ # that are going to be animated and to determine each of their deltas.
58
+ #
59
+ def after_initialize
60
+ @deltas = {}
27
61
 
28
- @attributes = to.map { |attribute,final| attribute }
62
+ @attributes = to.map { |attribute,final| attribute }
29
63
 
30
- to.each do |attribute,final|
31
- start = actor.send(attribute)
32
- deltas[attribute] = stepping(easing).calculate(start,final,interval)
64
+ to.each do |attribute,final|
65
+ start = actor.send(attribute)
66
+ deltas[attribute] = stepping(easing).calculate(start.to_f,final.to_f,interval.to_f)
67
+ end
33
68
  end
34
69
 
35
- step do
70
+ #
71
+ # @return the correct easing based on the specified name. When the name
72
+ # provided does not match anything then default to linear easing.
73
+ #
74
+ def stepping(stepping)
75
+ @steppings ||= begin
76
+ hash = Hash.new(Easing::Linear)
77
+ hash.merge! linear: Easing::Linear,
78
+ ease_in: Easing::EaseIn
79
+ end
80
+ @steppings[stepping]
81
+ end
82
+
83
+ #
84
+ # The ImplicitAnimation overrides the {Animation#execute_step} and
85
+ # updates the attributes of the actor based upon the value of the
86
+ # current animation step.
87
+ #
88
+ def execute_step
36
89
  attributes.each do |attribute|
37
90
  actor.send "#{attribute}=", delta_for_step(attribute)
38
91
  end
39
92
  end
40
93
 
41
- end
94
+ #
95
+ # @return the delta for the attribute for the given step
96
+ #
97
+ def delta_for_step(attribute)
98
+ deltas[attribute].at(current_step)
99
+ end
42
100
 
101
+ end
43
102
  end
data/lib/metro/game.rb CHANGED
@@ -33,11 +33,15 @@ module Metro
33
33
  def fullscreen?
34
34
  !!config.fullscreen
35
35
  end
36
-
36
+
37
37
  def debug?
38
38
  !!config.debug
39
39
  end
40
40
 
41
+ def name
42
+ config.name
43
+ end
44
+
41
45
  # TODO: ZOrder related constants that belong to Starry Knight
42
46
  Background, Stars, Players, UI = *0..3
43
47
 
@@ -31,6 +31,10 @@ module Metro
31
31
  def debug(set_debug = nil)
32
32
  set_debug.nil? ? @debug : @debug = set_debug
33
33
  end
34
+
35
+ def name(set_name = nil)
36
+ set_name.nil? ? @name : @name = set_name
37
+ end
34
38
 
35
39
  end
36
40
  end
@@ -0,0 +1,12 @@
1
+ module Metro
2
+ module Models
3
+
4
+ #
5
+ # Generic model is used when no model is cannot not be found
6
+ # when mapping the view content
7
+ #
8
+ class Generic < Model
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ module Metro
2
+ module Models
3
+
4
+ #
5
+ # Draws an Image
6
+ #
7
+ # @example Using the Image in a view file
8
+ # model: "metro::models::image"
9
+ #
10
+ class Image < Model
11
+
12
+ attr_accessor :angle, :center_x, :center_y, :x_factor, :y_factor
13
+
14
+ def image
15
+ @image ||= Gosu::Image.new(window,asset_path(path))
16
+ end
17
+
18
+ def draw
19
+ image.draw_rot x, y, z_order,
20
+ angle.to_f,
21
+ center_x, center_y,
22
+ x_factor, y_factor,
23
+ color
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end