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.



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
58
59
# File 'lib/smalruby/character.rb', line 23

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 = []
  @angle = 0 unless Util.windows?

  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

#angleObject

Returns the value of attribute angle.



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

def angle
  @angle
end

#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)


338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/smalruby/character.rb', line 338

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

#button(pin) ⇒ Object

ボタン



224
225
226
# File 'lib/smalruby/character.rb', line 224

def button(pin)
  Hardware.create_hardware(Hardware::Button, pin)
end

#button_down(pin) ⇒ Object



331
332
333
334
335
336
# File 'lib/smalruby/character.rb', line 331

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

#button_up(pin) ⇒ Object



324
325
326
327
328
329
# File 'lib/smalruby/character.rb', line 324

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

#click(buttons) ⇒ Object



295
296
297
298
299
300
301
302
# File 'lib/smalruby/character.rb', line 295

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

距離



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

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

#drawObject



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/smalruby/character.rb', line 235

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



304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/smalruby/character.rb', line 304

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

#hit?(other) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/smalruby/character.rb', line 175

def hit?(other)
  check([other]).length > 0
end

#joinObject



355
356
357
# File 'lib/smalruby/character.rb', line 355

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

#key_down(keys) ⇒ Object



277
278
279
280
281
282
283
284
# File 'lib/smalruby/character.rb', line 277

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



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

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



199
200
201
# File 'lib/smalruby/character.rb', line 199

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

#loop(&block) ⇒ Object



359
360
361
362
363
364
# File 'lib/smalruby/character.rb', line 359

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

#move(val = 1) ⇒ Object

( )歩動かす



64
65
66
67
# File 'lib/smalruby/character.rb', line 64

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

#move_back(val = 1) ⇒ Object

( )歩後ろに動かす



70
71
72
# File 'lib/smalruby/character.rb', line 70

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

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



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/smalruby/character.rb', line 251

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)
  when :button_up, :button_down
    button(options.first)
  end
end

#play(option = {}) ⇒ Object



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

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

#point_towards(target) ⇒ Object

( )に向ける



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/smalruby/character.rb', line 101

def point_towards(target)
  if target == :mouse
    tx = Input.mouse_pos_x
    ty = Input.mouse_pos_y
  else
    tx = target.x
    ty = target.y
  end
  dx = tx - x
  dy = ty - y
  self.angle = Math.atan2(dy, dx) * 180 / Math::PI
end

#reach_wall?Boolean

端に着いた

Returns:

  • (Boolean)


170
171
172
173
# File 'lib/smalruby/character.rb', line 170

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(アノード)



204
205
206
# File 'lib/smalruby/character.rb', line 204

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

#rgb_led_cathode(pin) ⇒ Object

RGB LED(カソード)



209
210
211
# File 'lib/smalruby/character.rb', line 209

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

#rotate(angle) ⇒ Object

( )度回転する



87
88
89
# File 'lib/smalruby/character.rb', line 87

def rotate(angle)
  self.angle += angle
end

#say(options = {}) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/smalruby/character.rb', line 118

def say(options = {})
  defaults = {
    message: '',
    second: 0,
  }
  opts = process_optional_arguments(options, defaults)

  if @balloon
    @balloon.vanish
    @balloon = nil
  end

  message = opts[:message].to_s
  return if message.empty?

  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])
  lines.each.with_index do |line, row|
    image.draw_font(frame_size + margin_size,
                    frame_size + margin_size + (font.size + 1) * row,
                    line, font, [0, 0, 0])
  end
  @balloon = Sprite.new(self.x, self.y, image)
end

#sensor(pin) ⇒ Object

汎用的なセンサー



229
230
231
# File 'lib/smalruby/character.rb', line 229

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

#sensor_change(pin, value) ⇒ Object



317
318
319
320
321
322
# File 'lib/smalruby/character.rb', line 317

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

#servo(pin) ⇒ Object

サーボモーター



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

def servo(pin)
  Hardware.create_hardware(Hardware::Servo, pin)
end

#startObject



271
272
273
274
275
# File 'lib/smalruby/character.rb', line 271

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

#turnObject

振り返る



75
76
77
78
79
# File 'lib/smalruby/character.rb', line 75

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

#turn_if_reach_wallObject

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



82
83
84
# File 'lib/smalruby/character.rb', line 82

def turn_if_reach_wall
  turn if reach_wall?
end

#two_wheel_drive_car(pin) ⇒ Object

2WD車



219
220
221
# File 'lib/smalruby/character.rb', line 219

def two_wheel_drive_car(pin)
  Hardware.create_hardware(Hardware::TwoWheelDriveCar, pin)
end