ruby_armor 0.0.2alpha

Sign up to get free protection for your applications and to get access to all the features.
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: []