Shadowed Text using Gideros

Do you want to create text that has a shadow and control the colour of the Text and the shadow, all of it using Gideros? This article is a quick and easy way to create a text item with shadow.

In terms of learning, there are a couple of things that we learn here
1. How to create a complex hierarchy of items
2. How to add custom functions that seem like the native functions

The theory

If you were to use any programing language or even draw it yourself in Photoshop, to create a shadow, there are two layers containing the text, one with the textColor and one with the shadowColor. The shadow layer and the text layer are positioned one on top of the other with a slight offset for the direction of the shadow. If it is possible, the shadow layer is blurred to give the soft shadow feel. In our case since we cannot blur, the shadow will look like a hard shadow.

The issue

Actually there is no issue, the only problem that we might encounter is that we have to manage two text objects and keep them together. In Gideros we use the TextField object to create text objects and each of these has a setText(), setTextColor() that we can use. To keep them together, we can combine them into a single object or group as we would call it. From the program, we have access to only one object, so if we access the group, we lose all access to the items contained in this group, if we retain access to one of the text items, then how do we access the other? That is the issue here.

Solution

The solution is also rather easy, Gideros has an O-O type structure and due to that the way one can think of solutions also becomes easier than using a non O-O type framework.

1. Creating the group

local container = Sprite.new()    -- Create a new container which is a sprite object
stage:addChild(container)

This container can now be positioned, scaled, moved, etc like any other sprite object, and when it is transformed, it will apply all of the transformations to the children object inside.

2. Creating the Shadow object

local theShadow = TextField.new(_font, "Hello")
container:addChild(theShadow)
theShadow:setPosition(1,1)
theShadow:setTextColor(0x000000)    --> Black Colour

3. Creating the Text Object

local theText = TextField.new(_font, "Hello")
container:addChild(theText)
theText:setTextColor(0xff0000)    --> Red Colour

Now if we position the container using the container:setPosition(100,100) for example, we shall see the text move to the position with the shadow underneath.

4. Adding the helper functions
We need to add the helper functions that will help us modify this object and work with it. The functions that we need are

  • setText
  • setTextColor
  • setShadowColor
  • setFont

These functions are going to be member functions of the container object, hence they are prefixed with the container:

function container:setText(theNewText)
  theText:setText(theNewText)
  theShadow:setText(theNewText)
  self.text = theNewText
end 
function container:setTextColor(theTextColor)
  theText:setTextColor(theTextColor)
  self.textColor = theTextColor
end 
function container:setShadowColor(theShadowColor)
  theShadow:setTextColor(theShadowColor)
  self.shadowColor = theShadowColor
end 

Putting it all together

The entire code can be wrapped in a function say newShadowText()

function newShadowText(theText, theFontName, theFontSize)
 local container = Sprite.new()
 stage:addChild(container)

 container.text = theText or "Untitled"   --> Change to whatever default text you want
 container.textColor = 0xff0000
 container.shadowColor = 0x0000
 container.fontName = theFontName
 container.fontSize = theFontSize or 12
 
 local _text, _shadow, _font
 
 function container:setText(theText)
  self.text = theText
  _text:setText(theText)
  _shadow:setText(theText)
 end

 function container:setTextColor(theTextColor)
  self.textColor = theTextColor
  _text:setTextColor(theTextColor)
 end 
 
 function container:setShadowColor(theShadowColor)
  self.shadowColor = theShadowColor
  _shadow:setTextColor(theShadowColor)
 end
 
 function container:setFont(theFontName, theFontSize)
   self.fontSize = theFontSize
   self.fontName = theFontName
   self._font = TTFont.new(theFontName, theFontSize)
   
   _text:removeFromParent()
   _shadow:removeFromParent()

   collectgarbage("collect")
 end

 function createText()
  _text = TextField.new(self._font, self.text)
  container:addChild(_text)
  _shadow = TextField.new(self._font, self.text)
  container:addChild(_shadow)
  _shadow:setPosition(1, 1)

 _text:setTextColor(self.textColor)
 _shadow:setTextColor(self.shadowColor)
 end 
 
 createText() 
 
 return container
end 

Now we can use this function to create text with shadows and change the font, colour or text as we want. It is as simple as using

  local sT = newShadowText("Hello, shadow text")
  st:setPosition(100,100)
  st:setTextColor(0x00ff00)

NOTE: If you want to use fonts in Gideros, the .TTF file has to be included in the project and the fontName has to reflect the exact name of the .ttf file. If you have the font file included into your project, let’s say it is called customFont.ttf then you can use it as

 st:setFont("customFont.ttf", 24)  --> This will change the font

Hope this is useful in your projects.

Social tagging: > > >

Comments are closed.