Jump to content

DrawText question


havenphillip
 Share

Recommended Posts

Is there a simpler way to center text so that it doesn't depend on the left margin? I have this counter and it looks right until it goes less than 100 and then less than 10. At that point it looks out of place. I thought I'd use "if self.timer...then self.textPos..." but then the text slides across the whole screen the whole time it's in the timer range. I want it to scoot over once then stop. How do I stop it?

 

    context:DrawText(""..Math:Round(self.timer),self.textPos, 465)

    --text positions
    if self.timer >= 100 and self.timer <= 999 then self.textPos = self.textPos  end
    if self.timer >= 10 and self.timer <= 99 then self.textPos = self.textPos +4  end --slides across screen at a rate of "4"
    if self.timer >= 0 and self.timer <= 9 then self.textPos = self.textPos +8  end --slides across screen at a rate of "8"

Link to comment
Share on other sites

Ok like if the countdown is 100 the text is centered where I want it to be but once it goes to 99 it looks slightly left since it loses that third digit place. So I want to keep it looking centered as it counts down and my solution was to shift it over slightly so it looks centered at 99 like it does at 100. But my problem is I'm animating it across the screen. I just want it to scoot over a bit then stop moving.

offcenter.png

Link to comment
Share on other sites

Ah I get it now. The best solution is not applying any 'move over' margin at all. Instead do the following:

  1. Lets say your health circle is 200 px wide. 
  2. Get center position of the health UI: centerUiX = ScreenWidth - (healthCircleWidth/2)
  3. Get the healthAmountWidth of the text every frame. There is a leadwerks API command for that.
  4. Subtract half of the text width from the centerUiX: drawX = centerUiX - (healthAmountWidth/2)
  5. Draw the text with drawX;

You can also use FlowGUI (free for download at https://bitbucket.org/Aggror/flowgui/src). I don't know if the official leadwerks UI has text centering.

Link to comment
Share on other sites

OK that'll take me a minute. Let me see if I can do that. The healthAmountWidth every frame? Is that just context:GetWidth?

I got the FlowGUI. I've looked through it before. It seems really cool but it's out of my league. If only there were a tutorial or something on it (cough cough).

Link to comment
Share on other sites

Technically you would only have to recalculate the position if your health changes, but it can't hurt to do it every frame.
Context:GetWidth will get you the width of your game window.
GetTextWidth, will get get you the length of a text string. https://www.leadwerks.com/learn?page=API-Reference_Object_Asset_Font_GetTextWidth 

Alternatively with FlowGui.

Best to download the sample project and opening a sample scene with text element. From the top of my head

  • create a pivot and attach flowgui manager lua script
  • create a pivot and attach label style lua script (here you can fine tune font, text size, color, center positioning)
  • create a healtbar script (your existing script) which references the label style and flowgui manager. Add something like this:
--Load FlowGUI if a script makes use of it.
import "Scripts/FlowGUI/FlowGUI.lua"

Script.guiManager = nil --entity "GUI manager"	
Script.healthLabelStyle = nil --entity "HealthLabelStyle"
Script.healthLabel = nil

function Script:UpdateWorld()	
	self.healthLabelStyle = self.healthLabelStyle.script:GetStyle()
	self:CreateLabel()
end

function Script:CreateLabel()
	self.healthLabel = FG_Label:Create()
	self.healthLabel:SetPosition(Vec2(200,120))
	self.healthLabel:SetScale(Vec2(150,50))
	self.healthLabel:SetText("Your health")
	self.healthLabel:SetGUIStyle(self.healthLabelStyle)
	self.healthLabel:SetTextPosition(FG_TextPosition.Center)
	self.healthLabel:SetDebug(false)	
	self.guiManager:AddElement(self.healthLabel)
end

function Script:PostRender()
	self.healthLabel:SetText("Your updated health")
end

 

Link to comment
Share on other sites

Ok this is what I have. If I put it under PostRender() it loads the font like every second. Doesn't do that if I put it under Start() but I think that would probably defeat the purpose. The other thing is it doesn't move position when it changes from 100 to 99.

    --text positions
    font = Font:Load("Fonts/arial.ttf",10)
    context:SetFont(font)
    centerUiX = self.cirPos.x - self.radius/2
    timeX = font:GetTextWidth(text)
    drawX = centerUiX - timeX/2

   (self.cirPos.x is context:GetWidth I'll clean that up)

I'm going to try this with your  FlowGUI. Also it's a countdown timer, though. Not health. I don't know if that changes anything. I think that may be why it's loading the font every second.

Link to comment
Share on other sites

You can load the font in the start function, and set the font in the postrender function.

self.font = Font:Load("Fonts/arial.ttf",10)

You can clean it up (like you already said) with something like this:

centerTimerX = context:GetWidth() - (timerAreaWidth / 2)
drawX = centerTimerX - (font:GetTextWidth(text)/2)

You can also System:Print(font:GetTextWidth(text)) to see if the width of the text is actually changing. 

 

Sorry I was thinking of a healthbar for some reason, but it doesn't matter for its purpose.

Link to comment
Share on other sites

Oh duh of course load the font in the Start()!

It's not changing position. I'm not sure at what point we told it to. Tried System:Print it's telling me "argument #3 is 'string';'[no object]' expected. I'm not sure maybe I'm not putting the right thing in the brackets. I've tried "text" and "self.timer"

I tried with FlowGUI it's telling me "attempt to index field 'healthLabel' (a nil value) --line 93

line 93:

    self.healthLabel:SetText("Your updated health")

I'm not supposed to child something to something or anything else, right? I created the two pivots with the correct scripts.

 

Link to comment
Share on other sites

"argument #3 is 'string';'[no object]' 

means that you put in an object rather than a string. Can you post the code were you print info?

 

I tried with FlowGUI it's telling me "attempt to index field 'healthLabel' (a nil value) --line 93

Can you screenshot the scene tree were you have created the style, guimanager? Child/parent isn't really required but helps organising the scene. As long as the guimanager is loaded first and the styles are being loaded before you create the label, everything should work. If you look at any example scene from the FlowGUI project, you can see that I like to organise my scene as follow:

  • pivot-GuiManager (gui manager script attached)
    • pivot styles (no script attached)
      • timerLabelStyle (labelstyle script attached)
  • mycustomobject (in your case the timer)
    • Referencing GUI manager and Timer lablestyle.

here is loading the ui style with a wait time build in. I am not at home, so haven't tested it.

--Load FlowGUI if a script makes use of it.
import "Scripts/FlowGUI/FlowGUI.lua"

Script.guiManager = nil --entity "GUI manager"	
Script.healthLabelStyle = nil --entity "HealthLabelStyle"
Script.healthLabel = nil

Script.uiLoadInterval = 1
Script.startTimeStamp = nil
Script.uiLoaded = false

function Script:Start()
	self.startTimeStamp = Time:GetCurrent()
	self.guiManager = self.guiManager.script	
end

function Script:UpdateWorld()	
	if self.uiLoaded == false and Time:GetCurrent()-self.startTimeStamp > self.uiLoadInterval then
		self.healthLabelStyle = self.healthLabelStyle.script:GetStyle()
		self:CreateLabel()
		sel.uiLoaded = true
	end
end

function Script:CreateLabel()
	self.healthLabel = FG_Label:Create()
	self.healthLabel:SetPosition(Vec2(200,120))
	self.healthLabel:SetScale(Vec2(150,50))
	self.healthLabel:SetText("Your health")
	self.healthLabel:SetGUIStyle(self.healthLabelStyle)
	self.healthLabel:SetTextPosition(FG_TextPosition.Center)
	self.healthLabel:SetDebug(false)	
	self.guiManager:AddElement(self.healthLabel)
end

function Script:PostRender()
	if sel.uiLoaded then
		self.healthLabel:SetText("Your updated health")
	end
end

 

Link to comment
Share on other sites

Yeah here's scene tree gui:

Now I"m getting: attempt  to call method 'AddElement' (a nil value) -- Line 70

Line 70:

    self.guiManager:AddElement(self.healthLabel)

I don't know why it would be nil.

Here's my current script. You can see it's a mess. System:Print is currently under PostRender near the bottom.

"Timer" is this script on the tree.

correctscripts.png

Countdown Circle.lua

Link to comment
Share on other sites

We are getting closer. So for some reason the Flowgui manager is empty in your script. Is it referenced in your countdown script? 

Instead of linking in the flowGUI manager, you can also create it by script. Note that you only need 1 flowguiManager. So you would either place it in main.lua or you have to make sure it is made only once.

self.flowGUIManager = FlowGUI_Manager:Create(Window:GetCurrent(), Context:GetCurrent() )

 

 

Link to comment
Share on other sites

There is also a way to center text inherent to LE in available parameter settings not in the official documentation, but was posted at one point in the gui development blog,

virtual void DrawText(std::string& text, const int x, const int y, const int width, const int height, const int style = 0);//lua

So in your example, I would set the x and y positions as the upper left hand corner of the circle's image and the width/height as the width and height of the circle.

Example showing drawing text within the center of a rectangle where the text width is changing and the style parameter settings are keeping it centered:

window = Window:Create("example",0,0,400,400)
context = Context:Create(window)
world = World:Create()
light = DirectionalLight:Create()
light:SetRotation(45,45,0)
camera = Camera:Create()
camera:SetPosition(0,0,-3)

counter = 1400
toggle = 0
myfont = Font:Load("Fonts/arial.ttf", 36)
context:SetFont(myfont)

while not window:KeyHit(Key.Escape) do
	if window:Closed() then return false end

	if toggle==1 then counter = counter + 10 end
	if toggle==0 then counter = counter - 10 end
	if counter>=1400 then toggle = 0 end
	if counter<=10 then toggle = 1 end

	Time:Update()
	world:Update()
	world:Render()

	context:SetBlendMode(Blend.Alpha)
	context:SetColor(1,0,0,.5)
	context:DrawRect(38,30,300,300,1,30)
	context:DrawText(string.format("%.0f",counter),38,30,300,300,Text.VCenter+Text.Center)
	context:SetColor(1,1,1,1)
	context:SetBlendMode(Blend.Solid)
	context:Sync(true)

end

 

fontcenter.jpg

  • Thanks 1

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

I still want to learn that FlowGUI though. I studied some of the sample maps but the scripts call scripts that call scripts. Where's the starting point if I want to understand it? I want to read it all and understand the step by step logic. Where do I start? What's the first script? I also don't understand how you don't use the format "function Script:Start()" for instance but do things like "function GetGuiElements(guiType)". Reminds me of Rick's State Machine Coroutine thing he posted which  I also can't make sense of.

 

 

Link to comment
Share on other sites

If you still want to use FlowGui, there is a small wiki: https://bitbucket.org/Aggror/flowgui/wiki/GUI Manager

here is how a minimal example would work:

  • import flowGui somewhere in your main.lua
  • create a flowGui manager
  • create a gui element and add it to the manager. (styles are not even needed to get a ui element to work. )

Remember that FlowGui is no longer being developed and that is there is an official Leadwerks ui that has been released.

  • Thanks 1
  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...