Class: Smalruby::Character

Inherits:
Sprite
  • Object
show all
Extended by:
Forwardable, Mutex_m
Defined in:
lib/smalruby/character.rb

Overview

キャラクターを表現するクラス

Direct Known Subclasses

Canvas, Console

Instance Attribute Summary collapse

動き collapse

見た目 collapse

調べる collapse

collapse

ハードウェア collapse

Instance Method Summary collapse

Constructor Details

#initialize(option = {}) ⇒ Character

Returns a new instance of Character.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/smalruby/character.rb', line 22

def initialize(option = {})
  defaults = {
    x: 0,
    y: 0,
    costume: nil,
    angle: 0,
    visible: true
  }
  opt = process_optional_arguments(option, defaults)

  # TODO: コスチュームの配列に対応する
  if opt[:costume].is_a?(String)
    opt[:costume] = Image.load(asset_path(opt[:costume]))
  end
  super(opt[:x], opt[:y], opt[:costume])

  @event_handlers = {}
  @threads = []
  @checking_hit_targets = []

  self.scale_x = 1.0
  self.scale_y = 1.0
  @vector = { x: 1, y: 0 }

  [:visible].each do |k|
    if opt.key?(k)
      send("#{k}=", opt[k])
    end
  end

  if opt[:angle] != 0
    rotate(opt[:angle])
  end

  World.instance.objects << self
end

Instance Attribute Details

#checking_hit_targetsObject

Returns the value of attribute checking_hit_targets.



20
21
22
# File 'lib/smalruby/character.rb', line 20

def checking_hit_targets
  @checking_hit_targets
end

#event_handlersObject

Returns the value of attribute event_handlers.



18
19
20
# File 'lib/smalruby/character.rb', line 18

def event_handlers
  @event_handlers
end

#threadsObject

Returns the value of attribute threads.



19
20
21
# File 'lib/smalruby/character.rb', line 19

def threads
  @threads
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/smalruby/character.rb', line 266

def alive?
  @threads.delete_if { |t|
    if t.alive?
      false
    else
      begin
        t.join
      rescue => e
        Util.print_exception(e)
        exit(1)
      end
      true
    end
  }
  @threads.length > 0
end

#click(buttons) ⇒ Object



237
238
239
240
241
242
243
244
# File 'lib/smalruby/character.rb', line 237

def click(buttons)
  @event_handlers[:click].try(:each) do |h|
    if h.options.length > 0 && !h.options.any? { |b| buttons.include?(b) }
      next
    end
    @threads << h.call(Input.mouse_pos_x, Input.mouse_pos_y)
  end
end

#distance(x, y) ⇒ Object

距離



127
128
129
130
# File 'lib/smalruby/character.rb', line 127

def distance(x, y)
  Math.sqrt((self.x + center_x - x).abs**2 +
            (self.y + center_y - y).abs**2).to_i
end

#drawObject



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/smalruby/character.rb', line 179

def draw
  draw_balloon

  if self.x < 0
    self.x = 0
  elsif self.x + image.width >= Window.width
    self.x = Window.width - image.width
  end
  if self.y < 0
    self.y = 0
  elsif self.y + image.height >= Window.height
    self.y = Window.height - image.height
  end
  super
end

#hitObject



246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/smalruby/character.rb', line 246

def hit
  # TODO: なんでもいいからキャラクターに当たった場合に対応する
  @checking_hit_targets &= World.instance.objects
  objects = check(@checking_hit_targets)
  return if objects.empty?
  @event_handlers[:hit].try(:each) do |h|
    if h.options.length > 0 && !h.options.any? { |o| objects.include?(o) }
      next
    end
    @threads << h.call(h.options & objects)
  end
end

#joinObject



283
284
285
# File 'lib/smalruby/character.rb', line 283

def join
  @threads.each(&:join)
end

#key_down(keys) ⇒ Object



219
220
221
222
223
224
225
226
# File 'lib/smalruby/character.rb', line 219

def key_down(keys)
  @event_handlers[:key_down].try(:each) do |h|
    if h.options.length > 0 && !h.options.any? { |k| keys.include?(k) }
      next
    end
    @threads << h.call
  end
end

#key_push(keys) ⇒ Object



228
229
230
231
232
233
234
235
# File 'lib/smalruby/character.rb', line 228

def key_push(keys)
  @event_handlers[:key_push].try(:each) do |h|
    if h.options.length > 0 && !h.options.any? { |k| keys.include?(k) }
      next
    end
    @threads << h.call
  end
end

#led(pin) ⇒ Object

LED



158
159
160
# File 'lib/smalruby/character.rb', line 158

def led(pin)
  Hardware.create_hardware(Hardware::Led, pin)
end

#loop(&block) ⇒ Object



287
288
289
290
291
292
# File 'lib/smalruby/character.rb', line 287

def loop(&block)
  Kernel.loop do
    yield
    Smalruby.await
  end
end

#move(val = 1) ⇒ Object

( )歩動かす



62
63
64
65
# File 'lib/smalruby/character.rb', line 62

def move(val = 1)
  self.x += @vector[:x] * val
  self.y += @vector[:y] * val
end

#move_back(val = 1) ⇒ Object

( )歩後ろに動かす



68
69
70
# File 'lib/smalruby/character.rb', line 68

def move_back(val = 1)
  move(-val)
end

#on(event, *options, &block) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/smalruby/character.rb', line 195

def on(event, *options, &block)
  event = event.to_sym
  @event_handlers[event] ||= []
  h = EventHandler.new(self, options, &block)
  @event_handlers[event] << h

  case event
  when :start
    @threads << h.call if Smalruby.started?
  when :hit
    @checking_hit_targets << options
    @checking_hit_targets.flatten!
    @checking_hit_targets.uniq!
  when :sensor_change
    sensor(options.first)
  end
end

#play(option = {}) ⇒ Object



142
143
144
145
146
147
148
149
150
151
# File 'lib/smalruby/character.rb', line 142

def play(option = {})
  defaults = {
    name: 'piano_do.wav'
  }
  opt = process_optional_arguments(option, defaults)

  @sound_cache ||= {}
  (@sound_cache[opt[:name]] ||= Sound.new(asset_path(opt[:name])))
    .play
end

#reach_wall?Boolean

端に着いた

Returns:

  • (Boolean)


133
134
135
136
# File 'lib/smalruby/character.rb', line 133

def reach_wall?
  self.x < 0 || self.x >= (Window.width - image.width) ||
    self.y < 0 || self.y >= (Window.height - image.height)
end

#rgb_led_anode(pin) ⇒ Object

RGB LED(アノード)



163
164
165
# File 'lib/smalruby/character.rb', line 163

def rgb_led_anode(pin)
  Hardware.create_hardware(Hardware::RgbLedAnode, pin)
end

#rgb_led_cathode(pin) ⇒ Object

RGB LED(カソード)



168
169
170
# File 'lib/smalruby/character.rb', line 168

def rgb_led_cathode(pin)
  Hardware.create_hardware(Hardware::RgbLedCathode, pin)
end

#rotate(angle) ⇒ Object

( )度回転する



85
86
87
88
89
90
91
# File 'lib/smalruby/character.rb', line 85

def rotate(angle)
  radian = angle * Math::PI / 180
  x, y = @vector[:x], @vector[:y]
  @vector[:x] = x * Math.cos(radian) - y * Math.sin(radian)
  @vector[:y] = x * Math.sin(radian) + y * Math.cos(radian)
  self.angle = (self.angle + angle) % 360
end

#say(message) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/smalruby/character.rb', line 97

def say(message)
  lines = message.to_s.lines.map { |l| l.scan(/.{1,10}/) }.flatten
  font = new_font(16)
  width = lines.map { |l| font.get_width(l) }.max
  height = lines.length * (font.size + 1)
  frame_size = 3
  margin_size = 3
  image = Image.new(width + (frame_size + margin_size) * 2,
                    height + (frame_size + margin_size) * 2)
  image.box_fill(0,
                 0,
                 width + (frame_size + margin_size) * 2 - 1,
                 height + (frame_size + margin_size) * 2 - 1,
                 [125, 125, 125])
  image.box_fill(frame_size,
                 frame_size,
                 width + (frame_size + margin_size) + margin_size - 1,
                 height + (frame_size + margin_size) + margin_size - 1,
                 [255, 255, 255])
  image.draw_font(frame_size + margin_size,
                  frame_size + margin_size,
                  lines.join("\n"), font, [0, 0, 0])
  @balloon = Sprite.new(self.x, self.y, image)
end

#sensor(pin) ⇒ Object

汎用的なセンサー



173
174
175
# File 'lib/smalruby/character.rb', line 173

def sensor(pin)
  Hardware.create_hardware(Hardware::Sensor, pin)
end

#sensor_change(pin, value) ⇒ Object



259
260
261
262
263
264
# File 'lib/smalruby/character.rb', line 259

def sensor_change(pin, value)
  @event_handlers[:sensor_change].try(:each) do |h|
    next unless h.options.include?(pin)
    @threads << h.call(value)
  end
end

#startObject



213
214
215
216
217
# File 'lib/smalruby/character.rb', line 213

def start
  @event_handlers[:start].try(:each) do |h|
    @threads << h.call
  end
end

#turnObject

振り返る



73
74
75
76
77
# File 'lib/smalruby/character.rb', line 73

def turn
  @vector[:x] *= -1
  @vector[:y] *= -1
  self.scale_x *= -1
end

#turn_if_reach_wallObject

もし端に着いたら、跳ね返る



80
81
82
# File 'lib/smalruby/character.rb', line 80

def turn_if_reach_wall
  turn if reach_wall?
end