class Smalruby3::Sprite

Constants

ROTATION_STYLE

Attributes

checking_hit_targets[RW]
costumes[R]
current_costume[R]
direction[R]
enable_pen[R]
event_handlers[RW]
lists[R]
name[RW]
pen_color[RW]
rotation_style[R]
size[RW]
threads[RW]
variables[R]
visible[RW]
volume[RW]
x[R]
y[R]

Public Class Methods

new(name, options = {}, &block) click to toggle source
# File lib/smalruby3/sprite.rb, line 45
def initialize(name, options = {}, &block)
  @name = name
  @x = 0
  @y = 0
  @costumes = []
  @current_costume = 0

  @vector = { x: 1, y: 0 }
  @event_handlers = {}
  @threads = []
  @name_to_costume = {}

  @dxruby_sprite = DXRuby::Sprite.new(0, 0)

  defaults = {
    x: 0,
    y: 0,
    direction: 90,
    visible: true,
    size: 100,
    current_costume: 0,
    costumes: [],
    rotation_style: ROTATION_STYLE[:all_around],
    variables: [],
    lists: [],
  }
  opts = Util.process_options(options, defaults)
  opts.each do |k, v|
    send("#{k}=", v)
  end

  World.instance.add_target(self)

  if block_given?
    instance_eval(&block)
  end
end

Public Instance Methods

costume() click to toggle source
# File lib/smalruby3/sprite.rb, line 110
def costume
  @costumes[@current_costume]
end
costumes=(assets) click to toggle source
# File lib/smalruby3/sprite.rb, line 91
def costumes=(assets)
  @name_to_costume = {}
  @costumes = assets.map { |asset|
    c = Costume.new(asset)
    @name_to_costume[c.name] = c
    c
  }
  sync_costumes
end
current_costume=(index) click to toggle source
# File lib/smalruby3/sprite.rb, line 101
def current_costume=(index)
  @current_costume = if @costumes.length > 0
                       index % @costumes.length
                     else
                       0
                     end
  sync_costumes
end
draw() click to toggle source
# File lib/smalruby3/sprite.rb, line 131
def draw
  if @visible
    @dxruby_sprite.draw
  end
end
fire(event, *options) click to toggle source
# File lib/smalruby3/sprite.rb, line 137
def fire(event, *options)
  if (events = @event_handlers[event])
    events.each do |e|
      if e.options == options
        @threads << e.call
      end
    end
  end
end
join_threads(wait = false) click to toggle source
# File lib/smalruby3/sprite.rb, line 147
def join_threads(wait = false)
  @threads.compact!
  error = false
  @threads.delete_if { |t|
    if t.alive?
      false
    else
      begin
        t.join
      rescue => e
        Util.print_exception(e)
        error = true
      end
      true
    end
  }
  if error
    exit(1)
  end
  if wait
    @threads.each(&:join)
  end
end
lists=(attrs) click to toggle source
# File lib/smalruby3/sprite.rb, line 125
def lists=(attrs)
  @lists = attrs.map { |attr|
    define_variable(attr[:name], attr.key?(:value) ? attr[:value] : [])
  }
end
position() click to toggle source
# File lib/smalruby3/sprite.rb, line 87
def position
  [x, y]
end
rotation_style=(val) click to toggle source
# File lib/smalruby3/sprite.rb, line 114
def rotation_style=(val)
  @rotation_style = val
  sync_direction
end
stage?() click to toggle source
# File lib/smalruby3/sprite.rb, line 83
def stage?
  false
end
variables=(attrs) click to toggle source
# File lib/smalruby3/sprite.rb, line 119
def variables=(attrs)
  @variables = attrs.map { |attr|
    define_variable(attr[:name], attr.key?(:value) ? attr[:value] : 0)
  }
end

Private Instance Methods

define_variable(name, value) click to toggle source
# File lib/smalruby3/sprite.rb, line 173
def define_variable(name, value)
  name = "@#{name}"
  instance_variable_set(name, value)
  name
end
s2dx() click to toggle source
# File lib/smalruby3/sprite.rb, line 179
def s2dx
  World.instance.s2dx
end
sync_costumes() click to toggle source
# File lib/smalruby3/sprite.rb, line 218
def sync_costumes
  if (c = costume)
    @dxruby_sprite.image = c.image
    @dxruby_sprite.scale_x = c.width_scale
    @dxruby_sprite.scale_y = c.height_scale
    @dxruby_sprite.center_x = c.rotation_center_x
    @dxruby_sprite.center_y = c.rotation_center_y
  end
  sync_position
end
sync_direction() click to toggle source
# File lib/smalruby3/sprite.rb, line 193
def sync_direction
  angle = s2dx.angle(direction)

  radian = angle * Math::PI / 180
  @vector[:x] = Math.cos(radian)
  @vector[:y] = -Math.sin(radian)

  scale_x = (c = costume) ? c.width_scale : 1
  case @rotation_style
  when ROTATION_STYLE[:all_around]
    @dxruby_sprite.scale_x = scale_x
    @dxruby_sprite.angle = angle
  when ROTATION_STYLE[:left_right]
    @dxruby_sprite.scale_x = if @vector[:x] >= 0
                               scale_x
                             else
                               -scale_x
                             end
    @dxruby_sprite.angle = 0
  when ROTATION_STYLE[:none]
    @dxruby_sprite.scale_x = scale_x
    @dxruby_sprite.angle = 0
  end
end
sync_position() click to toggle source
# File lib/smalruby3/sprite.rb, line 183
def sync_position
  dx_x, dx_y = *s2dx.position(x, y)
  if (c = costume)
    dx_x -= c.rotation_center_x
    dx_y -= c.rotation_center_y
  end
  @dxruby_sprite.x = dx_x
  @dxruby_sprite.y = dx_y
end