     @updatePosition()
     frameChanged = frameChanged or @targetScaleFactor isnt @scaleFactor
     if frameChanged
+      @handledDisplayEvents = {}
       @updateScale()  # must happen before rotation
       @updateAlpha()
       @updateRotation()

    return unless @thang?.currentEvents
    for event in @thang.currentEvents
      continue unless event.startsWith 'aoe-'
      continue if @handledAoEs[event]

      @handledAoEs[event] = true
      args = JSON.parse(event[4...])
      pos = @options.camera.worldToSurface {x:args[0], y:args[1]}
      circle = new createjs.Shape()

        .call =>
          return if @destroyed
          @options.groundLayer.removeChild circle
          delete @handledDisplayEvents[event]
        
  showTextEvents: ->
    return unless @thang?.currentEvents
    for event in @thang.currentEvents
      continue unless event.startsWith 'text-'
      continue if @handledDisplayEvents[event]
      @handledDisplayEvents[event] = true
      options = JSON.parse(event[5...])
      label = new createjs.Text options.text, "bold #{options.size or 16}px Arial", options.color or '#FFF'
      label.shadow = new createjs.Shadow '#000', 0, 0, 2
      offset = @getOffset 'aboveHead'
      [label.x, label.y] = [@imageObject.x + offset.x - label.getMeasuredWidth() / 2, @imageObject.y + offset.y]
      @options.floatingLayer.addChild label
      window.labels ?= []
      window.labels.push label
      label.alpha = 0
      createjs.Tween.get(label)
        .to({y:label.y-2, alpha:1}, 200, createjs.Ease.linear)
        .to({y:label.y-12}, 1000, createjs.Ease.linear)
        .to({y:label.y-22, alpha:0}, 1000, createjs.Ease.linear)
        .call =>
          return if @destroyed
          @options.floatingLayer.removeChild label


  cache: ->
    bounds = @imageObject.getBounds()
