reight 0.1.5 → 0.1.7
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.
- checksums.yaml +4 -4
- data/ChangeLog.md +57 -0
- data/Rakefile +4 -1
- data/VERSION +1 -1
- data/lib/reight/all.rb +10 -6
- data/lib/reight/app/map/brush.rb +1 -1
- data/lib/reight/app/map/brush_base.rb +3 -3
- data/lib/reight/app/map/canvas.rb +4 -13
- data/lib/reight/app/map/chips.rb +6 -2
- data/lib/reight/app/map/editor.rb +4 -4
- data/lib/reight/app/map/line.rb +5 -5
- data/lib/reight/app/map/rect.rb +2 -2
- data/lib/reight/app/navigator.rb +27 -27
- data/lib/reight/app/runner.rb +106 -84
- data/lib/reight/app/sound/brush.rb +32 -0
- data/lib/reight/app/sound/canvas.rb +190 -0
- data/lib/reight/app/sound/editor.rb +170 -10
- data/lib/reight/app/sound/eraser.rb +28 -0
- data/lib/reight/app/sound/tool.rb +29 -0
- data/lib/reight/app/sound.rb +4 -0
- data/lib/reight/app/sprite/canvas.rb +18 -15
- data/lib/reight/app/sprite/chips.rb +6 -1
- data/lib/reight/app/sprite/color.rb +3 -1
- data/lib/reight/app/sprite/editor.rb +15 -28
- data/lib/reight/app/sprite/line.rb +1 -1
- data/lib/reight/app/sprite/shape.rb +1 -1
- data/lib/reight/app.rb +19 -1
- data/lib/reight/button.rb +7 -4
- data/lib/reight/chip.rb +24 -6
- data/lib/reight/context.rb +168 -0
- data/lib/reight/helpers.rb +2 -2
- data/lib/reight/index.rb +76 -0
- data/lib/reight/map.rb +131 -11
- data/lib/reight/project.rb +34 -6
- data/lib/reight/reight.rb +1 -3
- data/lib/reight/sound.rb +238 -0
- data/lib/reight/sprite.rb +42 -0
- data/lib/reight/text.rb +116 -0
- data/lib/reight.rb +7 -3
- data/reight.gemspec +7 -7
- data/res/icons.png +0 -0
- data/test/helper.rb +16 -0
- data/test/test_map.rb +7 -7
- data/test/test_map_chunk.rb +6 -6
- data/test/test_sprite.rb +28 -0
- metadata +39 -30
- data/lib/reight/app/music/editor.rb +0 -25
- data/lib/reight/app/music.rb +0 -1
@@ -0,0 +1,168 @@
|
|
1
|
+
module Reight::Context
|
2
|
+
|
3
|
+
include Processing::GraphicsContext
|
4
|
+
include RubySketch::GraphicsContext
|
5
|
+
|
6
|
+
TIMER_PREFIX__ = '__r8__'
|
7
|
+
|
8
|
+
# @private
|
9
|
+
def initialize(rootContext, project)
|
10
|
+
@rootContext__, @project__ = rootContext, project
|
11
|
+
init__ Rays::Image.new(@rootContext__.width, @rootContext__.height)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the project object.
|
15
|
+
#
|
16
|
+
def project()
|
17
|
+
@project__
|
18
|
+
end
|
19
|
+
|
20
|
+
# @private
|
21
|
+
def screenOffset(*args)
|
22
|
+
unless args.empty?
|
23
|
+
args = args.flatten
|
24
|
+
x, y, z =
|
25
|
+
case arg = args.first
|
26
|
+
when Vector then [arg.x, arg.y, arg.z]
|
27
|
+
when Numeric then [args[0], args[1] || 0, args[2] || 0]
|
28
|
+
when nil then [0, 0, 0]
|
29
|
+
else raise ArgumentError
|
30
|
+
end
|
31
|
+
cx, cy, = @canvasFrame__
|
32
|
+
if cx && cy
|
33
|
+
zoom = spriteWorld__.zoom
|
34
|
+
x += cx / zoom
|
35
|
+
y += cy / zoom
|
36
|
+
end
|
37
|
+
spriteWorld__.offset = [x, y, z]
|
38
|
+
end
|
39
|
+
spriteWorld__.offset
|
40
|
+
end
|
41
|
+
|
42
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#size-instance_method
|
43
|
+
def size(width, height, **)
|
44
|
+
return if width == self.width || height == self.height
|
45
|
+
@resizeCanvas__ = [width, height]
|
46
|
+
end
|
47
|
+
|
48
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#createCanvas-instance_method
|
49
|
+
alias createCanvas size
|
50
|
+
|
51
|
+
# @see https://www.rubydoc.info/gems/processing/Processing/Context#mouseX-instance_method
|
52
|
+
def mouseX()
|
53
|
+
x, (cx, _) = @rootContext__.mouseX, @canvasFrame__
|
54
|
+
cx ? (x - cx) / spriteWorld__.zoom : x
|
55
|
+
end
|
56
|
+
|
57
|
+
# @see https://www.rubydoc.info/gems/processing/Processing/Context#mouseY-instance_method
|
58
|
+
def mouseY()
|
59
|
+
y, (_, cy) = @rootContext__.mouseY, @canvasFrame__
|
60
|
+
cy ? (y - cy) / spriteWorld__.zoom : y
|
61
|
+
end
|
62
|
+
|
63
|
+
# @see https://www.rubydoc.info/gems/processing/Processing/Context#pmouseX-instance_method
|
64
|
+
def pmouseX()
|
65
|
+
x, (cx, _) = @rootContext__.pmouseX, @canvasFrame__
|
66
|
+
cx ? (x - cx) / spriteWorld__.zoom : x
|
67
|
+
end
|
68
|
+
|
69
|
+
# @see https://www.rubydoc.info/gems/processing/Processing/Context#pmouseY-instance_method
|
70
|
+
def pmouseY()
|
71
|
+
y, (_, cy) = @rootContext__.pmouseY, @canvasFrame__
|
72
|
+
cy ? (y - cy) / spriteWorld__.zoom : y
|
73
|
+
end
|
74
|
+
|
75
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#createSprite-instance_method
|
76
|
+
def createSprite(*args, klass: nil, **kwargs, &block)
|
77
|
+
klass ||= Reight::Sprite
|
78
|
+
spriteWorld__.createSprite(*args, klass: klass, **kwargs, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#addSprite-instance_method
|
82
|
+
def addSprite(...)
|
83
|
+
spriteWorld__.addSprite(...)
|
84
|
+
end
|
85
|
+
|
86
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#removeSprite-instance_method
|
87
|
+
def removeSprite(...)
|
88
|
+
spriteWorld__.removeSprite(...)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#gravity-instance_method
|
92
|
+
def gravity(...)
|
93
|
+
spriteWorld__.gravity(...)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#setTimeout-instance_method
|
97
|
+
def setTimeout( *a, id: @rootContext__.nextTimerID__, **k, &b)
|
98
|
+
id = [TIMER_PREFIX__, id]
|
99
|
+
@rootContext__.setTimeout(*a, id: id, **k, &b)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#setInterval-instance_method
|
103
|
+
def setInterval(*a, id: @rootContext__.nextTimerID__, **k, &b)
|
104
|
+
id = [TIMER_PREFIX__, id]
|
105
|
+
@rootContext__.setInterval(*a, id: id, **k, &b)
|
106
|
+
end
|
107
|
+
|
108
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#clearTimer-instance_method
|
109
|
+
def clearTimer(id)
|
110
|
+
@rootContext__.clearTimer [TIMER_PREFIX__, id]
|
111
|
+
end
|
112
|
+
|
113
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#clearTimeout-instance_method
|
114
|
+
def clearTimeout(id)
|
115
|
+
@rootContext__.clearTimeout [TIMER_PREFIX__, id]
|
116
|
+
end
|
117
|
+
|
118
|
+
# @see https://rubydoc.info/gems/rubysketch/RubySketch/Context#clearInterval-instance_method
|
119
|
+
def clearInterval(id)
|
120
|
+
@rootContext__.clearInterval [TIMER_PREFIX__, id]
|
121
|
+
end
|
122
|
+
|
123
|
+
# @private
|
124
|
+
def beginDraw__()
|
125
|
+
super
|
126
|
+
@painter__.__send__ :begin_paint
|
127
|
+
end
|
128
|
+
|
129
|
+
# @private
|
130
|
+
def endDraw__()
|
131
|
+
@painter__.__send__ :end_paint
|
132
|
+
super
|
133
|
+
resizeCanvas__
|
134
|
+
end
|
135
|
+
|
136
|
+
# @private
|
137
|
+
def spriteWorld__()
|
138
|
+
@spriteWorld__ ||= SpriteWorld.new(pixelsPerMeter: 8)
|
139
|
+
end
|
140
|
+
|
141
|
+
# @private
|
142
|
+
def resizeCanvas__()
|
143
|
+
w, h = @resizeCanvas__ || return
|
144
|
+
@resizeCanvas__ = nil
|
145
|
+
updateCanvas__ Rays::Image.new(w.to_i, h.to_i)
|
146
|
+
|
147
|
+
rootw, rooth = @rootContext__.width, @rootContext__.height
|
148
|
+
if w == rootw && h == rooth
|
149
|
+
@canvasFrame__ = nil
|
150
|
+
else
|
151
|
+
wide = w.to_f / h >= rootw.to_f / rooth
|
152
|
+
canvasw = wide ? rootw : rooth * (w.to_f / h)
|
153
|
+
canvash = wide ? rootw * (h.to_f / w) : rooth
|
154
|
+
@canvasFrame__ = [
|
155
|
+
(rootw - canvasw) / 2,
|
156
|
+
(rooth - canvash) / 2,
|
157
|
+
canvasw,
|
158
|
+
canvash
|
159
|
+
].map(&:to_i)
|
160
|
+
end
|
161
|
+
|
162
|
+
spriteWorld__.zoom = wide ? rootw.to_f / w : rooth.to_f / h
|
163
|
+
end
|
164
|
+
|
165
|
+
# @private
|
166
|
+
attr_reader :canvasFrame__
|
167
|
+
|
168
|
+
end# Context
|
data/lib/reight/helpers.rb
CHANGED
@@ -33,8 +33,8 @@ module Reight::Hookable
|
|
33
33
|
@hookable_hooks ||= {}
|
34
34
|
(@hookable_hooks[name] ||= []).push block
|
35
35
|
end
|
36
|
-
singleton_class.__send__ :define_method, "#{name}!" do |*args|
|
37
|
-
@hookable_hooks&.[](name)&.each {
|
36
|
+
singleton_class.__send__ :define_method, "#{name}!" do |*args, &block|
|
37
|
+
@hookable_hooks&.[](name)&.each {_1.call(*args, &block)}
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
data/lib/reight/index.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
using Reight
|
2
|
+
|
3
|
+
|
4
|
+
class Reight::Index
|
5
|
+
|
6
|
+
include Reight::Activatable
|
7
|
+
include Reight::Hookable
|
8
|
+
include Reight::HasHelp
|
9
|
+
|
10
|
+
def initialize(index = 0, &changed)
|
11
|
+
super()
|
12
|
+
@index = index
|
13
|
+
|
14
|
+
hook :changed
|
15
|
+
self.changed(&changed) if changed
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :index
|
19
|
+
|
20
|
+
def draw()
|
21
|
+
sp = sprite
|
22
|
+
button_w, button_h = sp.h, sp.h
|
23
|
+
|
24
|
+
no_stroke
|
25
|
+
|
26
|
+
fill 230
|
27
|
+
if pressing? && prev?
|
28
|
+
rect 0, 0, sp.w / 2, button_h
|
29
|
+
elsif pressing? && next?
|
30
|
+
rect sp.w / 2, 0, sp.w / 2, button_h
|
31
|
+
end
|
32
|
+
|
33
|
+
fill 50
|
34
|
+
text_align CENTER, CENTER
|
35
|
+
text '<', 0, 0, button_w, button_h
|
36
|
+
text '>', sp.w - button_w, 0, button_w, button_h
|
37
|
+
text index, 0, 0, sp.w, sp.h
|
38
|
+
end
|
39
|
+
|
40
|
+
def prev? = sprite.mouse_x < sprite.w / 2
|
41
|
+
|
42
|
+
def next? = !prev?
|
43
|
+
|
44
|
+
def pressed(x, y)
|
45
|
+
@pressing = true
|
46
|
+
end
|
47
|
+
|
48
|
+
def released(x, y)
|
49
|
+
@pressing = false
|
50
|
+
end
|
51
|
+
|
52
|
+
def pressing? = @pressing
|
53
|
+
|
54
|
+
def hover(x, y)
|
55
|
+
r8.flash x < (sprite.w / 2) ? 'Prev' : 'Next'
|
56
|
+
end
|
57
|
+
|
58
|
+
def clicked()
|
59
|
+
old = @index
|
60
|
+
@index += 1 if next?
|
61
|
+
@index -= 1 if prev?
|
62
|
+
@index = 0 if @index < 0
|
63
|
+
changed! @index if @index != old
|
64
|
+
end
|
65
|
+
|
66
|
+
def sprite()
|
67
|
+
@sprite ||= RubySketch::Sprite.new(physics: false).tap do |sp|
|
68
|
+
sp.draw {draw}
|
69
|
+
sp.mouse_pressed {pressed sp.mouse_x, sp.mouse_y}
|
70
|
+
sp.mouse_released {released sp.mouse_x, sp.mouse_y}
|
71
|
+
sp.mouse_moved {hover sp.mouse_x, sp.mouse_y}
|
72
|
+
sp.mouse_clicked {clicked}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end# Index
|
data/lib/reight/map.rb
CHANGED
@@ -12,10 +12,32 @@ class Reight::Map
|
|
12
12
|
raise ArgumentError, "Invalid chunk_size: #{chunk_size}" if
|
13
13
|
chunk_size.to_i != chunk_size || chunk_size % chip_size != 0
|
14
14
|
|
15
|
-
@chip_size, @chunk_size = [chip_size, chunk_size].map
|
15
|
+
@chip_size, @chunk_size = [chip_size, chunk_size].map(&:to_i)
|
16
16
|
@chunks = {}
|
17
17
|
end
|
18
18
|
|
19
|
+
def activate(x, y, w, h, world = nil, &activated)
|
20
|
+
@sprites = nil if !activated && @sprites && @sprites.world != world
|
21
|
+
@sprites ||= SpriteArray.new(world: world) {|*a, &b| each_chunk(*a, &b)}
|
22
|
+
@sprites.activate(x, y, w, h, &activated)
|
23
|
+
@sprites
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_sprites()
|
27
|
+
map(&:to_sprite)
|
28
|
+
end
|
29
|
+
|
30
|
+
def sprites()
|
31
|
+
@sprites ||= SpriteArray.new(sprites: to_sprites)
|
32
|
+
end
|
33
|
+
|
34
|
+
alias sprites_at activate
|
35
|
+
|
36
|
+
def clear_sprites()
|
37
|
+
@chunks.each_value {_1&.clear_sprites}
|
38
|
+
@sprites = nil
|
39
|
+
end
|
40
|
+
|
19
41
|
def put(x, y, chip)
|
20
42
|
return unless chip
|
21
43
|
each_chunk x, y, chip.w, chip.h, create: true do |chunk|
|
@@ -23,16 +45,16 @@ class Reight::Map
|
|
23
45
|
end
|
24
46
|
end
|
25
47
|
|
26
|
-
def
|
48
|
+
def remove(x, y)
|
27
49
|
chip = self[x, y] or return
|
28
50
|
cx, cy, cw, ch = chip.then {[_1.pos.x, _1.pos.y, _1.w, _1.h]}
|
29
51
|
each_chunk cx, cy, cw, ch, create: false do |chunk|
|
30
|
-
each_chip_pos(cx, cy, cw, ch) {|xx, yy| chunk.
|
52
|
+
each_chip_pos(cx, cy, cw, ch) {|xx, yy| chunk.remove xx, yy}
|
31
53
|
end
|
32
54
|
end
|
33
55
|
|
34
|
-
def
|
35
|
-
|
56
|
+
def remove_chip(chip)
|
57
|
+
remove chip.pos.x, chip.pos.y
|
36
58
|
end
|
37
59
|
|
38
60
|
def each_chip(x = nil, y = nil, w = nil, h = nil, clip_by_chunk: false, &block)
|
@@ -62,18 +84,30 @@ class Reight::Map
|
|
62
84
|
chunk_at(x, y)&.[](x, y)
|
63
85
|
end
|
64
86
|
|
65
|
-
|
87
|
+
# @private
|
88
|
+
def cmp__(o)
|
66
89
|
a = [@chip_size, @chunk_size, @chunks]
|
67
90
|
b = o.instance_eval {[@chip_size, @chunk_size, @chunks]}
|
68
91
|
a <=> b
|
69
92
|
end
|
70
93
|
|
94
|
+
# @private
|
95
|
+
def drawSprite__(context)
|
96
|
+
if @sprites
|
97
|
+
@sprites.drawSprite__ context
|
98
|
+
else
|
99
|
+
@chunks.each_value {_1.drawSprite__ context}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
71
103
|
def self.restore(hash, source_chips)
|
72
|
-
hash
|
104
|
+
chip_size, chunk_size, chunks = hash.values_at :chip_size, :chunk_size, :chunks
|
105
|
+
#hash => {chip_size:, chunk_size:, chunks:}
|
73
106
|
new(chip_size: chip_size, chunk_size: chunk_size).tap do |obj|
|
74
107
|
obj.instance_eval do
|
75
108
|
@chunks = chunks.each.with_object({}) do |chunk_hash, result|
|
76
|
-
chunk_hash
|
109
|
+
x, y = chunk_hash.values_at :x, :y
|
110
|
+
#chunk_hash => {x:, y:}
|
77
111
|
result[[x, y]] = Chunk.restore chunk_hash, source_chips
|
78
112
|
end
|
79
113
|
end
|
@@ -135,8 +169,10 @@ class Reight::Map
|
|
135
169
|
end# Map
|
136
170
|
|
137
171
|
|
172
|
+
# @private
|
138
173
|
class Reight::Map::Chunk
|
139
174
|
|
175
|
+
include Enumerable
|
140
176
|
include Comparable
|
141
177
|
|
142
178
|
def initialize(x, y, w, h, chip_size: 8)
|
@@ -150,6 +186,16 @@ class Reight::Map::Chunk
|
|
150
186
|
|
151
187
|
attr_reader :x, :y, :w, :h
|
152
188
|
|
189
|
+
def sprites()
|
190
|
+
@sprites ||= map {|chip|
|
191
|
+
chip.to_sprite.tap {|sp| sp.map_chunk = self}
|
192
|
+
}
|
193
|
+
end
|
194
|
+
|
195
|
+
def clear_sprites()
|
196
|
+
@sprites = nil
|
197
|
+
end
|
198
|
+
|
153
199
|
def put(x, y, chip)
|
154
200
|
x, y = align_chip_pos x, y
|
155
201
|
raise "Invalid chip size" if
|
@@ -162,15 +208,17 @@ class Reight::Map::Chunk
|
|
162
208
|
each_chip_pos x, y, chip.w, chip.h do |xx, yy|
|
163
209
|
@chips[pos2index xx, yy] = get_chip.call
|
164
210
|
end
|
211
|
+
invalidate_cache__
|
165
212
|
end
|
166
213
|
|
167
|
-
def
|
214
|
+
def remove(x, y)
|
168
215
|
chip = self[x, y] or return
|
169
216
|
each_chip_pos chip.pos.x, chip.pos.y, chip.w, chip.h do |xx, yy|
|
170
217
|
index = pos2index xx, yy
|
171
218
|
@chips[index] = nil if @chips[index]&.id == chip.id
|
172
219
|
end
|
173
220
|
delete_last_nils
|
221
|
+
invalidate_cache__
|
174
222
|
end
|
175
223
|
|
176
224
|
def each_chip(x = nil, y = nil, w = nil, h = nil, include_hidden: false, &block)
|
@@ -201,6 +249,8 @@ class Reight::Map::Chunk
|
|
201
249
|
end
|
202
250
|
end
|
203
251
|
|
252
|
+
def each(&block) = each_chip {block.call _1}
|
253
|
+
|
204
254
|
def frame = [@x, @y, @w, @h]
|
205
255
|
|
206
256
|
def to_hash()
|
@@ -216,14 +266,40 @@ class Reight::Map::Chunk
|
|
216
266
|
@chips[index]
|
217
267
|
end
|
218
268
|
|
219
|
-
|
269
|
+
# @private
|
270
|
+
def cmp__(o)
|
220
271
|
a = [@x, @y, @w, @h, @chip_size, @chips]
|
221
272
|
b = o.instance_eval {[@x, @y, @w, @h, @chip_size, @chips]}
|
222
273
|
a <=> b
|
223
274
|
end
|
224
275
|
|
276
|
+
# @private
|
277
|
+
def invalidate_cache__()
|
278
|
+
@cached = false
|
279
|
+
end
|
280
|
+
|
281
|
+
# @private
|
282
|
+
def drawSprite__(context)
|
283
|
+
@cached ||= true.tap do
|
284
|
+
@cache ||= create_graphics @w, @h
|
285
|
+
@cache.begin_draw do |g|
|
286
|
+
g.background 0, 0
|
287
|
+
g.translate -@x, -@y
|
288
|
+
sprites.each {_1.drawSprite__ g}
|
289
|
+
end
|
290
|
+
end
|
291
|
+
context.image @cache, @x, @y
|
292
|
+
end
|
293
|
+
|
294
|
+
# @private
|
295
|
+
def delete_sprite__(sprite)
|
296
|
+
@sprites.delete sprite
|
297
|
+
invalidate_cache__
|
298
|
+
end
|
299
|
+
|
225
300
|
def self.restore(hash, source_chips)
|
226
|
-
hash
|
301
|
+
x, y, w, h, chip_size, chip_ids = hash.values_at :x, :y, :w, :h, :chip_size, :chips
|
302
|
+
#hash => {x:, y:, w:, h:, chip_size: chip_size, chips: chip_ids}
|
227
303
|
tmp_chips = {}
|
228
304
|
get_chip = -> id, x, y {
|
229
305
|
tmp_chips[[id, x, y]] ||= source_chips[id].with(pos: create_vector(x, y))
|
@@ -262,3 +338,47 @@ class Reight::Map::Chunk
|
|
262
338
|
end
|
263
339
|
|
264
340
|
end# Chunk
|
341
|
+
|
342
|
+
|
343
|
+
# @private
|
344
|
+
class Reight::Map::SpriteArray < Array
|
345
|
+
|
346
|
+
def initialize(world: nil, sprites: [], &each_chunk)
|
347
|
+
@world, @each_chunk = world, each_chunk
|
348
|
+
super(sprites)
|
349
|
+
end
|
350
|
+
|
351
|
+
attr_reader :world
|
352
|
+
|
353
|
+
def activate(x, y, w, h, &activated)
|
354
|
+
raise ArgumentError, "missing 'activated' block" if !@world && !activated
|
355
|
+
|
356
|
+
bounds, old_bounds = [x, y, w, h], @bounds
|
357
|
+
return if bounds == old_bounds
|
358
|
+
|
359
|
+
chunks, old_chunks = @each_chunk.call(x, y, w, h).to_a, @chunks || []
|
360
|
+
return if chunks == old_chunks
|
361
|
+
|
362
|
+
activateds, deactivateds = [chunks - old_chunks, old_chunks - chunks]
|
363
|
+
.map {|chunks| chunks.map(&:sprites).flatten.compact}
|
364
|
+
if activated
|
365
|
+
activated.call activateds, deactivateds
|
366
|
+
elsif @world
|
367
|
+
activateds.each {@world .add_sprite _1}
|
368
|
+
deactivateds.each {@world.remove_sprite _1}
|
369
|
+
end
|
370
|
+
|
371
|
+
@bounds, @chunks = bounds, chunks
|
372
|
+
clear.concat @chunks.map(&:sprites).flatten.compact
|
373
|
+
end
|
374
|
+
|
375
|
+
def delete(sprite)
|
376
|
+
sprite.map_chunk&.delete_sprite__ sprite
|
377
|
+
super
|
378
|
+
end
|
379
|
+
|
380
|
+
def drawSprite__(context)
|
381
|
+
(@chunks&.each || each).each {_1.drawSprite__ context}
|
382
|
+
end
|
383
|
+
|
384
|
+
end# SpriteArray
|
data/lib/reight/project.rb
CHANGED
@@ -3,6 +3,8 @@ using Reight
|
|
3
3
|
|
4
4
|
class Reight::Project
|
5
5
|
|
6
|
+
include Xot::Inspectable
|
7
|
+
|
6
8
|
def initialize(project_dir)
|
7
9
|
raise 'the project directory is required' unless project_dir
|
8
10
|
@project_dir = project_dir
|
@@ -17,7 +19,9 @@ class Reight::Project
|
|
17
19
|
def code_paths = settings[__method__]&.then {[_1].flatten} || ['game.rb']
|
18
20
|
|
19
21
|
def codes()
|
20
|
-
code_paths
|
22
|
+
code_paths
|
23
|
+
.map {File.expand_path _1, project_dir}
|
24
|
+
.map {File.read _1 rescue nil}
|
21
25
|
end
|
22
26
|
|
23
27
|
def chips_json_name = settings[__method__] || 'chips.json'
|
@@ -39,7 +43,7 @@ class Reight::Project
|
|
39
43
|
def chips_image()
|
40
44
|
@chips_image ||= -> {
|
41
45
|
create_graphics(chips_image_width, chips_image_height).tap do |g|
|
42
|
-
g.begin_draw {g.background 0, 0, 0}
|
46
|
+
g.begin_draw {g.background 0, 0, 0, 0}
|
43
47
|
img = load_image chips_image_path
|
44
48
|
g.begin_draw {g.image img, 0, 0}
|
45
49
|
rescue Rays::RaysError
|
@@ -55,19 +59,30 @@ class Reight::Project
|
|
55
59
|
@maps ||= load_maps
|
56
60
|
end
|
57
61
|
|
62
|
+
def sounds_json_name = settings[__method__] || 'sounds.json'
|
63
|
+
|
64
|
+
def sounds_json_path = "#{project_dir}/#{sounds_json_name}"
|
65
|
+
|
66
|
+
def sounds()
|
67
|
+
@sounds ||= load_sounds
|
68
|
+
end
|
69
|
+
|
58
70
|
def font = @font ||= create_font(nil, font_size)
|
59
71
|
|
60
72
|
def font_size = 8
|
61
73
|
|
62
|
-
def palette_colors =
|
63
|
-
|
64
|
-
|
65
|
-
|
74
|
+
def palette_colors = Reight::App::PALETTE_COLORS.dup
|
75
|
+
|
76
|
+
def clear_all_sprites()
|
77
|
+
chips.each(&:clear_sprite)
|
78
|
+
maps.each(&:clear_sprites)
|
79
|
+
end
|
66
80
|
|
67
81
|
def save()
|
68
82
|
File.write project_path, to_json_string(@settings)
|
69
83
|
save_chips
|
70
84
|
save_maps
|
85
|
+
save_sounds
|
71
86
|
end
|
72
87
|
|
73
88
|
private
|
@@ -104,6 +119,19 @@ class Reight::Project
|
|
104
119
|
end
|
105
120
|
end
|
106
121
|
|
122
|
+
def save_sounds()
|
123
|
+
File.write sounds_json_path, to_json_string(sounds.map {_1.to_hash})
|
124
|
+
end
|
125
|
+
|
126
|
+
def load_sounds()
|
127
|
+
if File.file? sounds_json_path
|
128
|
+
json = JSON.parse File.read(sounds_json_path), symbolize_names: true
|
129
|
+
json.map {Reight::Sound.restore _1}
|
130
|
+
else
|
131
|
+
[Reight::Sound.new]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
107
135
|
def to_json_string(obj, readable: true)
|
108
136
|
if readable
|
109
137
|
JSON.pretty_generate obj
|
data/lib/reight/reight.rb
CHANGED
@@ -26,8 +26,7 @@ class Reight::R8
|
|
26
26
|
Reight::Runner.new(project),
|
27
27
|
Reight::SpriteEditor.new(project),
|
28
28
|
Reight::MapEditor.new(project),
|
29
|
-
Reight::SoundEditor.new(project)
|
30
|
-
Reight::MusicEditor.new(project)
|
29
|
+
Reight::SoundEditor.new(project)
|
31
30
|
]
|
32
31
|
end
|
33
32
|
|
@@ -43,7 +42,6 @@ class Reight::R8
|
|
43
42
|
end
|
44
43
|
|
45
44
|
def current=(app)
|
46
|
-
return if app == @current
|
47
45
|
@current&.deactivated
|
48
46
|
@current = app
|
49
47
|
@current.activated
|