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
-
#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
モータードライバ.
-
#rgb_led_anode(pin) ⇒ Object
RGB LED(アノード).
-
#rgb_led_cathode(pin) ⇒ Object
RGB LED(カソード).
-
#sensor(pin) ⇒ Object
汎用的なセンサー.
-
#servo(pin) ⇒ Object
サーボモーター.
-
#two_wheel_drive_car(pin) ⇒ Object
2WD車.
Instance Method Summary collapse
- #alive? ⇒ Boolean
-
#await ⇒ Object
1フレーム待つ.
- #button_down(pin) ⇒ Object
- #button_up(pin) ⇒ Object
- #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
- #sensor_change(pin, value) ⇒ 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 |
# File 'lib/smalruby/character.rb', line 31 def initialize(option = {}) defaults = { x: 0, y: 0, costume: nil, angle: 0, visible: true, rotation_style: :free } opt = process_optional_arguments(option, defaults) @costumes = [opt[:costume]].flatten.compact.map { |costume| costume.is_a?(String) ? Image.load(asset_path(costume)) : costume } @costume_index = 0 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
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/smalruby/character.rb', line 504 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
角度
181 182 183 184 185 186 187 188 |
# File 'lib/smalruby/character.rb', line 181 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
( )度に向ける
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/smalruby/character.rb', line 191 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フレーム待つ
535 536 537 |
# File 'lib/smalruby/character.rb', line 535 def await Smalruby.await end |
#button(pin) ⇒ Object
ボタン
400 401 402 |
# File 'lib/smalruby/character.rb', line 400 def (pin) Hardware.create_hardware(Hardware::Button, pin) end |
#button_down(pin) ⇒ Object
497 498 499 500 501 502 |
# File 'lib/smalruby/character.rb', line 497 def (pin) @event_handlers[:button_down].try(:each) do |h| next unless h..include?(pin) @threads << h.call end end |
#button_up(pin) ⇒ Object
490 491 492 493 494 495 |
# File 'lib/smalruby/character.rb', line 490 def (pin) @event_handlers[:button_up].try(:each) do |h| next unless h..include?(pin) @threads << h.call end end |
#click(buttons) ⇒ Object
461 462 463 464 465 466 467 468 |
# File 'lib/smalruby/character.rb', line 461 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
距離
310 311 312 313 |
# File 'lib/smalruby/character.rb', line 310 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
ペンを下ろす
353 354 355 |
# File 'lib/smalruby/character.rb', line 353 def down_pen @enable_pen = true end |
#draw ⇒ Object
411 412 413 414 415 |
# File 'lib/smalruby/character.rb', line 411 def draw draw_balloon if visible super end |
#go_to(target) ⇒ Object
( )に行く
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/smalruby/character.rb', line 228 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
470 471 472 473 474 475 476 477 478 479 480 481 |
# File 'lib/smalruby/character.rb', line 470 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
330 331 332 |
# File 'lib/smalruby/character.rb', line 330 def hit?(other) check([other]).length > 0 end |
#join ⇒ Object
522 523 524 525 |
# File 'lib/smalruby/character.rb', line 522 def join @threads.compact! @threads.each(&:join) end |
#key_down(keys) ⇒ Object
443 444 445 446 447 448 449 450 |
# File 'lib/smalruby/character.rb', line 443 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
452 453 454 455 456 457 458 459 |
# File 'lib/smalruby/character.rb', line 452 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
370 371 372 |
# File 'lib/smalruby/character.rb', line 370 def led(pin) Hardware.create_hardware(Hardware::Led, pin) end |
#loop ⇒ Object
527 528 529 530 531 532 |
# File 'lib/smalruby/character.rb', line 527 def loop Kernel.loop do yield Smalruby.await end end |
#motor_driver(pin) ⇒ Object
モータードライバ
395 396 397 |
# File 'lib/smalruby/character.rb', line 395 def motor_driver(pin) Hardware.create_hardware(Hardware::MotorDriver, pin) end |
#move(val = 1) ⇒ Object
( )歩動かす
81 82 83 |
# File 'lib/smalruby/character.rb', line 81 def move(val = 1) self.position = [x + @vector[:x] * val, y + @vector[:y] * val] end |
#move_back(val = 1) ⇒ Object
( )歩後ろに動かす
86 87 88 |
# File 'lib/smalruby/character.rb', line 86 def move_back(val = 1) move(-val) end |
#next_costume ⇒ Object
次のコスチュームにする
299 300 301 302 303 |
# File 'lib/smalruby/character.rb', line 299 def next_costume @costume_index += 1 @costume_index = @costume_index % @costumes.length self.image = @costumes[@costume_index] end |
#on(event, *options, &block) ⇒ Object
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/smalruby/character.rb', line 417 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! when :sensor_change sensor(.first) when :button_up, :button_down (.first) end end |
#play(option = {}) ⇒ Object
( )の音を鳴らす
339 340 341 342 343 344 345 346 |
# File 'lib/smalruby/character.rb', line 339 def play(option = {}) defaults = { name: 'piano_do.wav' } opt = process_optional_arguments(option, defaults) new_sound(opt[:name]).play end |
#point_towards(target) ⇒ Object
( )に向ける
214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/smalruby/character.rb', line 214 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座標
138 139 140 |
# File 'lib/smalruby/character.rb', line 138 def position [x, y] end |
#position=(val) ⇒ Object
X座標を( )、Y座標を( )にする
122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/smalruby/character.rb', line 122 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
左右の端に着いた?
321 322 323 |
# File 'lib/smalruby/character.rb', line 321 def reach_left_or_right_wall? x <= 0 || x >= (Window.width - image.width) end |
#reach_top_or_bottom_wall? ⇒ Boolean
上下の端に着いた?
326 327 328 |
# File 'lib/smalruby/character.rb', line 326 def reach_top_or_bottom_wall? y <= 0 || y >= (Window.height - image.height) end |
#reach_wall? ⇒ Boolean
端に着いた?
316 317 318 |
# File 'lib/smalruby/character.rb', line 316 def reach_wall? reach_left_or_right_wall? || reach_top_or_bottom_wall? end |
#rgb_led_anode(pin) ⇒ Object
RGB LED(アノード)
375 376 377 |
# File 'lib/smalruby/character.rb', line 375 def rgb_led_anode(pin) Hardware.create_hardware(Hardware::RgbLedAnode, pin) end |
#rgb_led_cathode(pin) ⇒ Object
RGB LED(カソード)
380 381 382 |
# File 'lib/smalruby/character.rb', line 380 def rgb_led_cathode(pin) Hardware.create_hardware(Hardware::RgbLedCathode, pin) end |
#rotate(angle) ⇒ Object
( )度回転する
171 172 173 |
# File 'lib/smalruby/character.rb', line 171 def rotate(angle) self.angle += angle end |
#say(options = {}) ⇒ Object
243 244 245 246 247 248 249 250 251 252 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 |
# File 'lib/smalruby/character.rb', line 243 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
汎用的なセンサー
405 406 407 |
# File 'lib/smalruby/character.rb', line 405 def sensor(pin) Hardware.create_hardware(Hardware::Sensor, pin) end |
#sensor_change(pin, value) ⇒ Object
483 484 485 486 487 488 |
# File 'lib/smalruby/character.rb', line 483 def sensor_change(pin, value) @event_handlers[:sensor_change].try(:each) do |h| next unless h..include?(pin) @threads << h.call(value) end end |
#servo(pin) ⇒ Object
サーボモーター
385 386 387 |
# File 'lib/smalruby/character.rb', line 385 def servo(pin) Hardware.create_hardware(Hardware::Servo, pin) end |
#start ⇒ Object
437 438 439 440 441 |
# File 'lib/smalruby/character.rb', line 437 def start @event_handlers[:start].try(:each) do |h| @threads << h.call end end |
#turn ⇒ Object
くるっと振り返る
143 144 145 |
# File 'lib/smalruby/character.rb', line 143 def turn sync_angle(@vector[:x] * -1, @vector[:y] * -1) end |
#turn_if_reach_wall ⇒ Object
もし端に着いたら、跳ね返る
158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/smalruby/character.rb', line 158 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
横に振り返る
148 149 150 |
# File 'lib/smalruby/character.rb', line 148 def turn_x sync_angle(@vector[:x] * -1, @vector[:y]) end |
#turn_y ⇒ Object
縦に振り返る
153 154 155 |
# File 'lib/smalruby/character.rb', line 153 def turn_y sync_angle(@vector[:x], @vector[:y] * -1) end |
#two_wheel_drive_car(pin) ⇒ Object
2WD車
390 391 392 |
# File 'lib/smalruby/character.rb', line 390 def two_wheel_drive_car(pin) Hardware.create_hardware(Hardware::TwoWheelDriveCar, pin) end |
#up_pen ⇒ Object
ペンを上げる
358 359 360 |
# File 'lib/smalruby/character.rb', line 358 def up_pen @enable_pen = false end |
#visible=(val) ⇒ Object
表示する/隠す
289 290 291 292 293 294 295 296 |
# File 'lib/smalruby/character.rb', line 289 def visible=(val) if val self.collision_enable = true else self.collision_enable = false end super end |
#x=(val) ⇒ Object
X座標を( )にする
91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/smalruby/character.rb', line 91 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座標を( )にする
107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/smalruby/character.rb', line 107 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 |