Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Looking for feedback/suggestions on my free bitmap font library (bit like TextCandy ...)
Started by paulscottrobson May 08 2014 01:11 PM

* * * * * 1 votes
121 replies to this topic
[TOPIC CONTROLS]
Page 1 of 5 1 2 3 »
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

I'm releasing my font manager / bitmap strings library (MIT license, so it's free to use).

 

There are two links for it ; one is a demo, which shows some of the features in a q & d fashion, the other is the library itself. It can be used for text effects in menus and instructions, scores in games and so on.

 

Demo https://github.com/autismuk/Font-Demo

 

Library https://github.com/autismuk/Font-Manager

 

It can do this sort of stuff - this is an example showing three fonts produced using Glyph Designer very easily. You can't tell from the picture, but the bottom one of the three is animating a nice sine curve.

 

To reproduce this line you just need this line of code (curve is one of the built in modifiers - you can write  your own if you want to do something really weird ....)

display.newBitmapText("This is text",160,240,"font1",40):setModifier("curve"):animate()

 

fontdemo.png



[TOPIC: post.html]
#2

Gremlin Interactive

[GLOBAL: userInfoPane.html]
Gremlin Interactive
  • Enterprise
  • PipPipPipPipPipPip
  • 699 posts
  • Jedi

I posted in another thread you created, but just want to say: well done! again.

I tried out your demo and it is excellent :)

If you want suggestions for more text effects... One i have always liked is the text effect used in the call of duty games. I think the best one to showcase this was in "call of duty modern warfare 1"

I'll try and find you a vid if needed. It is a really nice text effect, with random letters in the string fading out at the end, and the whole string being created initially by cycling through random individual letters and stopping at the needed letter to make up the whole word.

Of course, we could create this ourselves, but thought i would throw it out there, seen as though you asked for suggestions :)

[TOPIC: post.html]
#3

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Pro
  • PipPipPipPipPipPip
  • 1,112 posts
  • Jedi

I want to take a look at this, but off the top of my head (not knowing the specifics of your implementation), I'd need:

 

1. Multibyte character support (gotta support JP+KO+ZH)

2. Word-by-word effects (though personally I'd only need fade or "pop". nothing fancy.)

3. Line break support. (A good game text display is usually two lines with 8-10 words.)

 

To be more specific, I'd look to fill the requirements of this blog post (Gamasutra).



[TOPIC: post.html]
#4

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Some good ideas - this first was in the pipeline, the second I hadn't considered (you could do it now but I'll make it a lot easier with a small change, you'd have to track the words yourself at the moment) and the last isn't supported yet, but isn't an enormous change.

 

Cheers.



[TOPIC: post.html]
#5

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Pro
  • PipPipPipPipPipPip
  • 1,112 posts
  • Jedi

Actually, one final improvement comes to mind: tinting. As the link explains, there is real value in color changing specific words, and Corona allows using setFillColor to tint graphics.

The only trick is that you'd need to develop a short code for it, so maybe it's a change I have to add on later...

[TOPIC: post.html]
#6

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Hi, me again. The extended character set is something I hadn't previously considered, and lua is just streams of 8 bit data. Is the best encoding format UTF-8 ?

 

GlyphDesigner seems to use 8 bit ASCII in its fonts. Some others don't and use 16 bit character codes :)

 

Multiline works - word effects isn't done yet but is easy to do, tinting I haven't yet looked at.



[TOPIC: post.html]
#7

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Pro
  • PipPipPipPipPipPip
  • 1,112 posts
  • Jedi

Yeah, I think UTF8 is what you need? Wouldn't be too hard to test, at least - add a weird character to a bitmap font, try adding it to the string too, and see what happens...



[TOPIC: post.html]
#8

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Cheers :) I should probably get it working tomorrow. Not sure about the tinting, haven't looked at that yet.



[TOPIC: post.html]
#9

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Pro
  • PipPipPipPipPipPip
  • 1,112 posts
  • Jedi

In theory, it's not too bad. The process would have to go something like this:

 

1. Use invented shortcodes in the string supplied. Maybe %red%, %blue%, etc. Depends what would cause the least problems with gsub. Each shortcode (and associated 0-1,0-1,0-1 color) would need to exist in a table. Add %default% wherever color should revert to normal. (Or go with an HTML style encapsulating method, either way...)

 

2. Write a function to intercept the string during a newBitmapText() call:

- Use string.gsub or such to look for valid shortcodes

- Record which words (or characters) need color changes.

- Remove the shortcodes from the string (so it reads properly)

 

3. When rendering the bitmap characters from imageSheet, look for a .color property. If found, :setFillColor() using whatever the shortcode color was.

 

(I believe Corona pro has a seperate tinting function through graphics.*, but :setFillColor() should still work, I think. Although the effect will vary a lot based on the actual font images themselves.)



[TOPIC: post.html]
#10

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Doesn't quite fit the design. It's designed so that simple f/x are dead easy, but if you actually want to zoom characters in and out individually, spin them round individually, and rotate/scale/translate the whole thing you can, but it needs a little coding (usually 2-4 lines !)

 

Probably something like have an overall method, setTintColor(), then some sort of character level tint, then finally render-modifying the final bitmap.  It really depends on how well it works, I'll experiment with it and see what happens.

 

Probably code up the word and line level functionality first, and release that as an interim (UTF-8 and Multiline are already in, though not as tested as much as I'd like, especially the multiline stuff, there's a bug to fix if you print multiline text backwards (not quite sure why I did this ...)



[TOPIC: post.html]
#11

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Okay, well it now has character/line/word functionality and supports multi-line and UTF-8 :)

 

Haven't started with the tint yet, probably be in a couple of days. 



[TOPIC: post.html]
#12

ingemar

[GLOBAL: userInfoPane.html]
ingemar
  • Enterprise
  • PipPipPipPipPipPip
  • 2,144 posts
  • Jedi

This is quite awesome!

Great work.



[TOPIC: post.html]
#13

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

I posted in another thread you created, but just want to say: well done! again.

I tried out your demo and it is excellent :)

If you want suggestions for more text effects... One i have always liked is the text effect used in the call of duty games. I think the best one to showcase this was in "call of duty modern warfare 1"

I'll try and find you a vid if needed. It is a really nice text effect, with random letters in the string fading out at the end, and the whole string being created initially by cycling through random individual letters and stopping at the needed letter to make up the whole word.

Of course, we could create this ourselves, but thought i would throw it out there, seen as though you asked for suggestions :)

 

I'd really like to see that. It's certainly do-able on what you describe.



[TOPIC: post.html]
#14

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Now supports font tinting, partially. You can tint the whole thing, or using the modifiers, but there is no easy syntax for it - considering something like "Hello {red}World {1,0,1}more" sort of syntax for colouring individual letters easily.

 

Picture shows multi line, UTF-8 (character after 'curve'), word effects, tinting. Not the animation obviously :)

 

snap2.png



[TOPIC: post.html]
#15

Gremlin Interactive

[GLOBAL: userInfoPane.html]
Gremlin Interactive
  • Enterprise
  • PipPipPipPipPipPip
  • 699 posts
  • Jedi

Now supports font tinting, partially. You can tint the whole thing, or using the modifiers, but there is no easy syntax for it - considering something like "Hello {red}World {1,0,1}more" sort of syntax for colouring individual letters easily.

Picture shows multi line, UTF-8 (character after 'curve'), word effects, tinting. Not the animation obviously :)

snap2.png


This keeps getting better and better!

Thanks for your continued efforts on this. You have saved me from reinventing the wheel for a game i am working on.

Btw, i'm sure a lot of people would be willing to pay for this, when you deem it finished.

Keep up the great work :)

If you are ever in Ireland, i'll have to buy you a pint of Guinness ;)

[TOPIC: post.html]
#16

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Pro
  • PipPipPipPipPipPip
  • 1,112 posts
  • Jedi

Tried out the code briefly this morning. The code itself is very impressive; the OO approach kind of makes my head spin, but clearly it works.

 

1. You say the fonts directory is where the lua should go, but that's not actually the case. Only the png and fnt files should go there.

2. Near display.newBitmapText() you claim it's not multiline compatible.

3. You say that .x/y cannot be set after the fact? Are you not grouping the font characters into a display.newGroup()?



[TOPIC: post.html]
#17

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Yes (the tinting inline now works as well). Thanks for those. They are hangovers - originally I converted the .fnt to a file so I can require it, but now it just scans the .font file, it wasn't multiline compatible originally.

 

The .x,.y can be set for the view group. 

 

It is a bit confusing. This is partly deliberate - I wanted to be able to have something like the display.newText() call because that's how Corona is designed, so the display.newBitmapText is a wrapper.

 

The problem with that  is, what it returns isn't any sort of display object - hence there is the getView() call - all the transitions refer to getView(). It can't be treated like a displayObject, you can insert it into groups and things but you have to be careful.

 

It tends to have two of everything because of this. It's a good idea to move it either with transition.to or setting x,y on the viewGroup, which works as normal, or to use the :moveTo() classes which also works, but if you try to do both it can get confusing as one ends up offsetting the other.

 

The driver is actually the singleton FontManager class, which updates the strings and does the animations,  this maintains a list of the strings and updates them if necessary. 

 

It is not best to use it in complex code but to use the strings as individual objects in a scene - this isn't really a problem, because it would normally be used for title screens or scores (this is why it does vertical text as well), and use the clear call to clean up (or remove() them manually).

 

Because it's not a proper display object it can't clear itself up with string:getView():removeSelf() - it doesn't work, it will leave the string behind because there is a lot of support stuff in there besides the display objects. Hence it has its own string:remove() method which clears everything up. It can't be integrated in quite the same way as Corona Objects can be.

 

I don't think it's practical (unfortunately) to implement it as a pure Corona extension, it is doable but it would be extremely vulnerable to changes in the way Corona works.

 

The OO doesn't really matter - it's much the same as Corona in many ways. I do like chaining stuff which Corona doesn't support but it's just shorthand for multiple calls

 

instead of

x:setFillColor(0,1,1)
x.setStrokecolor(1,0,1)

you just have

x:setFillColor(0,1,1):setStrokeColor(1,0,1)

which is neater :)



[TOPIC: post.html]
#18

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Basic
  • PipPipPipPipPipPip
  • 294 posts
  • Jedi

very nice, i've actually been waiting (aka hoping) for someone else to come along and update the bmfont loader code. :D
(i know bmGlyph has updated their support code, but i don't necessarily need their whole product)

my two cents, for what it's worth, would be a request to begin now (before it's too late) to decouple the "base" font support from all the various "effects" and "formatting" stuff. make some mechanism for "extending" or "plugging into" the base with effects/formatting/etc modules if/as required.

one thing this'll 'force' you to do is make sure all the necessary properties in base are adequately exposed, which also will make it easier for end-user to plug in their own variants. for example, most of your effects i could do without, but i'd like to know i could plug in my own (without any dependence on how YOU would do it) because all the right 'access points' are available, as i don't necessarily need 'yet another' sinus scrolly written by a third party:   ;)



so base would make available methods to get individual chars, words, lines, etc; formatter module would handle assembling them as desired (multi-line? vertical stack? following a curve? etc); effects module would handle frame loops, registering 'tweens' and other modifiers, and such.

that's probably asking for a big architectural change, but i'm just throwing it out there for your consideration, as i think the most important part is having a rock solid (and clean/uncluttered) base, making everything else (the 'candy' portion) optional.

fwiw, cheers



[TOPIC: post.html]
#19

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

That's not far off what happens. It's designed to be trivially easy to use if you just want a sine text but fairly extensible.

 

(Incidentally, it is MIT license, open source on github, so it's not dependent on me at all, though obviously I know best how it works !)

 

Basically it renders it as straight boring square text aligned neatly - this arrangement goes to drive the positioning stuff, irrespective of where the fonts actually end up.

 

Everything else is done using modifiers, which can be ignored if you just want straight text. These apply after the effect modifications to the bitmaps, however you like, individual characters, words, lines, over the whole thing, whatever pretty much you want.

 

So supposing you wanted the third word to be twice the size your modifier and rotated 45 degrees (the characters, not the whole thing) would be something like.

if info.wordIndex == 3 then modifier.xScale,modifier.yScale = 2 modifier.rotation = 45 end 

The built in ones all use that system, they are all about 2 or 3 lines of code each (there is a helper function which calculates bits of curves). These only affect how the text looks - where the bitmaps end up and how they are rendered, rather than how anything else actually behaves (except if you use an event listener, tap/touch are dependent on where the bitmaps actually are).

 

If you have a look at the main github archive, the demo flashes the letters of the word 'pulse' individually in sequence. This is the code for the modifier (can be a class instance or function) which does that.

 
(info.elapsed is the time since first display, info.index the current character number, info.length the current line length)
function pulser(modifier, cPos, info)
	local w = math.floor(info.elapsed/360) % info.length + 1 				 	
        if info.index == w then
		local newScale = 1 + (info.elapsed % 360) / 360
		modifier.xScale,modifier.yScale = newScale,newScale				
		modifier.tint.red = 0
	end
end

Your effect would be a little more complicated than the standard curve, because the curve scale changes over time - probably an extra line or two :)



[TOPIC: post.html]
#20

richard9

[GLOBAL: userInfoPane.html]
richard9
  • Pro
  • PipPipPipPipPipPip
  • 1,112 posts
  • Jedi

I don't really understand *why* your bitmap text objects can't be treated like regular display objects (or groups)? I mean, you still have to bring the frames in using display.newSprite and the sheet in with graphics.newImageSheet. Not to question your approach, just honestly unaware of the strategy behind it. :-)

[TOPIC: post.html]
#21

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

They can be up to a point. It should work as normal.

 

What doesn't happen , at the moment, is the clearing up bit. If you access the view group it should work like any other Corona display object, but the object itself isn't a display object, it's a class which manipulates display objects with a common group.

 

I have some ideas about how to improve the situation so it can respond appropriately if it is removed by (say) being part of a group which is removed. According to the SDK docs it sets the view groups metatable to nil if it is removed, so it should be possible in that case to detect that and remove the object references and so on. 

 

I will give it some thought.

 

L8R: If you create a text string and do str:getView():removeSelf() it crashes, which isn't a surprise, but something I need to fix.



[TOPIC: post.html]
#22

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Okay that was probably not a sensible thing to do, but I am concerned at composer's garbage collection (which doesn't seem to work properly) and also the display.remove() which may be related. It would appear that nesting groups doesn't clean up properly - the bitmapstring is a group of bitmaps, which in Composer ends up inserted into the scenes own group, if it garbage collects it apparently doesn't do anything to the group or the contents..... am awaiting some clarification on this problem.



[TOPIC: post.html]
#23

Alex@PaNc

[GLOBAL: userInfoPane.html]
Alex@PaNc
  • Pro
  • PipPipPipPipPipPip
  • 813 posts
  • Jedi

For those that are using this library, opengameart.com has a great collection of bitmap fonts that would work well.

 

 

http://opengameart.org/content/bitmap-font-pack



[TOPIC: post.html]
#24

paulscottrobson

[GLOBAL: userInfoPane.html]
paulscottrobson
  • Pro
  • PipPipPipPipPipPip
  • 364 posts
  • Jedi

Do you know if this is a common format for bitmap fonts ? Could do it one of two ways ; could modify the library to read them (it is expecting FNT/PNG files as in Glyph Designer) or simply write code to generate the FNT file to match ? 



[TOPIC: post.html]
#25

Alex@PaNc

[GLOBAL: userInfoPane.html]
Alex@PaNc
  • Pro
  • PipPipPipPipPipPip
  • 813 posts
  • Jedi

@paul, I haven't used your library (definitely going to; it looks superb) but I figured those fonts would work out well. The .zip file does have all fonts as PNG files. Should I be looking for a specific bit sizes? Let me know and I'll modify my post. Thanks!




[topic_controls]
Page 1 of 5 1 2 3 »
 
[/topic_controls]