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

Instance Method Summary collapse

Constructor Details

#initialize(option = {}) ⇒ Character

Returns a new instance of Character.



18
19
20
21
22
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
# File 'lib/smalruby/character.rb', line 18

def initialize(option = {})
  defaults = {
    x: 0,
    y: 0,
    costume: nil,
    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 = []

  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

  World.instance.objects << self
end

Instance Attribute Details

#checking_hit_targetsObject

Returns the value of attribute checking_hit_targets.



16
17
18
# File 'lib/smalruby/character.rb', line 16

def checking_hit_targets
  @checking_hit_targets
end

#event_handlersObject

Returns the value of attribute event_handlers.



14
15
16
# File 'lib/smalruby/character.rb', line 14

def event_handlers
  @event_handlers
end

#threadsObject

Returns the value of attribute threads.



15
16
17
# File 'lib/smalruby/character.rb', line 15

def threads
  @threads
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/smalruby/character.rb', line 224

def alive?
  @threads.delete_if { |t|
    if t.alive?
      false
    else
      begin
        t.join
      rescue => e
        print_exception(e)
      end
      true
    end
  }
  @threads.length > 0
end

#click(buttons) ⇒ Object



202
203
204
205
206
207
208
209
# File 'lib/smalruby/character.rb', line 202

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

距離



118
119
120
121
# File 'lib/smalruby/character.rb', line 118

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

#drawObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/smalruby/character.rb', line 146

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



211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/smalruby/character.rb', line 211

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

#joinObject



240
241
242
# File 'lib/smalruby/character.rb', line 240

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

#key_down(keys) ⇒ Object



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

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



193
194
195
196
197
198
199
200
# File 'lib/smalruby/character.rb', line 193

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

#loop(&block) ⇒ Object



244
245
246
247
248
249
# File 'lib/smalruby/character.rb', line 244

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

#move(val = 1) ⇒ Object

( )歩動かす



53
54
55
56
# File 'lib/smalruby/character.rb', line 53

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

#move_back(val = 1) ⇒ Object

( )歩後ろに動かす



59
60
61
# File 'lib/smalruby/character.rb', line 59

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

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



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/smalruby/character.rb', line 162

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!
  end
end

#play(option = {}) ⇒ Object



133
134
135
136
137
138
139
140
141
142
# File 'lib/smalruby/character.rb', line 133

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

#reach_wall?Boolean

端に着いた

Returns:

  • (Boolean)


124
125
126
127
# File 'lib/smalruby/character.rb', line 124

def reach_wall?
  self.x < 0 || self.x >= (Window.width - image.width) ||
    self.y < 0 || self.y >= (Window.height - image.height)
end

#rotate(angle) ⇒ Object

( )度回転する



76
77
78
79
80
81
82
# File 'lib/smalruby/character.rb', line 76

def rotate(angle)
  radian = angle * Math::PI / 180
  x, y = @vector[:x], @vector[:y]
  @vector[:x] = x * Math.cos(radian) - y * Math.sin(radian)
  @vector[:y] = x * Math.sin(radian) + y * Math.cos(radian)
  self.angle = (self.angle + angle) % 360
end

#say(message) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/smalruby/character.rb', line 88

def say(message)
  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])
  image.draw_font(frame_size + margin_size,
                  frame_size + margin_size,
                  lines.join("\n"), font, [0, 0, 0])
  @balloon = Sprite.new(self.x, self.y, image)
end

#startObject



178
179
180
181
182
# File 'lib/smalruby/character.rb', line 178

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

#turnObject

振り返る



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

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

#turn_if_reach_wallObject

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



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

def turn_if_reach_wall
  turn if reach_wall?
end