ruby_armor 0.0.2alpha

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.
data/bin/ruby_armor ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "ruby_armor"
data/bin/ruby_armour ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "ruby_armor"
@@ -0,0 +1,71 @@
1
+ ---
2
+ :constants:
3
+ :text: [240, 255, 240]
4
+
5
+ :dark_background: [0, 30, 0]
6
+ :light_background: [50, 120, 50]
7
+ :hover_background: [120, 200, 120]
8
+
9
+ :dark_border: [0, 30, 0]
10
+ :light_border: [25, 60, 25]
11
+
12
+ :handle: [80, 180, 80]
13
+
14
+ :elements:
15
+ :Element:
16
+ :font_name: MONACO.TTF
17
+ :font_height: 20
18
+ :color: ?text
19
+ :background_color: ?none
20
+ :border_color: ?light_background
21
+
22
+ :Button:
23
+ :disabled:
24
+ :background_color: ?dark_background
25
+ :border_color: ?dark_border
26
+ :hover:
27
+ :background_color: ?hover_background
28
+
29
+ :Packer:
30
+ :spacing_h: 8
31
+ :spacing_v: 8
32
+ :padding_left: 16
33
+ :padding_right: 16
34
+ :padding_top: 12
35
+ :padding_bottom: 18
36
+
37
+ :Button:
38
+ :border_thickness: 2
39
+ :padding_left: 12
40
+ :padding_right: 12
41
+ :padding_top: 4
42
+ :padding_bottom: 4
43
+ :background_color: ?light_background
44
+
45
+ :ComboBox:
46
+ :border_thickness: 0
47
+
48
+ :MenuPane::Item:
49
+ :padding_top: 0.4
50
+ :padding_bottom: 0.4
51
+
52
+ :ToolTip:
53
+ :font_height: 16
54
+ :padding_top: 4
55
+ :padding_bottom: 4
56
+ :background_color: ?dark_background
57
+
58
+ :TextArea:
59
+ :color: ?text
60
+ :background_color: ?dark_background
61
+ :font_height: 16
62
+
63
+ :ScrollBar: # < Composite
64
+ :rail_width: 14
65
+ :rail_color: ?light_background
66
+ :handle_color: ?handle
67
+
68
+ :ScrollWindow: # < Composite
69
+ :scroll_bar_thickness: 12
70
+ :border_color: ?light_border
71
+
@@ -0,0 +1,22 @@
1
+ module RubyArmor
2
+ class FloatingText < GameObject
3
+ FONT_SIZE = 30
4
+
5
+ def initialize(text, options = {})
6
+ super(options)
7
+
8
+ @final_y = y - 60
9
+ @text = text
10
+ @font = Font["MONACO.TTF", FONT_SIZE]
11
+ end
12
+
13
+ def update
14
+ self.y -= 1 # TODO: scale this with FPS.
15
+ destroy if y < @final_y
16
+ end
17
+
18
+ def draw
19
+ @font.draw_rel @text, x, y, zorder, 0.5, 0.5, 1, 1, color
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ module RubyWarrior
2
+ module Abilities
3
+ class Rest < Base
4
+ alias_method :original_perform, :perform
5
+ def perform
6
+ original = @unit.health
7
+ original_perform
8
+ $window.current_game_state.unit_health_changed(@unit, @unit.health - original) if @unit.health > original
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module RubyWarrior
2
+ class Position
3
+ attr_reader :x, :y
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ module RubyWarrior
2
+ class UI
3
+ class << self
4
+ attr_accessor :proxy
5
+
6
+ def puts(msg)
7
+ print msg + "\n"
8
+ end
9
+
10
+ def puts_with_delay(msg)
11
+ puts msg
12
+ end
13
+
14
+ def print(msg)
15
+ proxy.print msg
16
+ end
17
+
18
+ def gets
19
+ ""
20
+ end
21
+
22
+ def request(msg)
23
+ print msg
24
+ true
25
+ end
26
+
27
+ def ask(msg)
28
+ print msg
29
+ true
30
+ end
31
+
32
+ def choose(item, options)
33
+ response = options.first
34
+ if response.kind_of? Array
35
+ response.first
36
+ else
37
+ response
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ end
@@ -0,0 +1,11 @@
1
+ module RubyWarrior
2
+ module Units
3
+ class Base
4
+ alias_method :original_take_damage, :take_damage
5
+ def take_damage(amount)
6
+ $window.current_game_state.unit_health_changed self, -amount
7
+ original_take_damage(amount)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module RubyArmor
2
+ class SpriteSheet
3
+ extend Forwardable
4
+
5
+ def_delegators :@sprites, :map, :each
6
+
7
+ class << self
8
+ def [](file, width, height, tiles_wide = 0)
9
+ @cached_sheets ||= Hash.new do |h, k|
10
+ h[k] = new(*k)
11
+ end
12
+ @cached_sheets[[file, width, height, tiles_wide]]
13
+ end
14
+ end
15
+
16
+ def initialize(file, width, height, tiles_wide = 0)
17
+ @sprites = Image.load_tiles($window, File.expand_path(file, Image.autoload_dirs[0]), width, height, false)
18
+ @tiles_wide = tiles_wide
19
+ end
20
+
21
+ def [](x, y = 0)
22
+ @sprites[y * @tiles_wide + x]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,272 @@
1
+ module RubyArmor
2
+ class Play < Fidgit::GuiState
3
+ FLOOR_COLOR = Color.rgba(255, 255, 255, 125)
4
+
5
+ trait :timer
6
+
7
+ def setup
8
+ super
9
+
10
+ RubyWarrior::UI.proxy = self
11
+
12
+ @tiles = SpriteSheet.new "tiles.png", 8, 8, 8
13
+ @sprites = SpriteSheet.new "characters.png", 8, 8, 4
14
+ @max_turns = 75 # Just to recognise a stalemate ;)
15
+
16
+ vertical spacing: 0, padding: 10 do
17
+ horizontal padding: 0, height: $window.height * 0.5, width: 780 do
18
+ vertical padding: 0, height: $window.height * 0.5, align_h: :fill
19
+ vertical padding: 0, height: $window.height * 0.5, width: 100 do
20
+ @tower_label = label ""
21
+ @level_label = label "Level:"
22
+ @turn_label = label "Turn:"
23
+ @health_label = label "Health:"
24
+
25
+ button_options = { :width => 70 }
26
+ @start_button = button "Start", button_options do
27
+ start_level
28
+ end
29
+
30
+ @reset_button = button "Reset", button_options do
31
+ prepare_level
32
+ end
33
+
34
+ @hint_button = button "Hint", button_options do
35
+ message level.tip
36
+ end
37
+
38
+ @continue_button = button "Continue", button_options do
39
+ @game.prepare_next_level
40
+ prepare_level
41
+ end
42
+ end
43
+ end
44
+
45
+ horizontal padding: 0, spacing: 10 do
46
+ vertical padding: 0, width: 380, spacing: 10, height: $window.height * 0.45 do
47
+ @readme_window = scroll_window width: 380, height: $window.height * 0.23 do
48
+ @readme_display = text_area width: 368, editable: false
49
+ end
50
+ @readme_window.background_color = @readme_display.background_color
51
+
52
+ @code_window = scroll_window width: 380, height: $window.height * 0.2 do
53
+ @code_display = text_area width: 368, editable: false
54
+ end
55
+ @code_window.background_color = @code_display.background_color
56
+ end
57
+
58
+ vertical padding: 0, width: 380, height: $window.height * 0.45 do
59
+ @log_window = scroll_window width: 380, height: $window.height * 0.45 do
60
+ @log_display = text_area width: 368, editable: false
61
+ end
62
+ @log_window.background_color = @log_display.background_color
63
+ end
64
+ end
65
+ end
66
+
67
+ prepare_level
68
+ end
69
+
70
+ def prepare_level
71
+ @log_display.text = ""
72
+ @continue_button.enabled = false
73
+ @hint_button.enabled = false
74
+ @reset_button.enabled = false
75
+ @start_button.enabled = true
76
+
77
+ # Create the game.
78
+ @game = RubyWarrior::Game.new
79
+
80
+ # Create brand new profile or use the first of those already set.
81
+ profile_to_use = if @game.profiles.empty?
82
+ new_profile = RubyWarrior::Profile.new
83
+ new_profile.tower_path = @game.towers[0].path
84
+ new_profile.warrior_name = "Ruby"
85
+ new_profile
86
+ else
87
+ @game.profiles[0]
88
+ end
89
+
90
+ @game.instance_variable_set :@profile, profile_to_use
91
+
92
+ @game.prepare_next_level unless profile.current_level.number > 0
93
+
94
+ # Start level.
95
+ @_level = profile.current_level
96
+ level.load_player
97
+ level.load_level
98
+
99
+ @readme_display.text = replace_syntax File.read(File.join(level.player_path, "README"))
100
+ every(100) do
101
+ begin
102
+ player_code = File.read File.join(level.player_path, "player.rb")
103
+ unless @code_display.text == player_code
104
+ @code_display.text = player_code
105
+ prepare_level
106
+ end
107
+ rescue Errno::ENOENT
108
+ # This can happen if the file is busy.
109
+ end
110
+ end
111
+
112
+ print "Starting Level #{level.number}\n"
113
+ @tile_set = %w[beginner intermediate].index(profile.tower.name) || 2 # We don't know what the last tower will be called.
114
+ @turn = 0
115
+ @playing = false
116
+
117
+ refresh_labels
118
+ end
119
+
120
+ def refresh_labels
121
+ @tower_label.text = profile.tower.name.capitalize
122
+ @level_label.text = "Level: #{level.number}"
123
+ @turn_label.text = "Turn: #{(@turn + 1).to_s.rjust(2)}"
124
+ @health_label.text = "Health: #{level.warrior.health.to_s.rjust(2)}"
125
+ end
126
+
127
+ def start_level
128
+ @reset_button.enabled = true
129
+ @start_button.enabled = false
130
+ @playing = true
131
+ @take_next_turn_at = Time.now + 0.5
132
+ refresh_labels
133
+ end
134
+
135
+ def replace_syntax(string)
136
+ string.gsub(/warrior\.[a-z]+./) do |s|
137
+ if s[-1, 1] == '!'
138
+ "<c=ff0000>#{s}</c>" # Commands.
139
+ else
140
+ "<c=00ff00>#{s}</c>" # Queries.
141
+ end
142
+ end
143
+ end
144
+
145
+ def profile; @game.profile; end
146
+ def level; @_level; end
147
+ def floor; level.floor; end
148
+
149
+ def play_turn
150
+ self.puts "- turn #{@turn+1} -"
151
+ self.print floor.character
152
+
153
+ floor.units.each(&:prepare_turn)
154
+ floor.units.each(&:perform_turn)
155
+ @turn += 1
156
+ level.time_bonus -= 1 if level.time_bonus > 0
157
+
158
+ @take_next_turn_at = Time.now + 0.5
159
+
160
+ refresh_labels
161
+
162
+ if level.passed?
163
+ if @game.next_level.exists?
164
+ @continue_button.enabled = true
165
+ self.puts "Success! You have found the stairs."
166
+ else
167
+ self.puts "CONGRATULATIONS! You have climbed to the top of the tower and rescued the fair maiden Ruby."
168
+ end
169
+ level.tally_points
170
+ elsif level.failed?
171
+ @hint_button.enabled = true
172
+ self.puts "Sorry, you failed level #{level.number}. Change your script and try again."
173
+ elsif out_of_time?
174
+ @hint_button.enabled = true
175
+ self.puts "Sorry, you starved to death on level #{level.number}. Change your script and try again."
176
+ end
177
+ end
178
+
179
+ def out_of_time?
180
+ @turn > @max_turns
181
+ end
182
+
183
+ def puts(message)
184
+ print message + "\n"
185
+ end
186
+
187
+ def print(message)
188
+ $stdout.puts message
189
+ @log_display.text += message
190
+ @log_window.offset_y = Float::INFINITY
191
+ end
192
+
193
+ SPRITE_WIDTH, SPRITE_HEIGHT = 8, 8
194
+ SPRITE_OFFSET_X, SPRITE_OFFSET_Y = 64, 64
195
+ SPRITE_SCALE = 7
196
+
197
+ def draw
198
+ super
199
+
200
+ $window.translate SPRITE_OFFSET_X, SPRITE_OFFSET_Y do
201
+ $window.scale SPRITE_SCALE do
202
+ # Draw walls.
203
+ floor.width.times do |x|
204
+ light = x % 2
205
+ light = 2 if light == 1 and (Gosu::milliseconds / 500) % 2 == 0
206
+ @tiles[light + 3, @tile_set].draw x * SPRITE_WIDTH, -SPRITE_HEIGHT, 0
207
+ @tiles[3, @tile_set].draw x * SPRITE_WIDTH, floor.height * SPRITE_HEIGHT, 0
208
+ end
209
+ floor.height.times do |y|
210
+ @tiles[3, @tile_set].draw -SPRITE_WIDTH, y * SPRITE_HEIGHT, 0
211
+ @tiles[3, @tile_set].draw floor.width * SPRITE_WIDTH, y * SPRITE_HEIGHT, 0
212
+ end
213
+
214
+ # Draw floor
215
+ floor.width.times do |x|
216
+ floor.height.times do |y|
217
+ @tiles[(x + y + 1) % 2, @tile_set].draw x * SPRITE_WIDTH, y * SPRITE_HEIGHT, 0, 1, 1, FLOOR_COLOR
218
+ end
219
+ end
220
+
221
+ # Draw stairs
222
+ @tiles[2, @tile_set].draw floor.stairs_location[0] * SPRITE_WIDTH, floor.stairs_location[1] * SPRITE_HEIGHT, 0
223
+
224
+ # Draw units.
225
+ floor.units.each do |unit|
226
+ sprite = case unit
227
+ when RubyWarrior::Units::Warrior
228
+ @sprites[0, 0]
229
+ when RubyWarrior::Units::Wizard
230
+ @sprites[0, 1]
231
+ when RubyWarrior::Units::ThickSludge
232
+ @sprites[2, 1]
233
+ when RubyWarrior::Units::Sludge
234
+ @sprites[1, 1]
235
+ when RubyWarrior::Units::Archer
236
+ @sprites[3, 1]
237
+ when RubyWarrior::Units::Captive
238
+ @sprites[0, 2]
239
+ when RubyWarrior::Units::Golem
240
+ @sprites[1, 2]
241
+ else
242
+ raise "unknown unit: #{unit.class}"
243
+ end
244
+
245
+ sprite.draw unit.position.x * SPRITE_WIDTH, unit.position.y * SPRITE_HEIGHT, 0
246
+
247
+ if unit.bound?
248
+ @sprites[2, 2].draw unit.position.x * SPRITE_WIDTH, unit.position.y * SPRITE_HEIGHT, 0
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+ def unit_health_changed(unit, amount)
256
+ color = (amount > 0) ? Color::GREEN : Color::RED
257
+ y_offset = (amount > 0) ? -0.15 : +0.15
258
+ FloatingText.create "#{amount > 0 ? "+" : ""}#{amount}",
259
+ :color => color,
260
+ :x => unit.position.x * SPRITE_SCALE * SPRITE_WIDTH + (SPRITE_SCALE * SPRITE_WIDTH / 2) + SPRITE_OFFSET_X,
261
+ :y => (unit.position.y + y_offset) * SPRITE_SCALE * SPRITE_HEIGHT + SPRITE_OFFSET_Y
262
+ end
263
+
264
+ def update
265
+ super
266
+
267
+ if @playing and Time.now >= @take_next_turn_at and not (level.passed? || level.failed? || out_of_time?)
268
+ play_turn
269
+ end
270
+ end
271
+ end
272
+ end
@@ -0,0 +1,3 @@
1
+ module RubyArmor
2
+ VERSION = "0.0.2alpha"
3
+ end
@@ -0,0 +1,12 @@
1
+ module RubyArmor
2
+ class Window < Chingu::Window
3
+ def initialize
4
+ super 800, 600, false
5
+
6
+ Gosu::enable_undocumented_retrofication
7
+
8
+ self.caption = "RubyArmour GUI for RubyWarrior"
9
+ push_game_state Play
10
+ end
11
+ end
12
+ end
data/lib/ruby_armor.rb ADDED
@@ -0,0 +1,35 @@
1
+ require "ruby_warrior"
2
+
3
+ require 'yaml'
4
+
5
+ require "gosu"
6
+ require "chingu"
7
+ require "fidgit"
8
+
9
+ include Gosu
10
+ include Chingu
11
+
12
+ $LOAD_PATH.unshift File.expand_path("..", __FILE__)
13
+
14
+ require "ruby_armor/ruby_warrior_ext/position"
15
+ require "ruby_armor/ruby_warrior_ext/ui"
16
+ require "ruby_armor/ruby_warrior_ext/units/base"
17
+ require "ruby_armor/ruby_warrior_ext/abilities/rest"
18
+ require "ruby_armor/floating_text"
19
+ require "ruby_armor/sprite_sheet"
20
+ require "ruby_armor/states/play"
21
+ require "ruby_armor/window"
22
+
23
+ ROOT_PATH = File.expand_path('../../', __FILE__)
24
+
25
+ # Setup Chingu's autoloading media directories.
26
+ media_dir = File.expand_path('media', ROOT_PATH)
27
+ Image.autoload_dirs.unshift File.join(media_dir, 'images')
28
+ Sample.autoload_dirs.unshift File.join(media_dir, 'sounds')
29
+ Song.autoload_dirs.unshift File.join(media_dir, 'music')
30
+ Font.autoload_dirs.unshift File.join(media_dir, 'fonts')
31
+
32
+ Fidgit::Element.schema.merge_schema! YAML.load(File.read(File.expand_path('config/gui/schema.yml', ROOT_PATH)))
33
+
34
+ RubyArmor::Window.new.show
35
+
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_armor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2alpha
5
+ prerelease: 5
6
+ platform: ruby
7
+ authors:
8
+ - Bil Bas (Spooner)
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rubywarrior
16
+ requirement: &28045800 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.1.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *28045800
25
+ - !ruby/object:Gem::Dependency
26
+ name: gosu
27
+ requirement: &28045212 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.7.41
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *28045212
36
+ - !ruby/object:Gem::Dependency
37
+ name: chingu
38
+ requirement: &28044456 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9rc7
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *28044456
47
+ - !ruby/object:Gem::Dependency
48
+ name: fidgit
49
+ requirement: &28043952 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.2.1
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *28043952
58
+ description:
59
+ email:
60
+ - bil.bagpuss@gmail.com
61
+ executables:
62
+ - ruby_armour
63
+ - ruby_armor
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - config/gui/schema.yml
68
+ - lib/ruby_armor/floating_text.rb
69
+ - lib/ruby_armor/ruby_warrior_ext/abilities/rest.rb
70
+ - lib/ruby_armor/ruby_warrior_ext/position.rb
71
+ - lib/ruby_armor/ruby_warrior_ext/ui.rb
72
+ - lib/ruby_armor/ruby_warrior_ext/units/base.rb
73
+ - lib/ruby_armor/sprite_sheet.rb
74
+ - lib/ruby_armor/states/play.rb
75
+ - lib/ruby_armor/version.rb
76
+ - lib/ruby_armor/window.rb
77
+ - lib/ruby_armor.rb
78
+ - media/fonts/MONACO.TTF
79
+ - media/images/characters.png
80
+ - media/images/tiles.png
81
+ - bin/ruby_armour
82
+ - bin/ruby_armor
83
+ homepage: http://spooner.github.com/libraries/ruby_armor/
84
+ licenses:
85
+ - MIT
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ segments:
97
+ - 0
98
+ hash: -296871217
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>'
103
+ - !ruby/object:Gem::Version
104
+ version: 1.3.1
105
+ requirements: []
106
+ rubyforge_project: ruby_armor
107
+ rubygems_version: 1.8.16
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: GUI interface for RubyWarrior
111
+ test_files: []