Getting Started Coding Floating Combat Text

Hello again,

(I’ve had to reply on another toon because of Blizz Forum restrictions)

So, I’ve tried everything I could think of, and everything you and Fizzle have suggested, to create floating text that does not overlap, I’ve done timers (C_After, etc.,) in every conceivable way but to no joy. I’ve even gone so far as to create a true, asynchronous thread package with support for threadDelay(), threadYield(), and threadJoin() semantics. All in a vain attempt to keep the text lines separate.

It’s clear I just do not understand how this works.

I get that it is the frame that is being scrolled, not the text, and that f.animGroup:Play() scrolls a single frame at a time. Nevertheless, if I put a timed delay of N seconds between each f.animGroup:Play(), it still will eventually overlap.

Blizz can do it. Other addons can do it (MIK’s SCT, Parrot, etc.,). Have you guys got any other thoughts or advice?

Cheers,

I recommend scrapping all C_Timer calls. Go with OnUpdate as Fizzlemizz suggested at the start. Between every rendered frame the game client will run any OnUpdates for visible frames that have an OnUpdate handler defined. Use this for your timing.

Set animation aside for now. Use print() or something simple. If your animations are running at different speed they’ll overlap; but if you’re using the same speed (here defined as translation distance and duration) they should not overlap. You may be thinking you have a fixed speed but you may be getting confused by when stuff is actually happening. Remove animation from the equation and work on getting print()s to happen one second apart.

C_Timers and AnimationGroups throw a lot of timing into Blizzard’s hands to handle. If you can achieve a proof of concept of what you’re after with OnUpdates and print(), then your animation is very likely to start working with very little extra coding.

The following adds a /test slash commands that prints 5 Hello’s spaced one second apart. You can put /test in a macro and hit it a few times in succession and it will still space them apart by one second.

local queue = {}

-- simple counter to display: Hello #<counter>
local counter = 0

local f = CreateFrame("Frame")
f:Hide()

-- starts the timer if it's not already started
function f:Start()
  if not self:IsVisible() then
    self.timer = 1 -- starting "immediately"
    self:Show()
  end
end

-- every rendered frame (eg 60 times at 60fps) this function is run with elapsed being the time since the last time it was run. When the timer accumulates to 1, one second has passed.
function f:OnUpdate(elapsed)
  self.timer = self.timer + elapsed
  if self.timer > 1 then
    self.timer = 0
    print(queue[1])
    tremove(queue,1)
  end
  -- if queue is empty, then stop the OnUpdate
  if #queue==0 then
    self:Hide()
  end
end

-- this sets up the OnUpdate to run the above f:OnUpdate() every rendered frame
f:SetScript("OnUpdate",f.OnUpdate)

-- run /test to queue up 5 Hello's to print, spaced 1 second apart
SLASH_TEST1 = "/test"
SlashCmdList["TEST"] = function(msg)

  -- queue up 5 Hello's
  for i=1,5 do
    counter = counter + 1
    tinsert(queue,"Hello #"..counter)
  end

  -- and start the timer
  f:Start()
end
1 Like

You’re right. I’ve got the animation code well isolated and when I get the OnUpDate() stuff worked out, should be able to drop it right in.

I can’t be more grateful for your assistance. Thanks, again. Will close the loop if I get this thing working.

Cheers,

EDIT:
OK, I’ve scrapped the animation code and re-implemented the code using OnUpdate. And I found something very interesting.

The problem with overwriting the text seems to arise from the this code snippet (I changed the scrolling direction to vertical and yos = “y-offset”)

if yos > ScrollMax then -- we're offscreen to the top so...
    yos =  -self.Text1:GetHeight() -- reset to the origin
end

Thus, when a line of text reaches the top, the frame is returned to its origin and repeats. But this usually causes the next new line to be corrupted by
the one being repeated.

So, I removed those three lines (commented them) and the text scrolls nicely with no text overwrite. My question now is this: is removing these 3 lines the best way of solving this problem? Is there a method to simply stop the code after it runs off the top of the screen?

Thanks, Gello.