metro 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/changelog.md +8 -1
  2. data/lib/core_ext/class.rb +14 -0
  3. data/lib/metro.rb +1 -0
  4. data/lib/metro/events/event_data.rb +3 -4
  5. data/lib/metro/events/event_state_manager.rb +63 -0
  6. data/lib/metro/events/events.rb +3 -0
  7. data/lib/metro/events/hit_list.rb +4 -5
  8. data/lib/metro/events/unknown_sender.rb +1 -1
  9. data/lib/metro/models/model.rb +14 -25
  10. data/lib/metro/models/model_factory.rb +1 -1
  11. data/lib/metro/models/models.rb +62 -0
  12. data/lib/metro/models/properties/position_property.rb +1 -1
  13. data/lib/metro/models/ui/animated_sprite.rb +85 -0
  14. data/lib/metro/models/ui/border.rb +44 -18
  15. data/lib/metro/models/ui/fps.rb +1 -1
  16. data/lib/metro/models/ui/generic.rb +24 -3
  17. data/lib/metro/models/ui/model_label.rb +1 -1
  18. data/lib/metro/models/ui/model_labeler.rb +2 -2
  19. data/lib/metro/models/ui/rectangle.rb +1 -1
  20. data/lib/metro/models/ui/sprite.rb +79 -0
  21. data/lib/metro/models/ui/ui.rb +12 -0
  22. data/lib/metro/scene.rb +13 -61
  23. data/lib/metro/scenes.rb +11 -13
  24. data/lib/metro/transitions/edit_transition_scene.rb +2 -2
  25. data/lib/metro/units/calculation_validations.rb +74 -0
  26. data/lib/metro/units/dimensions.rb +11 -19
  27. data/lib/metro/units/point.rb +6 -22
  28. data/lib/metro/units/rectangle_bounds.rb +10 -6
  29. data/lib/metro/units/scale.rb +7 -0
  30. data/lib/metro/units/units.rb +1 -0
  31. data/lib/metro/version.rb +1 -1
  32. data/lib/metro/window.rb +7 -3
  33. data/lib/setup_handlers/reload_game_on_game_file_changes.rb +6 -6
  34. data/lib/templates/game/models/hero.rb +35 -6
  35. data/lib/templates/model.rb.tt +1 -1
  36. data/spec/core_ext/string_spec.rb +0 -20
  37. data/spec/metro/units/point_spec.rb +132 -0
  38. data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
  39. data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
  40. metadata +21 -9
@@ -5,6 +5,7 @@ module Metro
5
5
  # Represents and object that contains the x, y, and z position.
6
6
  #
7
7
  class Point < Struct.new(:x,:y,:z)
8
+ include CalculationValidations
8
9
 
9
10
  #
10
11
  # Generate a point at 0,0,0.
@@ -18,7 +19,7 @@ module Metro
18
19
  # all inputs to floating point and assumes that the z-value is
19
20
  # zero (as this is a 2D universe).
20
21
  #
21
- def self.at(x,y,z=0.0)
22
+ def self.at(x=0.0,y=0.0,z=0.0)
22
23
  new x.to_f, y.to_f, z.to_f
23
24
  end
24
25
 
@@ -28,7 +29,7 @@ module Metro
28
29
  # either "x,y" or "x,y,z".
29
30
  #
30
31
  def self.parse(string)
31
- at *string.split(",",3).map(&:to_f)
32
+ at *string.to_s.split(",",3).map(&:to_f)
32
33
  end
33
34
 
34
35
  # As this is a 2D world, the Z is often refered to as a the z-ordering
@@ -39,27 +40,10 @@ module Metro
39
40
  "#{x},#{y},#{z}"
40
41
  end
41
42
 
42
- #
43
- # Add this point to another another point-like structure. A point like structure
44
- # is anything has the methods x, y, and z.
45
- #
46
- # @return a new point which is the sum of the point and the provided value.
47
- #
48
- def +(value)
49
- raise "Unable to add point to #{value} #{value.class}" if [ :x, :y, :z ].find { |method| ! value.respond_to?(method) }
50
- self.class.at (x + value.x.to_f), (y + value.y.to_f), (z + value.z.to_f)
51
- end
43
+ private
52
44
 
53
- #
54
- # Subtract the point-like structure from this point. A point like structure
55
- # is anything has the methods x, y, and z.
56
- #
57
- # @return a new point which is the difference of the point and the
58
- # provided value.
59
- #
60
- def -(value)
61
- raise "Unable to subtract from this point with #{value} #{value.class}" if [ :x, :y, :z ].find { |method| ! value.respond_to?(method) }
62
- self.class.at (x - value.x.to_f), (y - value.y.to_f), (z - value.z.to_f)
45
+ def calculation_requirements
46
+ [ :x, :y, :z ]
63
47
  end
64
48
 
65
49
  end
@@ -5,9 +5,7 @@ module Metro
5
5
  # An object that represents a rectanglar bounds.
6
6
  #
7
7
  class RectangleBounds
8
-
9
- # Allow the ability to refer to the min, max values with their
10
- # other alternate names.
8
+ include CalculationValidations
11
9
 
12
10
  attr_accessor :left, :right, :top, :bottom
13
11
 
@@ -46,15 +44,15 @@ module Metro
46
44
  end
47
45
 
48
46
  def ==(value)
49
- return if [ :left, :right, :top, :bottom ].find { |method| ! value.respond_to?(method) }
47
+ check_calculation_requirements(value)
50
48
  left == value.left and right == value.right and top == value.top and bottom == value.bottom
51
49
  end
52
50
 
53
51
  #
54
52
  # Does this bounds contain the following point?
55
53
  #
56
- def contains?(x,y)
57
- x > left and x < right and y > top and y < bottom
54
+ def contains?(point)
55
+ point.x > left and point.x < right and point.y > top and point.y < bottom
58
56
  end
59
57
 
60
58
  #
@@ -68,6 +66,12 @@ module Metro
68
66
  "(#{left},#{top}) to (#{right},#{bottom})"
69
67
  end
70
68
 
69
+ private
70
+
71
+ def calculation_requirements
72
+ [ :left, :right, :top, :bottom ]
73
+ end
74
+
71
75
  end
72
76
 
73
77
  end
@@ -5,6 +5,7 @@ module Metro
5
5
  # Represents an object that contains the x scale factor, and y scale factor.
6
6
  #
7
7
  class Scale < Struct.new(:x_factor,:y_factor)
8
+ include CalculationValidations
8
9
 
9
10
  #
10
11
  # Create a scale that is 1:1.
@@ -34,6 +35,12 @@ module Metro
34
35
  "#{x_factor},#{y_factor}"
35
36
  end
36
37
 
38
+ private
39
+
40
+ def calculation_requirements
41
+ [ :x_factor, :y_factor ]
42
+ end
43
+
37
44
  end
38
45
  end
39
46
  end
@@ -1,3 +1,4 @@
1
+ require_relative 'calculation_validations'
1
2
  require_relative 'point'
2
3
  require_relative 'dimensions'
3
4
  require_relative 'scale'
@@ -1,5 +1,5 @@
1
1
  module Metro
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  WEBSITE = "https://github.com/burtlo/metro"
4
4
  CONTACT_EMAILS = ["dev@rubymetro.com"]
5
5
 
@@ -13,6 +13,10 @@ module Metro
13
13
  #
14
14
  attr_accessor :scene
15
15
 
16
+ def state
17
+ scene.state
18
+ end
19
+
16
20
  #
17
21
  # @param [Fixnum] width the width of the game window
18
22
  # @param [Fixnum] height the height of the game window
@@ -32,7 +36,7 @@ module Metro
32
36
  # This is called every update interval while the window is being shown.
33
37
  #
34
38
  def update
35
- scene.fire_events_for_held_buttons
39
+ state.fire_events_for_held_buttons
36
40
  scene.base_update
37
41
  end
38
42
 
@@ -49,7 +53,7 @@ module Metro
49
53
  # has focus.
50
54
  #
51
55
  def button_up(id)
52
- scene.button_up(id)
56
+ state.fire_button_up(id)
53
57
  end
54
58
 
55
59
  #
@@ -57,7 +61,7 @@ module Metro
57
61
  # has focus.
58
62
  #
59
63
  def button_down(id)
60
- scene.button_down(id)
64
+ state.fire_button_down(id)
61
65
  end
62
66
 
63
67
  #
@@ -8,6 +8,10 @@ module Metro
8
8
  #
9
9
  class ReloadGameOnGameFileChanges
10
10
 
11
+ def watched_filepaths
12
+ source_filepaths + view_filepaths + asset_filepaths
13
+ end
14
+
11
15
  #
12
16
  # @NOTE this is duplication of the paths is also defined in LoadGameFiles.
13
17
  # @see Metro::SetupHandlers::LoadGameFiles
@@ -24,21 +28,17 @@ module Metro
24
28
  [ 'assets' ]
25
29
  end
26
30
 
27
- def all_filepaths
28
- source_filepaths + view_filepaths + asset_filepaths
29
- end
30
-
31
31
  #
32
32
  # @param [Metro::Parameters::Options] options the options that the game
33
33
  # was provided when it was launched.
34
34
  #
35
35
  def setup(options)
36
- start_watcher if Game.debug?
36
+ start_watcher if Game.debug? and not options.packaged?
37
37
  end
38
38
 
39
39
  def start_watcher
40
40
  Thread.abort_on_exception = true
41
- Thread.new { watch_filepaths(all_filepaths) }
41
+ Thread.new { watch_filepaths(watched_filepaths) }
42
42
  end
43
43
 
44
44
  #
@@ -1,9 +1,23 @@
1
- class Hero < Metro::Model
1
+ class Hero < Metro::UI::Sprite
2
+
3
+ # A Metro::UI::Sprite predefines a number of commmon properties:
4
+ #
5
+ # * position
6
+ # * dimensions
7
+ # * color
8
+ # * angle
9
+ # * scale
10
+ #
11
+ # These properties add getter and setter methods of the following:
12
+ #
13
+ # * position, x, y, z and z_order (both z and z_order are the same)
14
+ # * dimensions, width, and height
15
+ # * color, red, green, blue, alpha
16
+ # * angle
17
+ # * scale, x_factor, y_factor
2
18
 
3
19
  property :image, path: "hero.png"
4
20
 
5
- property :position
6
- property :angle
7
21
  property :move_amount, default: 1.5
8
22
  property :turn_amount, default: 90.0
9
23
 
@@ -27,7 +41,22 @@ class Hero < Metro::Model
27
41
  self.angle += turn_amount
28
42
  end
29
43
 
30
- def draw
31
- image.draw_rot(x,y,z_order,angle.to_f)
32
- end
44
+ # By default a Metro::UI::Sprite defines a #draw method which will
45
+ # draw the associated image with the position, rotation, and scale.
46
+ #
47
+ # If you would like to maintain the current draw functionality but augment
48
+ # it, you can define a draw method which calls to super.
49
+ #
50
+ # def draw
51
+ # super
52
+ # # custom drawing alongside the image
53
+ # end
54
+ #
55
+ # You may find it necessary to replace the existing draw functionality.
56
+ # Here you could define your own draw that overrides the original.
57
+ #
58
+ # def draw
59
+ # # custom drawing without the original image draw
60
+ # end
61
+
33
62
  end
@@ -1,4 +1,4 @@
1
- class <%= model_name %> < GameModel
1
+ class <%= model_name %> < Metro::Model
2
2
 
3
3
  #
4
4
  # Properties
@@ -30,24 +30,4 @@ describe String do
30
30
  its(:underscore) { should eq expected_value }
31
31
  end
32
32
  end
33
-
34
- describe "#classify" do
35
- context "when given a regular string" do
36
- subject { "string" }
37
- let(:expected_value) { "String" }
38
- its(:classify) { should eq expected_value }
39
- end
40
-
41
- context "when given a underscored string" do
42
- subject { "camel_cased" }
43
- let(:expected_value) { "CamelCased" }
44
- its(:classify) { should eq expected_value }
45
- end
46
-
47
- context "when given a partial camel_CasedString" do
48
- subject { "camel_CasedString" }
49
- let(:expected_value) { "CamelCasedString" }
50
- its(:classify) { should eq expected_value }
51
- end
52
- end
53
33
  end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metro::Units::Point do
4
+
5
+ subject { described_class.new x, y, z }
6
+
7
+ let(:x) { 12 }
8
+ let(:y) { 24 }
9
+ let(:z) { 36 }
10
+
11
+ its(:x) { should eq x }
12
+ its(:y) { should eq y }
13
+ its(:z) { should eq z }
14
+ its(:z_order) { should eq z }
15
+
16
+ let(:expected_string) { "#{x},#{y},#{z}" }
17
+ its(:to_s) { should eq expected_string }
18
+
19
+ describe "#+" do
20
+ context "when adding it to another point" do
21
+ let(:point) { described_class.at 1, 2, 3 }
22
+ let(:summed_point) { described_class.at 13, 26, 39 }
23
+
24
+ it "should be a sum of the two points" do
25
+ sum = subject + point
26
+ sum.should eq summed_point
27
+ end
28
+ end
29
+
30
+ context "when adding it to another point-like object" do
31
+ let(:point) { stub('Point Like',x: 1, y: 2, z: 3) }
32
+ let(:summed_point) { described_class.at 13, 26, 39 }
33
+
34
+ it "should be a sum of the two points" do
35
+ sum = subject + point
36
+ sum.should eq summed_point
37
+ end
38
+ end
39
+
40
+ context "when adding it to something not like a point" do
41
+ let(:point) { stub('Not Point Like') }
42
+ let(:summed_point) { described_class.at 13, 26, 39 }
43
+
44
+ it "should raise an error" do
45
+ expect { subject + point }.to raise_error
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#-" do
51
+ context "when adding it to another point" do
52
+ let(:point) { described_class.at 1, 2, 3 }
53
+ let(:summed_point) { described_class.at 11, 22, 33 }
54
+
55
+ it "should be a sum of the two points" do
56
+ sum = subject - point
57
+ sum.should eq summed_point
58
+ end
59
+ end
60
+
61
+ context "when adding it to another point-like object" do
62
+ let(:point) { stub('Point Like',x: 1, y: 2, z: 3) }
63
+ let(:summed_point) { described_class.at 11, 22, 33 }
64
+
65
+ it "should be a sum of the two points" do
66
+ sum = subject - point
67
+ sum.should eq summed_point
68
+ end
69
+ end
70
+
71
+ context "when adding it to something not like a point" do
72
+ let(:point) { stub('Not Point Like') }
73
+ let(:summed_point) { described_class.at 13, 26, 39 }
74
+
75
+ it "should raise an error" do
76
+ expect { subject - point }.to raise_error
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "Class Methods" do
82
+
83
+ subject { described_class }
84
+
85
+ describe "#zero" do
86
+ let(:expected_point) { Point.new 0,0,0 }
87
+
88
+ it "should create a zero point" do
89
+ subject.zero.should == expected_point
90
+ end
91
+ end
92
+
93
+ describe "#at" do
94
+ let(:expected_point) { Point.new 1,2,3 }
95
+
96
+ it "should be equal to a new created point" do
97
+ subject.at(1,2,3).should == expected_point
98
+ end
99
+ end
100
+
101
+ describe "#parse" do
102
+ context "when the input string is defined with 'x,y,z'" do
103
+ let(:input) { "1,2,3" }
104
+ let(:expected_value) { Point.at(1,2,3) }
105
+
106
+ it "should create the expected point" do
107
+ subject.parse(input).should eq expected_value
108
+ end
109
+ end
110
+
111
+ context "when the input string is defined with 'x,y'" do
112
+ let(:input) { "1,2" }
113
+ let(:expected_value) { Point.at(1,2,0) }
114
+
115
+ it "should create the expected point" do
116
+ subject.parse(input).should eq expected_value
117
+ end
118
+ end
119
+
120
+ context "when the input is a nil" do
121
+ let(:input) { nil }
122
+ let(:expected_value) { Point.at(0,0,0) }
123
+
124
+ it "should create the expected point" do
125
+ subject.parse(input).should eq expected_value
126
+ end
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Metro::SetupHandlers::ExitIfDryRun do
4
+
5
+ describe "#setup" do
6
+ context "when the options specify that this is a dry run" do
7
+
8
+ let(:options) { stub('Options', dry_run?: true) }
9
+
10
+ it "should exit the game" do
11
+ subject.should_receive(:exit)
12
+ subject.setup(options)
13
+ end
14
+ end
15
+
16
+ context "when the options DO NOT specify that this is a dry run" do
17
+
18
+ let(:options) { stub('Options', dry_run?: false) }
19
+
20
+ it "should not exit the game" do
21
+ subject.should_not_receive(:exit)
22
+ subject.setup(options)
23
+ end
24
+ end
25
+ end
26
+
27
+ end