ehb_game_lib 0.1.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ehb_game_lib.rb +2 -24
- data/lib/ehb_game_lib/base_state.rb +0 -4
- data/lib/ehb_game_lib/canvas.rb +20 -0
- data/lib/ehb_game_lib/math.rb +9 -0
- data/lib/ehb_game_lib/math/rectable_object.rb +32 -81
- data/lib/ehb_game_lib/math/rectable_object/axis.rb +63 -0
- data/lib/ehb_game_lib/media_path.rb +45 -0
- data/lib/ehb_game_lib/nes.rb +9 -0
- data/lib/ehb_game_lib/nes/palette.rb +20 -9
- data/lib/ehb_game_lib/nes/pvm_style_d93_palette.pal +0 -0
- data/lib/ehb_game_lib/palettes.rb +9 -0
- data/lib/ehb_game_lib/palettes/color.rb +95 -0
- data/lib/ehb_game_lib/palettes/palette.rb +48 -0
- data/lib/ehb_game_lib/palettes/sprite.rb +42 -0
- data/lib/ehb_game_lib/palettes/sprite_set/paletted.rb +31 -0
- data/lib/ehb_game_lib/palettes/sprite_set/source.rb +45 -0
- data/lib/ehb_game_lib/text.rb +9 -0
- data/lib/ehb_game_lib/utils.rb +9 -0
- data/lib/ehb_game_lib/version.rb +1 -1
- data/lib/ehb_game_lib/window.rb +31 -30
- data/lib/ehb_game_lib/window/gl_read_pixels_image.rb +26 -0
- data/test/lib/ehb_game_lib/math/intersection/circle_line_segment_test.rb +3 -0
- metadata +59 -21
- data/lib/ehb_game_lib/nes/all_colors_palette.rb +0 -31
- data/lib/ehb_game_lib/nes/color.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42ec189978ad34c8ab1c64d5ba99e63ae27099553310cfa380e1cb2eec9bb19d
|
4
|
+
data.tar.gz: aabf62f8fcb17570c9088b3c94dc9d6c47c5900916cb7630e113f3672a3e8f1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1964fd37af7244749fc0303dbe7c9504e2df777574ada1fb5cd7db174705e485363f45bbeacefb66c27ef2436b3f8c5c8b3926bcdc9004f37c81e0740f816fe0
|
7
|
+
data.tar.gz: e8de637269a0de65b42668c04df1632268689cbb26476803b2681d347e1b7ba49525272e5960697b5aca6cbe83f4f1d9a74aee32b7216b34e3c609c2b7217b98
|
data/lib/ehb_game_lib.rb
CHANGED
@@ -1,31 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support'
|
4
|
-
require 'active_support/core_ext'
|
5
3
|
require 'chingu'
|
4
|
+
require 'eac_ruby_utils/core_ext'
|
6
5
|
require 'opengl'
|
7
|
-
require 'ehb_game_lib/version'
|
8
|
-
require 'ehb_game_lib/base_state'
|
9
|
-
require 'ehb_game_lib/globals'
|
10
|
-
require 'ehb_game_lib/gfx'
|
11
|
-
require 'ehb_game_lib/math/circle'
|
12
|
-
require 'ehb_game_lib/math/line'
|
13
|
-
require 'ehb_game_lib/math/line_segment'
|
14
|
-
require 'ehb_game_lib/math/quadratic_equation'
|
15
|
-
require 'ehb_game_lib/math/rectable_object'
|
16
|
-
require 'ehb_game_lib/math/vector'
|
17
|
-
require 'ehb_game_lib/math/intersection/circle_line'
|
18
|
-
require 'ehb_game_lib/math/intersection/circle_line_segment'
|
19
|
-
require 'ehb_game_lib/nes/all_colors_palette'
|
20
|
-
require 'ehb_game_lib/nes/color'
|
21
|
-
require 'ehb_game_lib/nes/palette'
|
22
|
-
require 'ehb_game_lib/patches/chingu/basic_game_object'
|
23
|
-
require 'ehb_game_lib/patches/gosu/font'
|
24
|
-
require 'ehb_game_lib/traits/bounding_line_segment'
|
25
|
-
require 'ehb_game_lib/text/bitmap_font'
|
26
|
-
require 'ehb_game_lib/text/bitmap_text'
|
27
|
-
require 'ehb_game_lib/utils/cursor'
|
28
|
-
require 'ehb_game_lib/window'
|
29
6
|
|
30
7
|
module EhbGameLib
|
8
|
+
require_sub __FILE__
|
31
9
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'ehb_game_lib/math/rectable_object'
|
5
|
+
|
6
|
+
module EhbGameLib
|
7
|
+
class Canvas
|
8
|
+
include ::EhbGameLib::Math::RectableObject
|
9
|
+
|
10
|
+
common_constructor :width, :height
|
11
|
+
|
12
|
+
def x
|
13
|
+
0
|
14
|
+
end
|
15
|
+
|
16
|
+
def y
|
17
|
+
0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,99 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
|
3
5
|
module EhbGameLib
|
4
6
|
module Math
|
5
7
|
module RectableObject
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
require_sub __FILE__
|
9
|
+
|
10
|
+
[%i[ax x width x_anchor left center right], # rubocop:disable Metrics/BlockLength
|
11
|
+
%i[ay y height y_anchor top middle bottom]].each do |aa|
|
12
|
+
a = ::OpenStruct.new(
|
13
|
+
%i[name coord size anchor floor mean ceil]
|
14
|
+
.each_with_index.map { |k, i| [k, aa[i]] }.to_h
|
15
|
+
)
|
16
|
+
|
17
|
+
define_method a.name do
|
18
|
+
@data ||= {}
|
19
|
+
@data[a.name] ||=
|
20
|
+
Axis.new(
|
21
|
+
-> { send(a.coord) },
|
22
|
+
->(v) { send("#{a.coord}=", v) },
|
23
|
+
-> { send(a.size) }
|
18
24
|
)
|
19
|
-
end
|
20
|
-
RUBY_EVAL
|
21
|
-
|
22
|
-
%i[floor mean ceil].each do |m|
|
23
|
-
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
24
|
-
def #{a[m]}
|
25
|
-
#{a[:name]}.#{m}
|
26
|
-
end
|
27
|
-
|
28
|
-
def #{a[m]}=(v)
|
29
|
-
#{a[:name]}.#{m} = v
|
30
|
-
end
|
31
|
-
RUBY_EVAL
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def rect
|
36
|
-
::Chingu::Rect.new(left, top, width, height)
|
37
|
-
end
|
38
|
-
|
39
|
-
class Axis
|
40
|
-
attr_accessor :anchor
|
41
|
-
|
42
|
-
def initialize(coord_get, coord_set, size_get)
|
43
|
-
@coord_get = coord_get
|
44
|
-
@coord_set = coord_set
|
45
|
-
@size_get = size_get
|
46
25
|
end
|
47
26
|
|
48
|
-
|
49
|
-
|
50
|
-
|
27
|
+
%i[anchor floor mean ceil].each do |m|
|
28
|
+
define_method a[m] do |*args|
|
29
|
+
if args.count.zero?
|
30
|
+
send(a.name).send(m)
|
31
|
+
elsif args.count == 1
|
32
|
+
send(a.name).send("#{m}=", args[0])
|
51
33
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def size
|
57
|
-
@size_get.call
|
58
|
-
end
|
59
|
-
|
60
|
-
%w[floor mean ceil].each do |m|
|
61
|
-
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
62
|
-
def #{m}
|
63
|
-
coord + #{m}_delta
|
34
|
+
self
|
35
|
+
else
|
36
|
+
raise ::ArgumentError, "Invalid number of arguments (#{args.count} for 0..1)"
|
64
37
|
end
|
65
|
-
|
66
|
-
def #{m}=(v)
|
67
|
-
self.coord = v - #{m}_delta
|
68
|
-
end
|
69
|
-
RUBY_EVAL
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def floor_delta
|
75
|
-
case anchor
|
76
|
-
when :mean then - size / 2
|
77
|
-
when :ceil then - size
|
78
|
-
else 0
|
79
38
|
end
|
80
|
-
end
|
81
39
|
|
82
|
-
|
83
|
-
|
84
|
-
when :mean then 0
|
85
|
-
when :ceil then - size / 2
|
86
|
-
else size / 2
|
40
|
+
define_method "#{a[m]}=" do |v|
|
41
|
+
send(a.name).send("#{m}=", v)
|
87
42
|
end
|
88
43
|
end
|
44
|
+
end
|
89
45
|
|
90
|
-
|
91
|
-
|
92
|
-
when :mean then size / 2
|
93
|
-
when :ceil then 0
|
94
|
-
else size
|
95
|
-
end
|
96
|
-
end
|
46
|
+
def rect
|
47
|
+
::Chingu::Rect.new(left, top, width, height)
|
97
48
|
end
|
98
49
|
end
|
99
50
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
|
5
|
+
module EhbGameLib
|
6
|
+
module Math
|
7
|
+
module RectableObject
|
8
|
+
class Axis
|
9
|
+
attr_accessor :anchor
|
10
|
+
|
11
|
+
common_constructor :coord_get, :coord_set, :size_get
|
12
|
+
|
13
|
+
def coord
|
14
|
+
coord_get.call
|
15
|
+
end
|
16
|
+
|
17
|
+
def coord=(v)
|
18
|
+
coord_set.call(v)
|
19
|
+
end
|
20
|
+
|
21
|
+
def size
|
22
|
+
size_get.call
|
23
|
+
end
|
24
|
+
|
25
|
+
%w[floor mean ceil].each do |m|
|
26
|
+
define_method m do
|
27
|
+
coord + send("#{m}_delta")
|
28
|
+
end
|
29
|
+
|
30
|
+
define_method "#{m}=" do |v|
|
31
|
+
self.coord = v - send("#{m}_delta")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def floor_delta
|
38
|
+
case anchor
|
39
|
+
when :mean then - size / 2
|
40
|
+
when :ceil then - size
|
41
|
+
else 0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def mean_delta
|
46
|
+
case anchor
|
47
|
+
when :mean then 0
|
48
|
+
when :ceil then - size / 2
|
49
|
+
else size / 2
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def ceil_delta
|
54
|
+
case anchor
|
55
|
+
when :mean then size / 2
|
56
|
+
when :ceil then 0
|
57
|
+
else size
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'ehb_game_lib/palettes/sprite'
|
5
|
+
require 'ehb_game_lib/text/bitmap_font'
|
6
|
+
|
7
|
+
module EhbGameLib
|
8
|
+
class MediaPath
|
9
|
+
class << self
|
10
|
+
# @return [EhbGameLib::MediaPath]
|
11
|
+
def default
|
12
|
+
@default ||= new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array]
|
17
|
+
def paths
|
18
|
+
@paths ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Pathname]
|
22
|
+
def find(subpath)
|
23
|
+
paths.each do |path|
|
24
|
+
full_path = path.to_pathname.expand_path.join(subpath)
|
25
|
+
return full_path if full_path.exist?
|
26
|
+
end
|
27
|
+
raise "Subpath \"#{subpath}\" not found (Searched in: #{paths})"
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [EhbGameLib::Text::BitmapFont]
|
31
|
+
def load_bitmap_font(subpath, line_height)
|
32
|
+
::EhbGameLib::Text::BitmapFont.new(find(subpath).to_path, line_height)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Gosu::Image]
|
36
|
+
def load_gosu_image(subpath)
|
37
|
+
::Gosu::Image.new(find(subpath).to_path, ::EhbGameLib::Palettes::Sprite.to_gosu_image_options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [EhbGameLib::Palettes::Sprite]
|
41
|
+
def load_sprite(subpath)
|
42
|
+
::EhbGameLib::Palettes::Sprite.from_file(find(subpath))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,20 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'ehb_game_lib/palettes/palette'
|
4
|
+
|
3
5
|
module EhbGameLib
|
4
6
|
module Nes
|
5
|
-
|
6
|
-
|
7
|
+
# Reference: http://www.firebrandx.com/nespalette.html
|
8
|
+
class Palette < ::EhbGameLib::Palettes::Palette
|
9
|
+
COLUMNS = %w[grey blue indigo purple violet red brown orange yellow lawn_green lime_green
|
10
|
+
sea_green cyan black].freeze
|
11
|
+
ROWS = %w[dd d l ll].freeze
|
7
12
|
|
8
|
-
|
9
|
-
|
13
|
+
COLUMNS.each_with_index do |c_name, c_index|
|
14
|
+
ROWS.each_with_index do |r_name, r_index|
|
15
|
+
const_set("#{c_name}_#{r_name}".upcase, r_index * 0x10 + c_index)
|
16
|
+
end
|
10
17
|
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
19
|
+
BLACK = BLACK_DD
|
20
|
+
WHITE = GREY_LL
|
21
|
+
TRANSPARENT = 0x3F
|
15
22
|
|
16
|
-
def
|
17
|
-
|
23
|
+
def initialize
|
24
|
+
colors = ::EhbGameLib::Palettes::Color.array_from_file(
|
25
|
+
::File.join(__dir__, 'pvm_style_d93_palette.pal')
|
26
|
+
)
|
27
|
+
colors[TRANSPARENT] = ::EhbGameLib::Palettes::Color.new(0x00, 0x00, 0x00, 0x00)
|
28
|
+
super(colors)
|
18
29
|
end
|
19
30
|
end
|
20
31
|
end
|
Binary file
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'gosu'
|
5
|
+
require 'rmagick'
|
6
|
+
|
7
|
+
module EhbGameLib
|
8
|
+
module Palettes
|
9
|
+
class Color
|
10
|
+
QUANTUM_MIN = 0
|
11
|
+
QUANTUM_MAX = 255
|
12
|
+
QUANTUM_RANGE = (QUANTUM_MIN..QUANTUM_MAX).freeze
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def validate_quantum(quantum)
|
16
|
+
raise "Not a integer: #{quantum}" unless quantum.is_a?(::Integer)
|
17
|
+
raise 'Out of bounds' unless QUANTUM_RANGE.include?(quantum)
|
18
|
+
|
19
|
+
quantum
|
20
|
+
end
|
21
|
+
|
22
|
+
def quantum_to_magick_range(quantum, invert = false)
|
23
|
+
r = ((quantum / QUANTUM_MAX.to_f) * ::Magick::QuantumRange).floor
|
24
|
+
r = ::Magick::QuantumRange - r if invert
|
25
|
+
r
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Array<EhbGameLib::Palettes::Color>]
|
29
|
+
def array_from_file(file_path)
|
30
|
+
r = []
|
31
|
+
::File.open(file_path.to_s) do |file|
|
32
|
+
while (b = file.read(3))
|
33
|
+
b = b.bytes.to_a
|
34
|
+
r << ::EhbGameLib::Palettes::Color.new(b[0], b[1], b[2])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
r
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
enable_simple_cache
|
42
|
+
attr_reader :red, :green, :blue, :alpha
|
43
|
+
|
44
|
+
def initialize(red, green, blue, alpha = QUANTUM_MAX)
|
45
|
+
@red = self.class.validate_quantum(red)
|
46
|
+
@green = self.class.validate_quantum(green)
|
47
|
+
@blue = self.class.validate_quantum(blue)
|
48
|
+
@alpha = self.class.validate_quantum(alpha)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Gosu::Color]
|
52
|
+
def gosu_color
|
53
|
+
@gosu_color ||= ::Gosu::Color.rgba(red, green, blue, alpha)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Magick::Pixel]
|
57
|
+
def magick_pixel
|
58
|
+
@magick_pixel ||= ::Magick::Pixel.new(
|
59
|
+
*[red, green, blue].map { |n| self.class.quantum_to_magick_range(n) },
|
60
|
+
self.class.quantum_to_magick_range(alpha, true)
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def names
|
65
|
+
Array(::Colorname.find(red, green, blue))
|
66
|
+
end
|
67
|
+
|
68
|
+
def rgb_to_s
|
69
|
+
values_to_s(red, green, blue)
|
70
|
+
end
|
71
|
+
|
72
|
+
def rgba_to_s
|
73
|
+
rgb_to_s + '|' + values_to_s(alpha)
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_a
|
77
|
+
[red, green, blue, alpha]
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_s
|
81
|
+
rgba_to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_html
|
85
|
+
'#' + rgb_to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def values_to_s(*values)
|
91
|
+
values.map { |i| i.to_s(16).rjust(2, '0') }.join.upcase
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'gosu'
|
4
|
+
require 'ehb_game_lib/palettes/color'
|
5
|
+
|
6
|
+
module EhbGameLib
|
7
|
+
module Palettes
|
8
|
+
class Palette
|
9
|
+
class << self
|
10
|
+
# @return [EhbGameLib::Palettes::Palette]
|
11
|
+
def from_file(file_path)
|
12
|
+
new(::EhbGameLib::Palettes::Color.array_from_file(file_path))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array<Gosu::Color>]
|
17
|
+
attr_reader :colors
|
18
|
+
|
19
|
+
def initialize(colors)
|
20
|
+
colors.each_with_index do |color, index|
|
21
|
+
unless color.is_a?(::EhbGameLib::Palettes::Color)
|
22
|
+
raise "\##{index} is not a Palette::Color (#{color})"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@colors = colors.to_a.freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [EhbGameLib::Palettes::Color]
|
29
|
+
def color(index)
|
30
|
+
colors.fetch(index)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [EhbGameLib::Palettes::Color]
|
34
|
+
def [](index)
|
35
|
+
colors.fetch(index)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [EhbGameLib::Palettes::Palette]
|
39
|
+
def sub(*indexes)
|
40
|
+
sub_class.new(indexes.map { |index| color(index) })
|
41
|
+
end
|
42
|
+
|
43
|
+
def sub_class
|
44
|
+
::EhbGameLib::Palettes::Palette
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ehb_game_lib/media_path'
|
4
|
+
require 'rmagick'
|
5
|
+
|
6
|
+
module EhbGameLib
|
7
|
+
module Palettes
|
8
|
+
class Sprite
|
9
|
+
class << self
|
10
|
+
def from_file(file_path)
|
11
|
+
new(::Magick::Image.read(file_path.to_s).first)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_gosu_image_options
|
15
|
+
{ retro: true, tileable: true }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
common_constructor :magick_image do
|
20
|
+
magick_image.alpha(::Magick::ActivateAlphaChannel)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return Gosu::Image
|
24
|
+
def gosu_image
|
25
|
+
@gosu_image ||= begin
|
26
|
+
the_path = '/tmp/temp_magick_image.png'
|
27
|
+
magick_image.write(the_path)
|
28
|
+
::Gosu::Image.new(the_path, self.class.to_gosu_image_options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [EhbGameLib::Palettes::Sprite]
|
33
|
+
def palette_image(palette)
|
34
|
+
r = magick_image.dup
|
35
|
+
r.colors.times.each do |index|
|
36
|
+
r.colormap(index, palette.color(index).magick_pixel)
|
37
|
+
end
|
38
|
+
self.class.new(r)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
|
5
|
+
module EhbGameLib
|
6
|
+
module Palettes
|
7
|
+
module SpriteSet
|
8
|
+
class Paletted
|
9
|
+
common_constructor :palette, :source_set
|
10
|
+
|
11
|
+
def [](name)
|
12
|
+
sprite(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def sprite(name)
|
16
|
+
sprites_hash[name.to_sym] ||= source_set.sprite(name).palette_image(palette)
|
17
|
+
end
|
18
|
+
|
19
|
+
def sprites
|
20
|
+
source_set.sprites.keys.map { |name| [name, sprite(name)] }.to_h
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def sprites_hash
|
26
|
+
@sprites_hash ||= {}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'ehb_game_lib/media_path'
|
5
|
+
require 'ehb_game_lib/palettes/sprite'
|
6
|
+
|
7
|
+
module EhbGameLib
|
8
|
+
module Palettes
|
9
|
+
module SpriteSet
|
10
|
+
class Source
|
11
|
+
enable_simple_cache
|
12
|
+
common_constructor :media_path, default: [::EhbGameLib::MediaPath.default]
|
13
|
+
|
14
|
+
def add(name, sprite)
|
15
|
+
sprites_hash[name.to_sym] = sprite
|
16
|
+
reset_cache :sprites
|
17
|
+
end
|
18
|
+
|
19
|
+
def load(subpath, name = nil)
|
20
|
+
name ||= ::File.basename(subpath, '.*')
|
21
|
+
|
22
|
+
add(name, media_path.load_sprite(subpath))
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](name)
|
26
|
+
sprite(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def sprite(name)
|
30
|
+
sprites_hash.fetch(name.to_sym)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def sprites_uncached
|
36
|
+
sprites_hash.dup.freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
def sprites_hash
|
40
|
+
@sprites_hash ||= {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/ehb_game_lib/version.rb
CHANGED
data/lib/ehb_game_lib/window.rb
CHANGED
@@ -1,71 +1,72 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'eac_ruby_utils/require_sub'
|
5
|
+
require 'ehb_game_lib/canvas'
|
6
|
+
::EacRubyUtils.require_sub(__FILE__)
|
7
|
+
|
3
8
|
module EhbGameLib
|
4
9
|
class Window < ::Chingu::Window
|
5
10
|
attr_accessor :fit_canvas_to_window, :draw_retro
|
6
|
-
attr_reader :
|
11
|
+
attr_reader :canvas, :canvas_factor
|
7
12
|
|
8
13
|
def initialize(canvas_width, canvas_height)
|
9
|
-
@
|
10
|
-
@canvas_height = canvas_height
|
14
|
+
@canvas = ::EhbGameLib::Canvas.new(canvas_width, canvas_height)
|
11
15
|
@canvas_factor = 1
|
12
16
|
self.fit_canvas_to_window = true
|
13
17
|
self.draw_retro = true
|
14
18
|
super calculated_width, calculated_height
|
19
|
+
dimensions_reset
|
15
20
|
end
|
16
21
|
|
17
22
|
def calculated_width
|
18
|
-
|
23
|
+
canvas.width * canvas_factor
|
19
24
|
end
|
20
25
|
|
21
26
|
def calculated_height
|
22
|
-
|
27
|
+
canvas.height * canvas_factor
|
23
28
|
end
|
24
29
|
|
25
30
|
def canvas_factor=(factor)
|
26
31
|
@canvas_factor = factor
|
27
|
-
|
28
|
-
|
32
|
+
dimensions_reset
|
33
|
+
end
|
34
|
+
|
35
|
+
def fullscreen=(value)
|
36
|
+
super(value)
|
37
|
+
dimensions_reset
|
29
38
|
end
|
30
39
|
|
31
40
|
def draw
|
32
41
|
super if ::EhbGameLib::Globals.window
|
42
|
+
draw_resized
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def dimensions_reset
|
48
|
+
if fullscreen?
|
49
|
+
self.width = canvas.width
|
50
|
+
self.height = canvas.height
|
51
|
+
else
|
52
|
+
self.width = calculated_width
|
53
|
+
self.height = calculated_height
|
54
|
+
end
|
33
55
|
end
|
34
56
|
|
35
57
|
def draw_resized
|
36
|
-
return unless fit_canvas_to_window
|
58
|
+
return unless fit_canvas_to_window && !fullscreen?
|
37
59
|
|
38
60
|
::Gosu::Image.new(canvas_image_source, retro: draw_retro)
|
39
61
|
.draw(0, 0, 100, canvas_factor, canvas_factor)
|
40
62
|
end
|
41
63
|
|
42
|
-
private
|
43
|
-
|
44
64
|
def canvas_image_source
|
45
|
-
image_source(0, height -
|
65
|
+
image_source(0, height - canvas.height, canvas.width, canvas.height)
|
46
66
|
end
|
47
67
|
|
48
68
|
def image_source(x, y, w, h)
|
49
69
|
GlReadPixelsImage.new(x, y, w, h)
|
50
70
|
end
|
51
|
-
|
52
|
-
class GlReadPixelsImage
|
53
|
-
attr_reader :columns, :rows
|
54
|
-
|
55
|
-
DEPTH = 4
|
56
|
-
|
57
|
-
def initialize(x, y, width, height)
|
58
|
-
@columns = width
|
59
|
-
@rows = height
|
60
|
-
Gosu.flush
|
61
|
-
Gosu.gl do
|
62
|
-
@blob = ::Gl.glReadPixels(x, y, width, height, Gl::GL_RGBA, Gl::GL_UNSIGNED_BYTE)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def to_blob
|
67
|
-
@blob.force_encoding('binary').scan(/.{#{columns * 4}}/m).reverse.join
|
68
|
-
end
|
69
|
-
end
|
70
71
|
end
|
71
72
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'chingu'
|
4
|
+
|
5
|
+
module EhbGameLib
|
6
|
+
class Window < ::Chingu::Window
|
7
|
+
class GlReadPixelsImage
|
8
|
+
attr_reader :columns, :rows
|
9
|
+
|
10
|
+
DEPTH = 4
|
11
|
+
|
12
|
+
def initialize(x, y, width, height)
|
13
|
+
@columns = width
|
14
|
+
@rows = height
|
15
|
+
Gosu.flush
|
16
|
+
Gosu.gl do
|
17
|
+
@blob = ::Gl.glReadPixels(x, y, width, height, Gl::GL_RGBA, Gl::GL_UNSIGNED_BYTE)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_blob
|
22
|
+
@blob.force_encoding('binary').scan(/.{#{columns * 4}}/m).reverse.join
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ehb_game_lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo H. Bogoni
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: chingu
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.8.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.8.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: eac_ruby_utils
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: '0.57'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: '0.57'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: gosu
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,33 +67,59 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rmagick
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.1'
|
73
76
|
- - ">="
|
74
77
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
76
|
-
type: :
|
78
|
+
version: 4.1.2
|
79
|
+
type: :runtime
|
77
80
|
prerelease: false
|
78
81
|
version_requirements: !ruby/object:Gem::Requirement
|
79
82
|
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '4.1'
|
80
86
|
- - ">="
|
81
87
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
88
|
+
version: 4.1.2
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
90
|
+
name: eac_ruby_gem_support
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
86
92
|
requirements:
|
87
93
|
- - "~>"
|
88
94
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
95
|
+
version: '0.1'
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.1.2
|
90
99
|
type: :development
|
91
100
|
prerelease: false
|
92
101
|
version_requirements: !ruby/object:Gem::Requirement
|
93
102
|
requirements:
|
94
103
|
- - "~>"
|
95
104
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
105
|
+
version: '0.1'
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 0.1.2
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rake
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
97
123
|
- !ruby/object:Gem::Dependency
|
98
124
|
name: test-unit
|
99
125
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,8 +143,10 @@ extra_rdoc_files: []
|
|
117
143
|
files:
|
118
144
|
- lib/ehb_game_lib.rb
|
119
145
|
- lib/ehb_game_lib/base_state.rb
|
146
|
+
- lib/ehb_game_lib/canvas.rb
|
120
147
|
- lib/ehb_game_lib/gfx.rb
|
121
148
|
- lib/ehb_game_lib/globals.rb
|
149
|
+
- lib/ehb_game_lib/math.rb
|
122
150
|
- lib/ehb_game_lib/math/circle.rb
|
123
151
|
- lib/ehb_game_lib/math/intersection/circle_line.rb
|
124
152
|
- lib/ehb_game_lib/math/intersection/circle_line_segment.rb
|
@@ -126,18 +154,29 @@ files:
|
|
126
154
|
- lib/ehb_game_lib/math/line_segment.rb
|
127
155
|
- lib/ehb_game_lib/math/quadratic_equation.rb
|
128
156
|
- lib/ehb_game_lib/math/rectable_object.rb
|
157
|
+
- lib/ehb_game_lib/math/rectable_object/axis.rb
|
129
158
|
- lib/ehb_game_lib/math/vector.rb
|
130
|
-
- lib/ehb_game_lib/
|
131
|
-
- lib/ehb_game_lib/nes
|
159
|
+
- lib/ehb_game_lib/media_path.rb
|
160
|
+
- lib/ehb_game_lib/nes.rb
|
132
161
|
- lib/ehb_game_lib/nes/palette.rb
|
162
|
+
- lib/ehb_game_lib/nes/pvm_style_d93_palette.pal
|
163
|
+
- lib/ehb_game_lib/palettes.rb
|
164
|
+
- lib/ehb_game_lib/palettes/color.rb
|
165
|
+
- lib/ehb_game_lib/palettes/palette.rb
|
166
|
+
- lib/ehb_game_lib/palettes/sprite.rb
|
167
|
+
- lib/ehb_game_lib/palettes/sprite_set/paletted.rb
|
168
|
+
- lib/ehb_game_lib/palettes/sprite_set/source.rb
|
133
169
|
- lib/ehb_game_lib/patches/chingu/basic_game_object.rb
|
134
170
|
- lib/ehb_game_lib/patches/gosu/font.rb
|
171
|
+
- lib/ehb_game_lib/text.rb
|
135
172
|
- lib/ehb_game_lib/text/bitmap_font.rb
|
136
173
|
- lib/ehb_game_lib/text/bitmap_text.rb
|
137
174
|
- lib/ehb_game_lib/traits/bounding_line_segment.rb
|
175
|
+
- lib/ehb_game_lib/utils.rb
|
138
176
|
- lib/ehb_game_lib/utils/cursor.rb
|
139
177
|
- lib/ehb_game_lib/version.rb
|
140
178
|
- lib/ehb_game_lib/window.rb
|
179
|
+
- lib/ehb_game_lib/window/gl_read_pixels_image.rb
|
141
180
|
- test/lib/ehb_game_lib/math/circle_test.rb
|
142
181
|
- test/lib/ehb_game_lib/math/intersection/circle_line_segment_test.rb
|
143
182
|
- test/lib/ehb_game_lib/math/intersection/circle_line_test.rb
|
@@ -164,8 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
203
|
- !ruby/object:Gem::Version
|
165
204
|
version: '0'
|
166
205
|
requirements: []
|
167
|
-
|
168
|
-
rubygems_version: 2.7.7
|
206
|
+
rubygems_version: 3.0.8
|
169
207
|
signing_key:
|
170
208
|
specification_version: 4
|
171
209
|
summary: EHB's game library for Ruby
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EhbGameLib
|
4
|
-
module Nes
|
5
|
-
class AllColorsPalette
|
6
|
-
def initialize(pal_file)
|
7
|
-
@colors = []
|
8
|
-
File.open(pal_file) do |file|
|
9
|
-
while (b = file.read(3))
|
10
|
-
b = b.bytes.to_a
|
11
|
-
@colors << Gosu::Color.rgba(b[0], b[1], b[2], 0xFF)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
@colors.freeze
|
15
|
-
end
|
16
|
-
|
17
|
-
def gosu_color(i)
|
18
|
-
@colors[i]
|
19
|
-
end
|
20
|
-
|
21
|
-
def draw(x, y)
|
22
|
-
s = 32
|
23
|
-
@colors.each_with_index do |c, i|
|
24
|
-
cx = x + (i % 16) * s
|
25
|
-
cy = y + (i / 16) * s
|
26
|
-
Gosu.draw_rect(cx, cy, s, s, c)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EhbGameLib
|
4
|
-
module Nes
|
5
|
-
class Color
|
6
|
-
attr_accessor :color_index
|
7
|
-
|
8
|
-
BLACK = 0x0F
|
9
|
-
YELLOW = 0x28
|
10
|
-
RED = 0x05
|
11
|
-
WHITE = 0x30
|
12
|
-
|
13
|
-
def initialize(all_colors, color_index)
|
14
|
-
@all_colors = all_colors
|
15
|
-
@color_index = color_index
|
16
|
-
end
|
17
|
-
|
18
|
-
def gosu_color
|
19
|
-
@all_colors.gosu_color(color_index)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|