I made a drop text shadow function a while back, it’s not perfect but it allows you to offset the x/y position of the shadow among other things. The only “catch” is that it returns a single group containing both objects (for easy repositioning later), so if you want to update the string you need to call the :setText function I’ve included:
function display.newShadowText(params) local group = display.newGroup() local parent = params.parent or nil--display group to insert the text into local txt = params.text or ""--the string to display local width = params.width or 0--width of the textbox, 0 for unlimited local height = params.height or 0--height of the textbox, 0 for unlimited local x = params.x or 0--x position local y = params.y or 0--y position local font = params.font or native.systemFont--font name local fontSize = params.fontSize or 50--font size local align = params.align or "left"--alignment left/right/center local shadowColor = params.shadowColor or {0, 0, 0, 0.4}--colour of the drop shadow local textColor = params.textColor or {1}--colour of the main text local xOffset = params.xOffset or 0--how much to offset the dropshadow's x position relative to the main text object local yOffset = params.yOffset or -fontSize / 15 --same for the y position local shadowOff = params.shadowOff or false --if you don't want to show a shadow local anchorX = params.anchorX or 0.5 --anchor points local anchorY = params.anchorY or 0.5 --offset text on OS as needed, since some fonts get displayed differently on different OS if system.getInfo("platformName") == "iPhone OS" then --y = y + 5 elseif system.getInfo("platformName") == "Android" then --y = y + 5 end local s = display.newText({ text = txt, width = width, height = height, x = 0, y = 0, font = font, align = align, fontSize = fontSize, }) s:setFillColor( unpack(shadowColor) ) group:insert(s) local t = display.newText({ text = txt, width = width, height = height, x = xOffset, y = yOffset, font = font, align = align, fontSize = fontSize, }) t:setFillColor( unpack(textColor) ) group:insert(t) group.x, group.y = x + (group.width \* 0.5) - (group.width \* anchorX), y + (group.height \* 0.5) - (group.height \* anchorY) group.s = s group.t = t if shadowOff then s.isVisible = false end if parent then parent:insert(group) end function group:setText(str, shouldMove) self.s.text = str self.t.text = str if shouldMove == true or shouldMove == nil then group.x, group.y = x + (group.width \* 0.5) - (group.width \* anchorX), y + (group.height \* 0.5) - (group.height \* anchorY) end end function group:getText() return self.t.text end function group:setShadowColor(...) if arg then if type(arg[1]) == "table" then self.s:setFillColor( unpack(arg[1]) ) elseif type(arg[1]) == "number" then self.s:setFillColor( unpack(arg) ) end end end function group:setFillColor(...) if arg then if type(arg[1]) == "table" then self.t:setFillColor( unpack(arg[1]) ) elseif type(arg[1]) == "number" then self.t:setFillColor( unpack(arg) ) end end end return group end
It takes a table of parameters as it’s only argument. The params all have defaults so you only need to set the ones that you need to customise.
Here’s a sample of it in use:
local myGroup = display.newGroup() local bg = display.newRect(myGroup, display.contentWidth \* 0.5, display.contentHeight \* 0.5, display.contentWidth, display.contentHeight) bg:setFillColor(0.8, 0.8, 1) local myText = display.newShadowText({ parent = myGroup, text = "show this string with a shadow please", width = display.contentWidth \* 0.5, height = 0, x = display.contentWidth \* 0.5, y = display.contentHeight \* 0.5, font = "someFontName", align = "center", fontSize = 75, xOffset = 0, yOffset = -5, anchorX = 0.5, shadowColor = {0, 0, 0, 0.8} }) local strings = { "hello", "world", "foo", "bar" } local function update() --can pass in a table or just numbers --myText:setFillColor( {math.random(), math.random(), math.random()} ) myText:setFillColor( math.random(), math.random(), math.random() ) --update the text myText:setText(strings[math.random(1, #strings)]) end timer.performWithDelay( 1000, update, -1 )