Class: Smalruby::Character
- Inherits:
-
Sprite
- Object
- Sprite
- Smalruby::Character
- Extended by:
- Forwardable, Mutex_m
- Defined in:
- lib/smalruby/character.rb
Overview
キャラクターを表現するクラス
動き collapse
-
#angle ⇒ Object
角度.
Instance Attribute Summary collapse
-
#checking_hit_targets ⇒ Object
Returns the value of attribute checking_hit_targets.
-
#event_handlers ⇒ Object
Returns the value of attribute event_handlers.
-
#rotation_style ⇒ Object
Returns the value of attribute rotation_style.
-
#threads ⇒ Object
Returns the value of attribute threads.
動き collapse
-
#move(val = 1) ⇒ Object
( )歩動かす.
-
#move_back(val = 1) ⇒ Object
( )歩後ろに動かす.
-
#point_towards(target) ⇒ Object
( )に向ける.
-
#rotate(angle) ⇒ Object
( )度回転する.
-
#turn ⇒ Object
くるっと振り返る.
-
#turn_if_reach_wall ⇒ Object
もし端に着いたら、跳ね返る.
-
#turn_x ⇒ Object
横に振り返る.
-
#turn_y ⇒ Object
縦に振り返る.
見た目 collapse
調べる collapse
-
#distance(x, y) ⇒ Object
距離.
- #hit?(other) ⇒ Boolean
-
#reach_left_or_right_wall? ⇒ Boolean
左右の端に着いた?.
-
#reach_top_or_bottom_wall? ⇒ Boolean
上下の端に着いた?.
-
#reach_wall? ⇒ Boolean
端に着いた?.
音 collapse
ハードウェア collapse
-
#button(pin) ⇒ Object
ボタン.
-
#led(pin) ⇒ Object
LED.
-
#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
- #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.
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 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/smalruby/character.rb', line 28 def initialize(option = {}) defaults = { x: 0, y: 0, costume: nil, angle: 0, visible: true, rotation_style: :free } 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 self.angle = opt[:angle] if opt[:angle] != 0 self.rotation_style = opt[:rotation_style] # 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
#angle ⇒ Object
角度
125 126 127 |
# File 'lib/smalruby/character.rb', line 125 def angle @angle end |
#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 |
#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 |
#rotation_style ⇒ Object
Returns the value of attribute rotation_style.
26 27 28 |
# File 'lib/smalruby/character.rb', line 26 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
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/smalruby/character.rb', line 398 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
ボタン
284 285 286 |
# File 'lib/smalruby/character.rb', line 284 def (pin) Hardware.create_hardware(Hardware::Button, pin) end |
#button_down(pin) ⇒ Object
391 392 393 394 395 396 |
# File 'lib/smalruby/character.rb', line 391 def (pin) @event_handlers[:button_down].try(:each) do |h| next unless h..include?(pin) @threads << h.call end end |
#button_up(pin) ⇒ Object
384 385 386 387 388 389 |
# File 'lib/smalruby/character.rb', line 384 def (pin) @event_handlers[:button_up].try(:each) do |h| next unless h..include?(pin) @threads << h.call end end |
#click(buttons) ⇒ Object
355 356 357 358 359 360 361 362 |
# File 'lib/smalruby/character.rb', line 355 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
距離
217 218 219 220 |
# File 'lib/smalruby/character.rb', line 217 def distance(x, y) Math.sqrt((self.x + center_x - x).abs**2 + (self.y + center_y - y).abs**2).to_i end |
#draw ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/smalruby/character.rb', line 295 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 |
#hit ⇒ Object
364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/smalruby/character.rb', line 364 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
237 238 239 |
# File 'lib/smalruby/character.rb', line 237 def hit?(other) check([other]).length > 0 end |
#join ⇒ Object
415 416 417 |
# File 'lib/smalruby/character.rb', line 415 def join @threads.each(&:join) end |
#key_down(keys) ⇒ Object
337 338 339 340 341 342 343 344 |
# File 'lib/smalruby/character.rb', line 337 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
346 347 348 349 350 351 352 353 |
# File 'lib/smalruby/character.rb', line 346 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
259 260 261 |
# File 'lib/smalruby/character.rb', line 259 def led(pin) Hardware.create_hardware(Hardware::Led, pin) end |
#loop ⇒ Object
419 420 421 422 423 424 |
# File 'lib/smalruby/character.rb', line 419 def loop Kernel.loop do yield Smalruby.await end end |
#move(val = 1) ⇒ Object
( )歩動かす
76 77 78 79 |
# File 'lib/smalruby/character.rb', line 76 def move(val = 1) self.x += @vector[:x] * val self.y += @vector[:y] * val end |
#move_back(val = 1) ⇒ Object
( )歩後ろに動かす
82 83 84 |
# File 'lib/smalruby/character.rb', line 82 def move_back(val = 1) move(-val) end |
#on(event, *options, &block) ⇒ Object
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/smalruby/character.rb', line 311 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
245 246 247 248 249 250 251 252 |
# File 'lib/smalruby/character.rb', line 245 def play(option = {}) defaults = { name: 'piano_do.wav' } opt = process_optional_arguments(option, defaults) new_sound(opt[:name]).play end |
#point_towards(target) ⇒ Object
( )に向ける
154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/smalruby/character.rb', line 154 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_left_or_right_wall? ⇒ Boolean
左右の端に着いた?
228 229 230 |
# File 'lib/smalruby/character.rb', line 228 def reach_left_or_right_wall? self.x < 0 || self.x >= (Window.width - image.width) end |
#reach_top_or_bottom_wall? ⇒ Boolean
上下の端に着いた?
233 234 235 |
# File 'lib/smalruby/character.rb', line 233 def reach_top_or_bottom_wall? self.y < 0 || self.y >= (Window.height - image.height) end |
#reach_wall? ⇒ Boolean
端に着いた?
223 224 225 |
# File 'lib/smalruby/character.rb', line 223 def reach_wall? reach_left_or_right_wall? || reach_top_or_bottom_wall? end |
#rgb_led_anode(pin) ⇒ Object
RGB LED(アノード)
264 265 266 |
# File 'lib/smalruby/character.rb', line 264 def rgb_led_anode(pin) Hardware.create_hardware(Hardware::RgbLedAnode, pin) end |
#rgb_led_cathode(pin) ⇒ Object
RGB LED(カソード)
269 270 271 |
# File 'lib/smalruby/character.rb', line 269 def rgb_led_cathode(pin) Hardware.create_hardware(Hardware::RgbLedCathode, pin) end |
#rotate(angle) ⇒ Object
( )度回転する
115 116 117 |
# File 'lib/smalruby/character.rb', line 115 def rotate(angle) self.angle += angle end |
#say(options = {}) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/smalruby/character.rb', line 171 def say( = {}) defaults = { message: '', second: 0, } opts = process_optional_arguments(, defaults) if @balloon @balloon.vanish @balloon = nil end = opts[:message].to_s 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(self.x, self.y, image) end |
#sensor(pin) ⇒ Object
汎用的なセンサー
289 290 291 |
# File 'lib/smalruby/character.rb', line 289 def sensor(pin) Hardware.create_hardware(Hardware::Sensor, pin) end |
#sensor_change(pin, value) ⇒ Object
377 378 379 380 381 382 |
# File 'lib/smalruby/character.rb', line 377 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
サーボモーター
274 275 276 |
# File 'lib/smalruby/character.rb', line 274 def servo(pin) Hardware.create_hardware(Hardware::Servo, pin) end |
#start ⇒ Object
331 332 333 334 335 |
# File 'lib/smalruby/character.rb', line 331 def start @event_handlers[:start].try(:each) do |h| @threads << h.call end end |
#turn ⇒ Object
くるっと振り返る
87 88 89 |
# File 'lib/smalruby/character.rb', line 87 def turn sync_angle(@vector[:x] * -1, @vector[:y] * -1) end |
#turn_if_reach_wall ⇒ Object
もし端に着いたら、跳ね返る
102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/smalruby/character.rb', line 102 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
横に振り返る
92 93 94 |
# File 'lib/smalruby/character.rb', line 92 def turn_x sync_angle(@vector[:x] * -1, @vector[:y]) end |
#turn_y ⇒ Object
縦に振り返る
97 98 99 |
# File 'lib/smalruby/character.rb', line 97 def turn_y sync_angle(@vector[:x], @vector[:y] * -1) end |
#two_wheel_drive_car(pin) ⇒ Object
2WD車
279 280 281 |
# File 'lib/smalruby/character.rb', line 279 def two_wheel_drive_car(pin) Hardware.create_hardware(Hardware::TwoWheelDriveCar, pin) end |