colstrom-ruby_armor 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae135a2df0ad854fa1672d90bbd9c25dcc6d15bb
4
+ data.tar.gz: 5b58540c38a00139ea14ccd2f429ba708ee8b9c6
5
+ SHA512:
6
+ metadata.gz: 49b493e0abb56830cdc14b51c5fd15d98bb92e7bd2e9b084edb6e61ddc81073540bd994f5233e9185b846e9ac8855cd6da35e3c96bc981cfa3671d5d0bd503c6
7
+ data.tar.gz: 26e99c3a1e72b99d23158c5d57f6db6bf889208a9c24e21b96a09fde256d6d630e5e427653b3e6cb79371fbaa23e6a1b7ea51a7654ee756f631aaf733f530c58
@@ -0,0 +1,54 @@
1
+
2
+ # Created by https://www.gitignore.io/api/ruby
3
+
4
+ ### Ruby ###
5
+ *.gem
6
+ *.rbc
7
+ /.config
8
+ /coverage/
9
+ /InstalledFiles
10
+ /pkg/
11
+ /spec/reports/
12
+ /spec/examples.txt
13
+ /test/tmp/
14
+ /test/version_tmp/
15
+ /tmp/
16
+
17
+ # Used by dotenv library to load environment variables.
18
+ # .env
19
+
20
+ ## Specific to RubyMotion:
21
+ .dat*
22
+ .repl_history
23
+ build/
24
+ *.bridgesupport
25
+ build-iPhoneOS/
26
+ build-iPhoneSimulator/
27
+
28
+ ## Specific to RubyMotion (use of CocoaPods):
29
+ #
30
+ # We recommend against adding the Pods directory to your .gitignore. However
31
+ # you should judge for yourself, the pros and cons are mentioned at:
32
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
33
+ #
34
+ # vendor/Pods/
35
+
36
+ ## Documentation cache and generated files:
37
+ /.yardoc/
38
+ /_yardoc/
39
+ /doc/
40
+ /rdoc/
41
+
42
+ ## Environment normalization:
43
+ /.bundle/
44
+ /vendor/bundle
45
+ /lib/bundler/man/
46
+
47
+ # for a library or gem, you might want to ignore these files since the code is
48
+ # intended to run in multiple environments; otherwise, check them in:
49
+ # Gemfile.lock
50
+ # .ruby-version
51
+ # .ruby-gemset
52
+
53
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
54
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,57 @@
1
+ Ruby Armor
2
+ ==========
3
+
4
+ A graphical front-end for [RubyWarrior](https://github.com/ryanb/ruby-warrior). Make sure your Ruby Warrior is wearing Ruby Armor!
5
+
6
+ * Author: Spooner / Bil Bas (bil.bagpuss@gmail.com)
7
+ * License: [MIT](http://opensource.org/licenses/MIT)
8
+ * Website: http://spooner.github.com/games/ruby_armor/
9
+ * Project: https://github.com/Spooner/ruby_armor
10
+
11
+ Features
12
+ --------
13
+
14
+ RubyArmor has all the features of [RubyWarrior](https://github.com/ryanb/ruby-warrior), but with a more friendly, graphical interface. It also adds some unique features:
15
+
16
+ ### Extended functionality
17
+
18
+ * After a level has been finished (completed or failed) the user can drag a slider to see what the state was during each turn.
19
+ * Records code and score when each level is completed. This code can be reviewed at any point later, which can be used to see how your code evolved during play.
20
+ * Speed of playback can be changed while watching the game being played (from one turn per display frame, up to one turn per second). Preferred playback speed is saved with the profile.
21
+ * At any point, user can reset the level back to the start, without having to wait to see it played out to the end.
22
+ * The text log can be viewed as individual turns rather than the normal stream of turns. This can make it easier to follow.
23
+
24
+ ### Purely cosmetic additions
25
+
26
+ * The rogue-like ASCII game display is also displayed with colourful graphics in a pixelated style.
27
+ * Floating numbers appear when damage is taken or healed.
28
+ * Can choose whether you play as a Valkyrie, Mercenary, Monk or Burglar (This difference is entirely cosmetic, since it just changes the graphics used for the warrior).
29
+
30
+ Installation
31
+ ------------
32
+
33
+ RubyArmor requires Ruby 1.9.2 or higher (sorry!). It is still in an alpha state, so must be installed using `--pre`
34
+
35
+ > gem install ruby_armor --pre
36
+
37
+ Play
38
+ ----
39
+
40
+ > ruby_armor
41
+
42
+ Credits
43
+ -------
44
+
45
+ * A myriad thanks to ryanb for making such an inspiring game as RubyWarrior!
46
+ * Thanks to jlnr and RomyRomy for play-testing and suggestions.
47
+
48
+
49
+ Third party assets used
50
+ -----------------------
51
+
52
+ * Font: [ProggyCleanSZ.ttf](http://proggyfonts.com)
53
+ * Sprites made by Oryx from his [LOFI Sprite Pack](http://cgbarrett.squarespace.com/sprites/). [![CC BY-NC-ND](http://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png)](http://creativecommons.org/licenses/by-nc-nd/3.0/)
54
+ * [Gosu](http://libgosu.org/) game development library
55
+ * [Chingu](http://ippa.se/chingu) game library (extending Gosu)
56
+ * [Fidgit](https://github.com/Spooner/fidgit) gui library (extending Chingu)
57
+ * [RubyWarrior](https://github.com/ryanb/ruby-warrior) gem
@@ -0,0 +1,15 @@
1
+ require 'bundler/setup'
2
+ require 'rake/clean'
3
+ require 'rake/testtask'
4
+
5
+ DISTRO_FILES = Dir[*%w<config/**/* lib/**/* media/**/* test/**/* *.md *.txt>]
6
+
7
+ CLEAN.include("*.log")
8
+ CLOBBER.include("doc/**/*")
9
+
10
+ Dir['rake/**/*.rake'].each {|f| import f }
11
+
12
+ Bundler::GemHelper.install_tasks
13
+ task :build => :gemspec
14
+ task :install => :gemspec
15
+ task :release => :gemspec
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # For running from the gem, so path will already be set.
4
+
5
+ require "ruby_armor"
6
+
7
+ RubyArmor::Window.new.show unless defined? Ocra
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
4
+
5
+ require "ruby_armor"
6
+
7
+ RubyArmor::Window.new.show unless defined? Ocra
@@ -0,0 +1,5 @@
1
+ ---
2
+
3
+ :description: This is the config file for RubyArmor and does not affect the game in any way if using RubyWarrior natively.
4
+ :turn_delay: 0.5 # seconds
5
+ :warrior_class: :valkyrie # :valkyrie, :mercenary, :monk, :burglar
@@ -0,0 +1,73 @@
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: ProggyCleanSZ.ttf
17
+ :font_height: 16
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: 14
62
+
63
+ :ScrollBar: # < Composite
64
+ :rail_width: 14
65
+ :rail_color: ?light_background
66
+ :handle_color: ?handle
67
+
68
+
69
+ :ScrollWindow: # < Composite
70
+ :scroll_bar_thickness: 12
71
+ :border_color: ?light_border
72
+ :background_color: ?dark_background
73
+
@@ -0,0 +1,42 @@
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/version"
15
+
16
+ require "ruby_armor/ruby_warrior_ext/position"
17
+ require "ruby_armor/ruby_warrior_ext/ui"
18
+ require "ruby_armor/ruby_warrior_ext/player_generator"
19
+ require "ruby_armor/ruby_warrior_ext/units/base"
20
+ require "ruby_armor/ruby_warrior_ext/abilities/rest"
21
+
22
+ require "ruby_armor/floating_text"
23
+ require "ruby_armor/sprite_sheet"
24
+ require "ruby_armor/states/create_profile"
25
+ require "ruby_armor/states/choose_profile"
26
+ require "ruby_armor/states/play"
27
+ require "ruby_armor/states/review_code"
28
+ require "ruby_armor/dungeon_view"
29
+ require "ruby_armor/window"
30
+ require "ruby_armor/warrior_config"
31
+
32
+ ROOT_PATH = File.expand_path('../../', __FILE__)
33
+
34
+ # Setup Chingu's autoloading media directories.
35
+ media_dir = File.expand_path('media', ROOT_PATH)
36
+ Image.autoload_dirs.unshift File.join(media_dir, 'images')
37
+ Sample.autoload_dirs.unshift File.join(media_dir, 'sounds')
38
+ Song.autoload_dirs.unshift File.join(media_dir, 'music')
39
+ Font.autoload_dirs.unshift File.join(media_dir, 'fonts')
40
+
41
+ Fidgit::Element.schema.merge_schema! YAML.load(File.read(File.expand_path('config/gui/schema.yml', ROOT_PATH)))
42
+
@@ -0,0 +1,38 @@
1
+ module RubyArmor
2
+ class BaseUserData
3
+ #include Log
4
+
5
+ def initialize(user_file, default_file)
6
+ @user_file = user_file
7
+
8
+ @data = if File.exists?(@user_file)
9
+ begin
10
+ YAML.load_file @user_file
11
+ rescue Psych::SyntaxError #log.warn { "Failed to load #{@user_file}; cleared settings" }
12
+
13
+ {}
14
+ end
15
+ else
16
+ {}
17
+ end
18
+
19
+ @data = YAML.load_file(default_file).deep_merge @data
20
+
21
+ #log.info { "Read and merged user data:\n#{@data}" }
22
+
23
+ save
24
+ end
25
+
26
+ protected
27
+ def data; @data; end
28
+
29
+ protected
30
+ def save
31
+ FileUtils.mkdir_p File.dirname(@user_file)
32
+
33
+ File.open(@user_file, "w") {|f| YAML.dump(@data, f) }
34
+
35
+ #log.info { "Saved #{File.basename(@user_file)}" }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,234 @@
1
+ module RubyArmor
2
+ class DungeonView < Fidgit::Vertical
3
+
4
+ # Sprites to show based on player facing.
5
+ FACINGS = {
6
+ :east => 0,
7
+ :south => 1,
8
+ :west => 2,
9
+ :north => 3,
10
+ }
11
+
12
+ # Rows in the warriors.png to use for each warrior type.
13
+ WARRIORS = {
14
+ :valkyrie => 0,
15
+ :mercenary => 1,
16
+ :monk => 2,
17
+ :burglar => 3,
18
+ }
19
+
20
+ FLOOR_COLOR = Color.rgba 255, 255, 255, 125
21
+ TILE_WIDTH, TILE_HEIGHT = 8, 12
22
+ SPRITE_WIDTH, SPRITE_HEIGHT = 8, 8
23
+ SPRITE_SCALE = 5
24
+
25
+ attr_accessor :floor, :tile_set, :turn
26
+
27
+ def initialize(packer, warrior_class)
28
+ @warrior_class = warrior_class
29
+
30
+ super padding: 0, width: 670, height: 260, parent: packer
31
+
32
+ @tiles = SpriteSheet.new "tiles.png", TILE_WIDTH, TILE_HEIGHT, 8
33
+ @warrior_sprites = SpriteSheet.new "warriors.png", SPRITE_WIDTH, SPRITE_HEIGHT, 4
34
+ @mob_sprites = SpriteSheet.new "mobs.png", SPRITE_WIDTH, SPRITE_HEIGHT, 4
35
+
36
+ @units_record = Array.new
37
+ @turn = @tile_set = 0
38
+ end
39
+
40
+ def floor=(floor)
41
+ @floor = floor
42
+
43
+ warrior = floor.units.find {|u| u.is_a? RubyWarrior::Units::Warrior }
44
+ @entry_x, @entry_y = warrior.position.x, warrior.position.y
45
+
46
+ # Work out how to offset the level graphics based on how large it is (should be centered in the level area.
47
+ level_width = floor.width * SPRITE_SCALE * SPRITE_WIDTH
48
+ level_height = floor.height * SPRITE_SCALE * SPRITE_HEIGHT
49
+
50
+ @level_offset_x = (width - level_width) / 2
51
+ @level_offset_y = (height - level_height) / 2
52
+
53
+ @tips = Hash.new
54
+
55
+ @floor
56
+ end
57
+
58
+ def turn=(turn)
59
+ @turn = turn
60
+
61
+ # Record tips for each tile for this turn, but not if we are revisiting it.
62
+ unless @tips[turn]
63
+ @tips[turn] = {}
64
+ floor.width.times do |x|
65
+ floor.height.times do |y|
66
+ @tips[turn][[x, y]] = tip_for_tile x, y
67
+ end
68
+ end
69
+ end
70
+
71
+ @turn
72
+ end
73
+
74
+ def draw
75
+ $window.translate @level_offset_x, @level_offset_y do
76
+ $window.scale SPRITE_SCALE do
77
+ draw_floor
78
+ draw_walls
79
+ draw_stairs
80
+ draw_entrance
81
+ draw_units
82
+ end
83
+ end
84
+ end
85
+
86
+ # Draw trapdoor (entrance)
87
+ def draw_entrance
88
+ @tiles[6, @tile_set].draw @entry_x * SPRITE_WIDTH, @entry_y * SPRITE_HEIGHT, 0
89
+ end
90
+
91
+ # Draw stairs (exit)
92
+ def draw_stairs
93
+ if floor.stairs_location[0] == 0
94
+ # flip when on the left hand side.
95
+ @tiles[2, @tile_set].draw (floor.stairs_location[0] + 1) * SPRITE_WIDTH, floor.stairs_location[1] * SPRITE_HEIGHT, 0, -1
96
+ else
97
+ @tiles[2, @tile_set].draw floor.stairs_location[0] * SPRITE_WIDTH, floor.stairs_location[1] * SPRITE_HEIGHT, 0
98
+ end
99
+ end
100
+
101
+ def draw_walls
102
+ # Draw horizontal walls.
103
+ floor.width.times do |x|
104
+ light = x % 2
105
+ light = 2 if light == 1 and (Gosu::milliseconds / 500) % 2 == 0
106
+ @tiles[light + 3, @tile_set].draw x * SPRITE_WIDTH, -SPRITE_HEIGHT, 0
107
+ @tiles[3, @tile_set].draw x * SPRITE_WIDTH, floor.height * SPRITE_HEIGHT, floor.height
108
+ end
109
+ # Draw vertical walls.
110
+ (-1..floor.height).each do |y|
111
+ @tiles[3, @tile_set].draw -SPRITE_WIDTH, y * SPRITE_HEIGHT, y
112
+ @tiles[3, @tile_set].draw floor.width * SPRITE_WIDTH, y * SPRITE_HEIGHT, y
113
+ end
114
+ end
115
+
116
+ def draw_floor
117
+ # Draw floor
118
+ floor.width.times do |x|
119
+ floor.height.times do |y|
120
+ @tiles[(x + y + 1) % 2, @tile_set].draw x * SPRITE_WIDTH, y * SPRITE_HEIGHT, 0, 1, 1, FLOOR_COLOR
121
+ end
122
+ end
123
+ end
124
+
125
+ def draw_units
126
+ @units_record[turn] ||= $window.record 1, 1 do
127
+ floor.units.sort_by {|u| u.position.y }.each do |unit|
128
+ sprite = case unit
129
+ when RubyWarrior::Units::Warrior
130
+ @warrior_sprites[FACINGS[unit.position.direction], WARRIORS[@warrior_class]]
131
+ when RubyWarrior::Units::Wizard
132
+ @mob_sprites[0, 1]
133
+ when RubyWarrior::Units::ThickSludge
134
+ @mob_sprites[2, 1]
135
+ when RubyWarrior::Units::Sludge
136
+ @mob_sprites[1, 1]
137
+ when RubyWarrior::Units::Archer
138
+ @mob_sprites[3, 1]
139
+ when RubyWarrior::Units::Captive
140
+ @mob_sprites[0, 2]
141
+ when RubyWarrior::Units::Golem
142
+ @mob_sprites[1, 2]
143
+ else
144
+ raise "unknown unit: #{unit.class}"
145
+ end
146
+
147
+ # Draw unit itself
148
+ x, y, z_order = unit.position.x * SPRITE_WIDTH, unit.position.y * SPRITE_HEIGHT, unit.position.y
149
+ sprite.draw x, y, z_order
150
+
151
+ # Draw health number
152
+ $window.scale 0.25 do
153
+ Font[12].draw unit.health, x * 4, y * 4 - 20, z_order
154
+ end
155
+
156
+ # Draw health-bar (black border, with red bar).
157
+ draw_rect x, y - 2, SPRITE_WIDTH, 1, z_order, Color::BLACK
158
+ draw_rect x + HEALTH_BAR_BORDER, y + HEALTH_BAR_BORDER - 2,
159
+ (SPRITE_WIDTH - 1) * unit.health / unit.max_health + HEALTH_BAR_BORDER * 2, 1 - HEALTH_BAR_BORDER * 2,
160
+ z_order, Color::RED
161
+
162
+ # Draw binding rope if if it tied up.
163
+ if unit.bound?
164
+ @mob_sprites[2, 2].draw x, y, z_order
165
+ end
166
+ end
167
+ end
168
+
169
+ @units_record[turn].draw 0, 0, 0
170
+ end
171
+
172
+ HEALTH_BAR_BORDER = 0.25
173
+
174
+
175
+ def unit_health_changed(unit, amount)
176
+ return unless @level_offset_x # Ignore changes out of order, such as between epic levels.
177
+
178
+ color = (amount > 0) ? Color::GREEN : Color::RED
179
+ y_offset = (amount > 0) ? -0.15 : +0.15
180
+ FloatingText.create "#{amount > 0 ? "+" : ""}#{amount}",
181
+ :color => color,
182
+ :x => unit.position.x * SPRITE_SCALE * SPRITE_WIDTH + (SPRITE_SCALE * SPRITE_WIDTH / 2) + @level_offset_x,
183
+ :y => (unit.position.y + y_offset) * SPRITE_SCALE * SPRITE_HEIGHT + @level_offset_y
184
+ end
185
+
186
+ # Tip is the unit/object under the cursor ON displayed turn.
187
+ def tip
188
+ # Find out the grid location of the cursor.
189
+ cursor = $window.current_game_state.cursor
190
+ x = (cursor.x - @level_offset_x) / (SPRITE_SCALE * SPRITE_WIDTH)
191
+ y = (cursor.y - @level_offset_y) / (SPRITE_SCALE * SPRITE_HEIGHT)
192
+ x, y = x.floor, y.floor
193
+
194
+ if x == -1 or x == floor.width or y == -1 or y == floor.height
195
+ "Wall"
196
+ else
197
+ @tips[@turn][[x, y]]
198
+ end
199
+ end
200
+
201
+ # Tip for the tile at x, y.
202
+ def tip_for_tile(x, y)
203
+ # Check if the mouse is over a unit.
204
+ unit = floor.units.find {|u| u.position.x == x and u.position.y == y }
205
+
206
+ unit_str = if unit
207
+ "#{unit.to_s} (#{unit.health} / #{unit.max_health} health)"
208
+ else
209
+ nil
210
+ end
211
+
212
+ unit_str += " (bound)" if unit and unit.bound?
213
+
214
+ location_str = case [x, y]
215
+ when floor.stairs_location
216
+ "Stairs (level exit) "
217
+ when [@entry_x, @entry_y]
218
+ "Trapdoor (level entry) "
219
+ else
220
+ nil
221
+ end
222
+
223
+ if unit_str and location_str
224
+ "#{unit_str} on #{location_str}"
225
+ elsif unit_str
226
+ unit_str
227
+ elsif location_str
228
+ location_str
229
+ else
230
+ nil
231
+ end
232
+ end
233
+ end
234
+ end