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.
動き 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
-
#down_pen ⇒ Object
ペンを下ろす.
-
#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.
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 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 |
# File 'lib/smalruby/character.rb', line 31 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' 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 |
Instance Method Details
#alive? ⇒ Boolean
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
# File 'lib/smalruby/character.rb', line 517 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
角度
191 192 193 194 195 196 197 198 |
# File 'lib/smalruby/character.rb', line 191 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
( )度に向ける
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/smalruby/character.rb', line 201 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 = 1 super(val) elsif @rotation_style == :left_right if @vector[:x] >= 0 self.scale_x = 1 else self.scale_x = -1 end super(0) else self.scale_x = 1 super(0) end end |
#await ⇒ Object
1フレーム待つ
548 549 550 |
# File 'lib/smalruby/character.rb', line 548 def await Smalruby.await end |
#button(pin) ⇒ Object
ボタン
428 429 430 |
# File 'lib/smalruby/character.rb', line 428 def (pin) Hardware.create_hardware(Hardware::Button, pin) end |
#click(buttons) ⇒ Object
495 496 497 498 499 500 501 502 |
# File 'lib/smalruby/character.rb', line 495 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
距離
333 334 335 336 |
# File 'lib/smalruby/character.rb', line 333 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
ペンを下ろす
376 377 378 |
# File 'lib/smalruby/character.rb', line 376 def down_pen @enable_pen = true end |
#draw ⇒ Object
449 450 451 452 453 |
# File 'lib/smalruby/character.rb', line 449 def draw draw_balloon if visible super end |
#go_to(target) ⇒ Object
( )に行く
238 239 240 241 242 243 244 245 246 247 |
# File 'lib/smalruby/character.rb', line 238 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
504 505 506 507 508 509 510 511 512 513 514 515 |
# File 'lib/smalruby/character.rb', line 504 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
353 354 355 |
# File 'lib/smalruby/character.rb', line 353 def hit?(other) check([other]).length > 0 end |
#join ⇒ Object
535 536 537 538 |
# File 'lib/smalruby/character.rb', line 535 def join @threads.compact! @threads.each(&:join) end |
#key_down(keys) ⇒ Object
477 478 479 480 481 482 483 484 |
# File 'lib/smalruby/character.rb', line 477 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
486 487 488 489 490 491 492 493 |
# File 'lib/smalruby/character.rb', line 486 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
393 394 395 |
# File 'lib/smalruby/character.rb', line 393 def led(pin) Hardware.create_hardware(Hardware::Led, pin) end |
#loop ⇒ Object
540 541 542 543 544 545 |
# File 'lib/smalruby/character.rb', line 540 def loop Kernel.loop do yield Smalruby.await end end |
#motor_driver(pin) ⇒ Object
モータードライバ
423 424 425 |
# File 'lib/smalruby/character.rb', line 423 def motor_driver(pin) Hardware.create_hardware(Hardware::MotorDriver, pin) end |
#move(val = 1) ⇒ Object
( )歩動かす
91 92 93 |
# File 'lib/smalruby/character.rb', line 91 def move(val = 1) self.position = [x + @vector[:x] * val, y + @vector[:y] * val] end |
#move_back(val = 1) ⇒ Object
( )歩後ろに動かす
96 97 98 |
# File 'lib/smalruby/character.rb', line 96 def move_back(val = 1) move(-val) end |
#neo_pixel(pin) ⇒ Object
マイコン内蔵RGB LED
408 409 410 |
# File 'lib/smalruby/character.rb', line 408 def neo_pixel(pin) Hardware.create_hardware(Hardware::NeoPixel, pin) end |
#next_costume ⇒ Object
次のコスチュームにする
309 310 311 |
# File 'lib/smalruby/character.rb', line 309 def next_costume self.costume_index = @costume_index + 1 end |
#on(event, *options, &block) ⇒ Object
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/smalruby/character.rb', line 455 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 |
#play(option = {}) ⇒ Object
( )の音を鳴らす
362 363 364 365 366 367 368 369 |
# File 'lib/smalruby/character.rb', line 362 def play(option = {}) defaults = { name: 'piano_do.wav' } opt = process_optional_arguments(option, defaults) new_sound(opt[:name]).play end |
#point_towards(target) ⇒ Object
( )に向ける
224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/smalruby/character.rb', line 224 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座標
148 149 150 |
# File 'lib/smalruby/character.rb', line 148 def position [x, y] end |
#position=(val) ⇒ Object
X座標を( )、Y座標を( )にする
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/smalruby/character.rb', line 132 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
左右の端に着いた?
344 345 346 |
# File 'lib/smalruby/character.rb', line 344 def reach_left_or_right_wall? x <= 0 || x >= (Window.width - image.width) end |
#reach_top_or_bottom_wall? ⇒ Boolean
上下の端に着いた?
349 350 351 |
# File 'lib/smalruby/character.rb', line 349 def reach_top_or_bottom_wall? y <= 0 || y >= (Window.height - image.height) end |
#reach_wall? ⇒ Boolean
端に着いた?
339 340 341 |
# File 'lib/smalruby/character.rb', line 339 def reach_wall? reach_left_or_right_wall? || reach_top_or_bottom_wall? end |
#rgb_led_anode(pin) ⇒ Object
RGB LED(アノード)
398 399 400 |
# File 'lib/smalruby/character.rb', line 398 def rgb_led_anode(pin) Hardware.create_hardware(Hardware::RgbLedAnode, pin) end |
#rgb_led_cathode(pin) ⇒ Object
RGB LED(カソード)
403 404 405 |
# File 'lib/smalruby/character.rb', line 403 def rgb_led_cathode(pin) Hardware.create_hardware(Hardware::RgbLedCathode, pin) end |
#rotate(angle) ⇒ Object
( )度回転する
181 182 183 |
# File 'lib/smalruby/character.rb', line 181 def rotate(angle) self.angle += angle end |
#say(options = {}) ⇒ Object
253 254 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 |
# File 'lib/smalruby/character.rb', line 253 def say( = {}) defaults = { message: '', second: 0, } opts = process_optional_arguments(, defaults) = opts[:message].to_s return if == = 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
汎用的なセンサー
433 434 435 |
# File 'lib/smalruby/character.rb', line 433 def sensor(pin) Hardware.create_hardware(Hardware::Sensor, pin) end |
#servo(pin) ⇒ Object
サーボモーター
413 414 415 |
# File 'lib/smalruby/character.rb', line 413 def servo(pin) Hardware.create_hardware(Hardware::Servo, pin) end |
#smalrubot_s1 ⇒ Object
create or get Hardware::SmalrubotS1 instance
443 444 445 |
# File 'lib/smalruby/character.rb', line 443 def smalrubot_s1 Hardware.create_hardware(Hardware::SmalrubotS1) end |
#smalrubot_v3 ⇒ Object
create or get Hardware::SmalrubotV3 instance
438 439 440 |
# File 'lib/smalruby/character.rb', line 438 def smalrubot_v3 Hardware.create_hardware(Hardware::SmalrubotV3) end |
#start ⇒ Object
471 472 473 474 475 |
# File 'lib/smalruby/character.rb', line 471 def start @event_handlers[:start].try(:each) do |h| @threads << h.call end end |
#switch_costume(name) ⇒ Object
コスチュームを( )にする
314 315 316 317 318 319 320 321 |
# File 'lib/smalruby/character.rb', line 314 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
くるっと振り返る
153 154 155 |
# File 'lib/smalruby/character.rb', line 153 def turn sync_angle(@vector[:x] * -1, @vector[:y] * -1) end |
#turn_if_reach_wall ⇒ Object
もし端に着いたら、跳ね返る
168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/smalruby/character.rb', line 168 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
横に振り返る
158 159 160 |
# File 'lib/smalruby/character.rb', line 158 def turn_x sync_angle(@vector[:x] * -1, @vector[:y]) end |
#turn_y ⇒ Object
縦に振り返る
163 164 165 |
# File 'lib/smalruby/character.rb', line 163 def turn_y sync_angle(@vector[:x], @vector[:y] * -1) end |
#two_wheel_drive_car(pin) ⇒ Object
2WD車
418 419 420 |
# File 'lib/smalruby/character.rb', line 418 def two_wheel_drive_car(pin) Hardware.create_hardware(Hardware::TwoWheelDriveCar, pin) end |
#up_pen ⇒ Object
ペンを上げる
381 382 383 |
# File 'lib/smalruby/character.rb', line 381 def up_pen @enable_pen = false end |
#visible=(val) ⇒ Object
表示する/隠す
299 300 301 302 303 304 305 306 |
# File 'lib/smalruby/character.rb', line 299 def visible=(val) if val self.collision_enable = true else self.collision_enable = false end super end |
#x=(val) ⇒ Object
X座標を( )にする
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/smalruby/character.rb', line 101 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座標を( )にする
117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/smalruby/character.rb', line 117 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 |