Class: Smalruby::Character
- Inherits:
-
Sprite
- Object
- Sprite
- Smalruby::Character
- Extended by:
- Forwardable, Mutex_m
- Defined in:
- lib/smalruby/character.rb
Overview
キャラクターを表現するクラス
Instance Attribute Summary collapse
-
#checking_hit_targets ⇒ Object
Returns the value of attribute checking_hit_targets.
-
#costume_index ⇒ Object
Returns the value of attribute costume_index.
-
#costumes ⇒ Object
Returns the value of attribute costumes.
-
#enable_pen ⇒ Object
readonly
Returns the value of attribute enable_pen.
-
#event_handlers ⇒ Object
Returns the value of attribute event_handlers.
-
#pen_color ⇒ Object
Returns the value of attribute pen_color.
-
#rotation_style ⇒ Object
Returns the value of attribute rotation_style.
-
#threads ⇒ Object
Returns the value of attribute threads.
-
#volume ⇒ Object
Returns the value of attribute volume.
動き collapse
-
#angle ⇒ Object
角度.
-
#angle=(val) ⇒ Object
( )度に向ける.
-
#go_to(target) ⇒ Object
( )に行く.
-
#move(val = 1) ⇒ Object
( )歩動かす.
-
#move_back(val = 1) ⇒ Object
( )歩後ろに動かす.
-
#point_towards(target) ⇒ Object
( )に向ける.
-
#position ⇒ Object
X座標、Y座標.
-
#position=(val) ⇒ Object
X座標を( )、Y座標を( )にする.
-
#rotate(angle) ⇒ Object
( )度回転する.
-
#turn ⇒ Object
くるっと振り返る.
-
#turn_if_reach_wall ⇒ Object
もし端に着いたら、跳ね返る.
-
#turn_x ⇒ Object
横に振り返る.
-
#turn_y ⇒ Object
縦に振り返る.
-
#x=(val) ⇒ Object
X座標を( )にする.
-
#y=(val) ⇒ Object
Y座標を( )にする.
見た目 collapse
-
#next_costume ⇒ Object
次のコスチュームにする.
- #say(options = {}) ⇒ Object
-
#switch_costume(name) ⇒ Object
コスチュームを( )にする.
-
#visible=(val) ⇒ Object
表示する/隠す.
調べる collapse
-
#distance(x, y) ⇒ Object
距離.
- #hit?(other) ⇒ Boolean
-
#reach_left_or_right_wall? ⇒ Boolean
左右の端に着いた?.
-
#reach_top_or_bottom_wall? ⇒ Boolean
上下の端に着いた?.
-
#reach_wall? ⇒ Boolean
端に着いた?.
音 collapse
-
#play(option = {}) ⇒ Object
( )の音を鳴らす.
ペン collapse
-
#change_pen_color_by(val) ⇒ Object
change pen color.
-
#clear ⇒ Object
Clears all pen marks from the Stage.
-
#down_pen ⇒ Object
ペンを下ろす.
-
#pen_shade=(val) ⇒ Object
set pen shade.
-
#up_pen ⇒ Object
ペンを上げる.
ハードウェア collapse
-
#button(pin) ⇒ Object
ボタン.
-
#led(pin) ⇒ Object
LED.
-
#motor_driver(pin) ⇒ Object
モータードライバ.
-
#neo_pixel(pin) ⇒ Object
マイコン内蔵RGB LED.
-
#rgb_led_anode(pin) ⇒ Object
RGB LED(アノード).
-
#rgb_led_cathode(pin) ⇒ Object
RGB LED(カソード).
-
#sensor(pin) ⇒ Object
汎用的なセンサー.
-
#servo(pin) ⇒ Object
サーボモーター.
-
#smalrubot_s1 ⇒ Object
create or get Hardware::SmalrubotS1 instance.
-
#smalrubot_v3 ⇒ Object
create or get Hardware::SmalrubotV3 instance.
-
#two_wheel_drive_car(pin) ⇒ Object
2WD車.
Instance Method Summary collapse
- #alive? ⇒ Boolean
-
#await ⇒ Object
1フレーム待つ.
- #click(buttons) ⇒ Object
- #draw ⇒ Object
- #hit ⇒ Object
-
#initialize(option = {}) ⇒ Character
constructor
A new instance of Character.
- #join ⇒ Object
- #key_down(keys) ⇒ Object
- #key_push(keys) ⇒ Object
- #loop ⇒ Object
- #on(event, *options, &block) ⇒ Object
- #start ⇒ Object
Constructor Details
#initialize(option = {}) ⇒ Character
Returns a new instance of Character.
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/smalruby/character.rb', line 32 def initialize(option = {}) defaults = { x: 0, y: 0, costume: nil, costume_index: 0, angle: 0, visible: true, rotation_style: :free } opt = process_optional_arguments(option, defaults) @costume_name__index = {} @costumes = Array.wrap(opt[:costume]).compact.map.with_index { |costume, i| if costume.is_a?(String) md = /^(?:([^:]+):)?(.*)$/.match(costume) name = md[1] path = md[2] costume = Image.load(asset_path(path)) end name ||= "costume#{i + 1}" @costume_name__index[name] = i costume } @costume_index = opt[:costume_index] super(opt[:x], opt[:y], @costumes[@costume_index]) @event_handlers = {} @threads = [] @checking_hit_targets = [] @angle = 0 unless Util.windows? @enable_pen = false @pen_color = 'black' @volume = 100 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 self.rotation_style = opt[:rotation_style] self.angle = opt[:angle] if opt[:angle] != 0 # HACK: Windows XP SP3の環境でワーカースレッドで音声を読み込めな # い不具合が発生した。このためメインスレッドでプリロードしておく。 %w(do re mi fa so ra si do_2).each do |n| new_sound("piano_#{n}.wav") end World.instance.objects << self end |
Instance Attribute Details
#checking_hit_targets ⇒ Object
Returns the value of attribute checking_hit_targets.
24 25 26 |
# File 'lib/smalruby/character.rb', line 24 def checking_hit_targets @checking_hit_targets end |
#costume_index ⇒ Object
Returns the value of attribute costume_index.
26 27 28 |
# File 'lib/smalruby/character.rb', line 26 def costume_index @costume_index end |
#costumes ⇒ Object
Returns the value of attribute costumes.
25 26 27 |
# File 'lib/smalruby/character.rb', line 25 def costumes @costumes end |
#enable_pen ⇒ Object (readonly)
Returns the value of attribute enable_pen.
28 29 30 |
# File 'lib/smalruby/character.rb', line 28 def enable_pen @enable_pen end |
#event_handlers ⇒ Object
Returns the value of attribute event_handlers.
22 23 24 |
# File 'lib/smalruby/character.rb', line 22 def event_handlers @event_handlers end |
#pen_color ⇒ Object
Returns the value of attribute pen_color.
29 30 31 |
# File 'lib/smalruby/character.rb', line 29 def pen_color @pen_color end |
#rotation_style ⇒ Object
Returns the value of attribute rotation_style.
27 28 29 |
# File 'lib/smalruby/character.rb', line 27 def rotation_style @rotation_style end |
#threads ⇒ Object
Returns the value of attribute threads.
23 24 25 |
# File 'lib/smalruby/character.rb', line 23 def threads @threads end |
#volume ⇒ Object
Returns the value of attribute volume.
30 31 32 |
# File 'lib/smalruby/character.rb', line 30 def volume @volume end |
Instance Method Details
#alive? ⇒ Boolean
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
# File 'lib/smalruby/character.rb', line 555 def alive? @threads.compact! @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 |
#angle ⇒ Object
角度
193 194 195 196 197 198 199 200 |
# File 'lib/smalruby/character.rb', line 193 def angle return super if @rotation_style == :free x, y = @vector[:x], @vector[:y] a = Math.acos(x / Math.sqrt(x**2 + y**2)) * 180 / Math::PI a = 360 - a if y < 0 a end |
#angle=(val) ⇒ Object
( )度に向ける
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/smalruby/character.rb', line 203 def angle=(val) val %= 360 radian = val * Math::PI / 180 @vector[:x] = Math.cos(radian) @vector[:y] = Math.sin(radian) if @rotation_style == :free self.scale_x = scale_x.abs super(val) elsif @rotation_style == :left_right if @vector[:x] >= 0 self.scale_x = scale_x.abs else self.scale_x = scale_x.abs * -1 end super(0) else self.scale_x = scale_x.abs super(0) end end |
#await ⇒ Object
1フレーム待つ
586 587 588 |
# File 'lib/smalruby/character.rb', line 586 def await Smalruby.await end |
#button(pin) ⇒ Object
ボタン
466 467 468 |
# File 'lib/smalruby/character.rb', line 466 def (pin) Hardware.create_hardware(Hardware::Button, pin) end |
#change_pen_color_by(val) ⇒ Object
change pen color
412 413 414 415 |
# File 'lib/smalruby/character.rb', line 412 def change_pen_color_by(val) h, s, l = Color.rgb_to_hsl(*pen_color) @pen_color = Color.hsl_to_rgb(h + val, s, l) end |
#clear ⇒ Object
Clears all pen marks from the Stage
380 381 382 |
# File 'lib/smalruby/character.rb', line 380 def clear world.current_stage.clear end |
#click(buttons) ⇒ Object
533 534 535 536 537 538 539 540 |
# File 'lib/smalruby/character.rb', line 533 def click() @event_handlers[:click].try(:each) do |h| if h..length > 0 && !h..any? { |b| .include?(b) } next end @threads << h.call(Input.mouse_pos_x, Input.mouse_pos_y) end end |
#distance(x, y) ⇒ Object
距離
335 336 337 338 |
# File 'lib/smalruby/character.rb', line 335 def distance(x, y) Math.sqrt((self.x + center_x - x).abs**2 + (self.y + center_y - y).abs**2).to_i end |
#down_pen ⇒ Object
ペンを下ろす
385 386 387 |
# File 'lib/smalruby/character.rb', line 385 def down_pen @enable_pen = true end |
#draw ⇒ Object
487 488 489 490 491 |
# File 'lib/smalruby/character.rb', line 487 def draw draw_balloon if visible super end |
#go_to(target) ⇒ Object
( )に行く
240 241 242 243 244 245 246 247 248 249 |
# File 'lib/smalruby/character.rb', line 240 def go_to(target) if target == :mouse x = Input.mouse_pos_x - center_x y = Input.mouse_pos_y - center_y else x = target.x y = target.y end self.position = [x, y] end |
#hit ⇒ Object
542 543 544 545 546 547 548 549 550 551 552 553 |
# File 'lib/smalruby/character.rb', line 542 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..length > 0 && !h..any? { |o| objects.include?(o) } next end @threads << h.call(h. & objects) end end |
#hit?(other) ⇒ Boolean
355 356 357 |
# File 'lib/smalruby/character.rb', line 355 def hit?(other) check([other]).length > 0 end |
#join ⇒ Object
573 574 575 576 |
# File 'lib/smalruby/character.rb', line 573 def join @threads.compact! @threads.each(&:join) end |
#key_down(keys) ⇒ Object
515 516 517 518 519 520 521 522 |
# File 'lib/smalruby/character.rb', line 515 def key_down(keys) @event_handlers[:key_down].try(:each) do |h| if h..length > 0 && !h..any? { |k| keys.include?(k) } next end @threads << h.call end end |
#key_push(keys) ⇒ Object
524 525 526 527 528 529 530 531 |
# File 'lib/smalruby/character.rb', line 524 def key_push(keys) @event_handlers[:key_push].try(:each) do |h| if h..length > 0 && !h..any? { |k| keys.include?(k) } next end @threads << h.call end end |
#led(pin) ⇒ Object
LED
431 432 433 |
# File 'lib/smalruby/character.rb', line 431 def led(pin) Hardware.create_hardware(Hardware::Led, pin) end |
#loop ⇒ Object
578 579 580 581 582 583 |
# File 'lib/smalruby/character.rb', line 578 def loop Kernel.loop do yield Smalruby.await end end |
#motor_driver(pin) ⇒ Object
モータードライバ
461 462 463 |
# File 'lib/smalruby/character.rb', line 461 def motor_driver(pin) Hardware.create_hardware(Hardware::MotorDriver, pin) end |
#move(val = 1) ⇒ Object
( )歩動かす
93 94 95 |
# File 'lib/smalruby/character.rb', line 93 def move(val = 1) self.position = [x + @vector[:x] * val, y + @vector[:y] * val] end |
#move_back(val = 1) ⇒ Object
( )歩後ろに動かす
98 99 100 |
# File 'lib/smalruby/character.rb', line 98 def move_back(val = 1) move(-val) end |
#neo_pixel(pin) ⇒ Object
マイコン内蔵RGB LED
446 447 448 |
# File 'lib/smalruby/character.rb', line 446 def neo_pixel(pin) Hardware.create_hardware(Hardware::NeoPixel, pin) end |
#next_costume ⇒ Object
次のコスチュームにする
311 312 313 |
# File 'lib/smalruby/character.rb', line 311 def next_costume self.costume_index = @costume_index + 1 end |
#on(event, *options, &block) ⇒ Object
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 |
# File 'lib/smalruby/character.rb', line 493 def on(event, *, &block) event = event.to_sym @event_handlers[event] ||= [] h = EventHandler.new(self, , &block) @event_handlers[event] << h case event when :start @threads << h.call if Smalruby.started? when :hit @checking_hit_targets << @checking_hit_targets.flatten! @checking_hit_targets.uniq! end end |
#pen_shade=(val) ⇒ Object
set pen shade
420 421 422 423 424 |
# File 'lib/smalruby/character.rb', line 420 def pen_shade=(val) val %= 101 h, s, = *Color.rgb_to_hsl(*pen_color) @pen_color = Color.hsl_to_rgb(h, s, val) end |
#play(option = {}) ⇒ Object
( )の音を鳴らす
364 365 366 367 368 369 370 371 372 373 |
# File 'lib/smalruby/character.rb', line 364 def play(option = {}) defaults = { name: 'piano_do.wav' } opt = process_optional_arguments(option, defaults) sound = new_sound(opt[:name]) sound.set_volume(calc_volume) sound.play end |
#point_towards(target) ⇒ Object
( )に向ける
226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/smalruby/character.rb', line 226 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 |
#position ⇒ Object
X座標、Y座標
150 151 152 |
# File 'lib/smalruby/character.rb', line 150 def position [x, y] end |
#position=(val) ⇒ Object
X座標を( )、Y座標を( )にする
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/smalruby/character.rb', line 134 def position=(val) if @enable_pen @enable_pen = false left = x + center_x top = y + center_y self.x = val[0] self.y = val[1] draw_pen(left, top, x + center_x, y + center_y) @enable_pen = true else self.x = val[0] self.y = val[1] end end |
#reach_left_or_right_wall? ⇒ Boolean
左右の端に着いた?
346 347 348 |
# File 'lib/smalruby/character.rb', line 346 def reach_left_or_right_wall? x <= 0 || x >= (Window.width - image.width) end |
#reach_top_or_bottom_wall? ⇒ Boolean
上下の端に着いた?
351 352 353 |
# File 'lib/smalruby/character.rb', line 351 def reach_top_or_bottom_wall? y <= 0 || y >= (Window.height - image.height) end |
#reach_wall? ⇒ Boolean
端に着いた?
341 342 343 |
# File 'lib/smalruby/character.rb', line 341 def reach_wall? reach_left_or_right_wall? || reach_top_or_bottom_wall? end |
#rgb_led_anode(pin) ⇒ Object
RGB LED(アノード)
436 437 438 |
# File 'lib/smalruby/character.rb', line 436 def rgb_led_anode(pin) Hardware.create_hardware(Hardware::RgbLedAnode, pin) end |
#rgb_led_cathode(pin) ⇒ Object
RGB LED(カソード)
441 442 443 |
# File 'lib/smalruby/character.rb', line 441 def rgb_led_cathode(pin) Hardware.create_hardware(Hardware::RgbLedCathode, pin) end |
#rotate(angle) ⇒ Object
( )度回転する
183 184 185 |
# File 'lib/smalruby/character.rb', line 183 def rotate(angle) self.angle += angle end |
#say(options = {}) ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/smalruby/character.rb', line 255 def say( = {}) defaults = { message: '', second: 0, } opts = process_optional_arguments(, defaults) = opts[:message].to_s return if == @current_message @current_message = if @balloon @balloon.vanish @balloon = nil end return if .empty? lines = .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(x, y, image) end |
#sensor(pin) ⇒ Object
汎用的なセンサー
471 472 473 |
# File 'lib/smalruby/character.rb', line 471 def sensor(pin) Hardware.create_hardware(Hardware::Sensor, pin) end |
#servo(pin) ⇒ Object
サーボモーター
451 452 453 |
# File 'lib/smalruby/character.rb', line 451 def servo(pin) Hardware.create_hardware(Hardware::Servo, pin) end |
#smalrubot_s1 ⇒ Object
create or get Hardware::SmalrubotS1 instance
481 482 483 |
# File 'lib/smalruby/character.rb', line 481 def smalrubot_s1 Hardware.create_hardware(Hardware::SmalrubotS1) end |
#smalrubot_v3 ⇒ Object
create or get Hardware::SmalrubotV3 instance
476 477 478 |
# File 'lib/smalruby/character.rb', line 476 def smalrubot_v3 Hardware.create_hardware(Hardware::SmalrubotV3) end |
#start ⇒ Object
509 510 511 512 513 |
# File 'lib/smalruby/character.rb', line 509 def start @event_handlers[:start].try(:each) do |h| @threads << h.call end end |
#switch_costume(name) ⇒ Object
コスチュームを( )にする
316 317 318 319 320 321 322 323 |
# File 'lib/smalruby/character.rb', line 316 def switch_costume(name) if @costume_name__index.key?(name) index = @costume_name__index[name] else index = 0 end self.costume_index = index end |
#turn ⇒ Object
くるっと振り返る
155 156 157 |
# File 'lib/smalruby/character.rb', line 155 def turn sync_angle(@vector[:x] * -1, @vector[:y] * -1) end |
#turn_if_reach_wall ⇒ Object
もし端に着いたら、跳ね返る
170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/smalruby/character.rb', line 170 def turn_if_reach_wall lr = reach_left_or_right_wall? tb = reach_top_or_bottom_wall? if lr && tb turn elsif lr turn_x elsif tb turn_y end end |
#turn_x ⇒ Object
横に振り返る
160 161 162 |
# File 'lib/smalruby/character.rb', line 160 def turn_x sync_angle(@vector[:x] * -1, @vector[:y]) end |
#turn_y ⇒ Object
縦に振り返る
165 166 167 |
# File 'lib/smalruby/character.rb', line 165 def turn_y sync_angle(@vector[:x], @vector[:y] * -1) end |
#two_wheel_drive_car(pin) ⇒ Object
2WD車
456 457 458 |
# File 'lib/smalruby/character.rb', line 456 def two_wheel_drive_car(pin) Hardware.create_hardware(Hardware::TwoWheelDriveCar, pin) end |
#up_pen ⇒ Object
ペンを上げる
390 391 392 |
# File 'lib/smalruby/character.rb', line 390 def up_pen @enable_pen = false end |
#visible=(val) ⇒ Object
表示する/隠す
301 302 303 304 305 306 307 308 |
# File 'lib/smalruby/character.rb', line 301 def visible=(val) if val self.collision_enable = true else self.collision_enable = false end super end |
#x=(val) ⇒ Object
X座標を( )にする
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/smalruby/character.rb', line 103 def x=(val) left = x + center_x top = y + center_y if val < 0 val = 0 elsif val + image.width >= Window.width val = Window.width - image.width end super(val) draw_pen(left, top, x + center_x, y + center_y) if @enable_pen end |
#y=(val) ⇒ Object
Y座標を( )にする
119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/smalruby/character.rb', line 119 def y=(val) left = x + center_x top = y + center_y if val < 0 val = 0 elsif val + image.height >= Window.height val = Window.height - image.height end super(val) draw_pen(left, top, x + center_x, y + center_y) if @enable_pen end |