Thursday 29 May 2014

More stuff ....

Not posted much for a few days - this is what I've been up to.


  1. Bug fixing / improving / tweaking the Bitmap Font system, known as "Font Manager". Even though it doesn't. This is now perfectly useable (padding is not supported but will be added soon) and pretty stable and appears to work.
  2. There's a new repository called 'Particle Classes' which are some simple classes which wrap the Particle System in Corona.
  3. I've written a Component/Entity/System library (called 'Comet') which is an alternative game framework. This is still really in beta, but there is a demo of it in the github repository.

Saturday 24 May 2014

Animation Manager renamed

To Coccyx. Well I got fed up with dull names. It's a little bit of the spine .....

I hope to start some more experimenting with this now I'm happy the Font tool is in a stablish state.

https://github.com/autismuk/coccyx

Friday 23 May 2014

Re-engineered Font Manager

The font manager has been replaced by something which does the same thing, but it has been rebuilt largely from scratch.

It offers most of the same functionality, actually slightly more. The main change is that it is now a display object in its own right rather than pretending to be one. So you can use it much as if it was a display.newText() object.

The one downer is that if you turn animation on, and you rely on the system to remove it, (e.g. garbage collection in Composer) it will keep the reference to the bitmap string - it needs it to generate the animations.

So in your exit events, turn animations off on any bitmap strings you use (or remove them). If it's not animated, there's no reference.

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

List of changes

a) setScale() no longer functions. Adjust font size to suit, or scale overall.

b) there is no FontManager object, really, though setEncoding(),setTintBrackets() and setAnimationRate() still work as there is a 'pretend' FontManager. These are now all methods of BitmapString, though all affect the global state of the fonts, so setAnimationRate() sets the rate for all the bitmap strings, not just one.

c) curve and scale have been switched so they are the right way round. Previously they were 'visual' opposites.

d) FontManager:Clear() does not exist. The primary reason for this is that it maintained a reference to the object. If there is sufficient demand I will add a tracking of creation on demand approach which will do the same thing.

e) You cannot directly subclass BitMapString, because it is now a mixin.

Your new method for a subclass should look something like

local function SubclassBitmapString:new(font,fontSize)
local newInstance = BitmapString:new(font,fontSize)
.. do class specific initialisation.

.. create mixin - you can do this with a for loop as well.
newInstance.someFunction = SubclassBitmapString.someFunction

return newInstance
end

f) Curve is now a static class in its own right rather than being a method of FontManager.

Thursday 15 May 2014

Support for tinting added.

FontManager can now tint characters - change their colours, effectively. If you have a white font, this gives you a multicolour font.

Multiline, tinting and UTF-8
support added.
There are three ways to do it - you can set the tint for the whole string using a method, you can use modifiers to change it (e.g. the e in pulse) and you can put inline colour definitions.

e.g. Hello{blue}World ! This {1,0,0.5}is {} text"

The {} can be set to any pair of bracketing characters that are not alphanumeric or a decimal point.

Both the library and demo have been updated for the new improved library - though the demo is still unchanged.


Wednesday 14 May 2014

FontManager enhancements

Thanks to Richard9 on the forums who gave me some good ideas for enhancing the font library. It now supports the following

  • Multiline text - separate with \r or \n - this only works in forward or backward orientation ; vertically orientated text doesn't start a new line.
  • Support for extended characters. Originally it just used unicode strings (e.g. 0-255) but it can now cope with UTF-8 strings up to two bytes long - if anyone wants three or four byte UTF-8 characters please let me know and I will code it.  These are still, however, converted to unicode characters, all the font designers use unicode as far as I can tell !
  • Word and Line effects. So for example, pulse originally operated on individual characters, now you can easily pulse words in a line, or lines in a multiline, or do anything with it really :)
Richard also suggested tinting characters, which I will experiment with. I'm not totally convinced what the API should be yet, but it will be consistent with the multi-level design.

One feature of the multiline text is that in bmglyph and Glyph Designer fonts the height is often more than you think it is - there seems to be a tendency to have odd characters will really low descenders or high ascenders (?) especially if you use exotic fonts. This means the text in multiline text is further apart than looks natural. 

This actually threw me for a while, I was sure the spacing had to be a bug. It wasn't until I looked at the .FNT file that I actually realised it was right.

However, to fix this there is a new method setVerticalSpacing(scalar) which is a scalar (default value 1) applied to the vertical spacing so you can squeeze or stretch this to your hearts content.


You can see most of these things by running the main.lua and experimenting with it.

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

Monday 12 May 2014

FontManager, small API change

Well, I don't like changing the API of something that's been released, but in this case it's necessary.  It  only affects the call to the modifiers and I suspect no-one other than me has written one yet.

It was a bad call in the first place anyway - in the modifier calls, the parameters are normal parameters, but in the extensions I have in my head it would end up with ten of them :(

What I have changed is the signature of the modifier, rather than providing the information as a parameter e.g.

function pulser(modifier, cPos, elapsed, index, length)

it passes everything except the first two as a table

function pulser(modifier, cPos, info)

the names are the same, so to use it in modifiers all you need to do is add "info." before elapsed, index and length so this:

function pulser(modifier, cPos, elapsed, index, length)
local w = math.floor(elapsed/250) % length + 1
if info.index == w then  
local newScale = 1 + (elapsed % 250) / 250
modifier.xScale,modifier.yScale = newScale,newScale
end
end

becomes this:

function pulser(modifier, cPos, info)
local w = math.floor(info.elapsed/250) % info.length + 1
if info.index == w then  
local newScale = 1 + (info.elapsed % 250) / 250
modifier.xScale,modifier.yScale = newScale,newScale
end
end

internally there is a bit of reengineering to support some new features, but externally this is the only change.

Sorry ! It shouldn't happen again.

Sunday 11 May 2014

Experimenting with Skeletal Animation ideas.

Graphics by Ray Wenderlich
I've been experimenting with some Skeletal Animation bits and bobs. The demo shows my first go, on the right (the Elf image is from Ray Wenderlich's Spine Tutorial)

Actually it's the second go but I can't draw for toffee, you wouldn't have wanted to see the original graphics....

I wanted something Spine-esque but simpler, however great Spine is the Corona library doesn't work (v1 Graphics) and it's still £100.

This makes some simplifications for simplicity and speed. All the graphics have to be aligned vertically top-up and their anchor points are on a vertical line through that graphic, though they can be moved up and down that line - see where the anchor point is on the bottom part of the body, it's 20% inwards.

This vertical line can be moved though - if you look at the legs the vertical line is way over to the left

If you look below (perhaps) you can see the arm - having it automatically in this vertical position saves a lot of math, but it does add limitations

The arm - notice
the vertical orientation
Any of those images can be placed between any two points on the skeleton (highlighted for debugging purposes as a yellow line) and then those points can be moved arbitrarily.

The big advantage of the simplification in the graphics bit is that there is no complex munging of the image or the line to make it work, it is about 3 or 4 Corona API calls and a little bit of simple mathematics.

I plan to experiment a bit further and then once that's done see if people have any useful suggestions or ideas.

The development version is currently at https://github.com/autismuk/coccyx and should normally be in a working state though of course it is in regular development.

Saturday 10 May 2014

A minor tweak

When I was writing the demo, I realised it would be handy if I could arbitrarily remove strings as well as add them - completely remove them from the whole system.

The FontManage controls the texts - it has an internal list of them. So if you remove a text from the view say, it will still physically be there, creating resources. It's really needed for transient displays, so suppose you pop up a screen over a game displaying some information and want to use a bitmapped font, then you can create bitmap strings on entry and remove them on exit.

None of this should affect any prior written code in any way.

Wednesday 7 May 2014

Think it can go out now.....

Demo Program
So my font manager is ready to go, in alpha (beta ?).

Apart from the sort of running commentary here, there are two places to go - first is the demo program, shown on the right.

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

This is a quick and dirty program that displays various text effects in action, built in and coded ones. There are six (four of which are built in).

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

is the other, which is the current version of the library and has its own demo program.

All the code is commented and the library has a HTML document file.

One thing the demo doesn't show (but the demo program in the library does) is that you can transition these objects like anything else.....

Tuesday 6 May 2014

Github Cloning issue

I did have one problem. I was using links to keep libraries in sync, there's a copy of the transition manager in the scene manager.

Git stores them as links, so if you clone SceneManager it wouldn't work, because the link goes nowhere. They are now hard copies, annoyingly.

Git does do sub projects and things, but it seems a nightmare just to have one file out of a repository and have that kept up to date.

luavadoc (sic ?)

The documentation of the libraries leaves a little to be desired (euphemism for 'rubbish') so I have been working on that ; I have created my own version of Javadoc for Lua - which is designed to operate in sync with my coding style. It's in github, but it's pretty useless if you don't code like me.

So, I've been working on the three libraries bringing them more up to scratch, commenting main.lua and other bits that needed it and so on. So far, I have only done the transition manager https://github.com/autismuk/Transition-Manager

The doc does come up as HTML, but I haven't figure out (yet) how to set up git so that html files within git display as html rather than as the raw text.

L8R: Have done the same for Scene Manager.
Even L8R: Have done the same for Font Manager.

Monday 5 May 2014

Something close to releasable .....

Too much of this stuff will give you
a headache
I must figure out a way of saving videos from the Simulator.

Anyway, this is sort of releasable, a version 0.1 alpha, or as Microsoft would call it 'bug free final release'. It needs commenting more and documenting better, well at all :)

Also, I think I'll make it so it reads the .fnt file in directly rather than parsing it separately. And it needs a better demo than what I have here (latest state of my testing)

You can't really see it here, but the top curve is oscillating, the middle word 'pulse' is highlighting each letter in turn by blowing it up, and 'Another one' is wobbling.

These are standard effects (except for pulse) - there is a fourth at the bottom right as well.

All of these are being transitioned.to ; one of the pleasant surprises is that you can scale a view and its parts independently, so the 'pulse' is being zoomed at the same time as the letters are.

The code to do this is not too long winded. The blue bits are usual Corona stuff ; the other four colours show the creation of four different strings.  The only thing that's unusual is the pulser() function.

It works out the current character by dividing the elapsed time in ms by 360 and making it in the range 1 .. length (the string length), that character (index identifies the character) then is scaled to 2,2. If you uncomment the modifier.rotation line it spends while it is highlighted which is nifty from a demo point of view but completely unreadable. It just bangs it out there x 2 at the moment but it wouldn't be hard to make it zoom.

The thing I like about this is you can do all kinds of utterly insane things with it if you want, but if you just want a simple effect there's a library of them (currently only about six of them)

The animate() methods tell it to animate - if you don't have this it just applies it once and leaves it, so you'd get a non moving curve on "Another demo curve" for example.

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

display.setStatusBar(display.HiddenStatusBar)

fm = require("system.fontmanager")

local str = fm.BitmapString:new("retrofont",48)

str:moveTo(160,240):setScale(2,2):setText("Another demo curve")
str:setModifier("curve"):animate(4)

local str2 = fm.BitmapString:new("font2",45):setDirection(270):setText("Bye!"):setAnchor(0,0):setScale(-1,1)

local str3 = fm.BitmapString:new("demofont",30):moveTo(160,400):setText("Another one"):setScale(2,2)

str3:setModifier("wobble")
str3:animate()

function pulser(modifier, cPos, elapsed, index, length)
local w = math.floor(elapsed/360) % length + 1
if index == w then 
modifier.xScale,modifier.yScale = 2,2
-- modifier.rotation = elapsed % 360
end
end

local str4 = fm.BitmapString:new("retrofont",80):setText("pulse"):moveTo(160,240):setModifier(pulser):animate()

local t = 8000
transition.to(str:getView(),{ time = t,rotation = 0, y = 100, xScale = 0.4,yScale = 0.7,onComplete = function() --[[ FontManager:clearText()--]] end })
transition.to(str2:getView(), { time = t,x = 300, y = 400, alpha = 0.4,xScale = 0.4,yScale = 0.4 })
transition.to(str3:getView(), { time = t,rotation = 360 })
transition.to(str4:getView(), { time = t, xScale = 2,yScale = 2})

Getting there

Something of a milestone.

You can't see it on here, but the system is animating at the dual level now - so this text is moving up the screen (under the control of transition.to) while vertically scaling up and down following a sine curve (under the control of the Font Manager).

It all seems to be working very nicely.


Sunday 4 May 2014

Dumb mistake of the week :(

Affects scene manager, transition manager and font manager.

What's wrong with this ?

_G.Base =  _G.Base or { new = function(s,...) local o = { } setmetatable(o,s) s.__index = s s:initialise(...) return o end, initialise = function() end }

This is my one line OOP. Like an idiot I modified it slightly but didn't test it thoroughly.

Answer : the initialiser which I added, s:initialise(...) works perfectly - except it initialises the passed in prototype (s) not the newly created object (o), should be.

So instead of nicely constructing a new object, it "reconstructed" the prototype.

_G.Base =  _G.Base or { new = function(s,...) local o = { } setmetatable(o,s) s.__index = s o:initialise(...) return o end, initialise = function() end }

Aarggh !

Making some progress

Progress is being made, the BitmapFont class (see picture) is now pretty much complete and tested. This is a picture of it with a sine function applied to the yScale.

The slight slant on the images is nothing to do with the font library, incidentally, it's the way the letters were when I created the working font with bmGlyph.

As usual you can see the actual demo (it spins and zooms this) in the github account https://github.com/autismuk/Font-Manager though obviously this is still very much a work in progress.

Things left to do are:

  1. The Font Manager - this tracks font usage, allows texts on a screen to be easily managed, and provides animation support.
  2. The Animation Support - the code will support this at the moment (e.g. you could make the 'curve' on the letter pictures move, or zoom in and out, or spin round (you can spin the letters individually or the whole thing).
  3. Some Animation Providers - these are some classes that provide some standard easily configurable animations and shapes. These aren't hard to write, you can pretty much make the letters do anything you want.
  4. Some sort of demo showing it working. This isn't a real demo, it's just the current state of my build - which is why the run code is still in the library - I will try to arrange it so every commit does do something, but what it will do depends largely on what I am testing at the time.

But it's looking quite promising. If anyone's wondering, this will be a freebie as well (pretty much you can do what you want with it, don't pretend someone else wrote it :) )

The guts of this demo, e.g. the bit to run it looks something like this (cut n pasted straight from the code)

local modClass = Base:new()
function modClass:modify(m,cPos,elapsed,length) 
local a = math.floor(cPos * 180*2) % 180
m.yScale = (math.sin(math.rad(a))+0.3)*3
end

display.newLine(0,240,320,240):setStrokeColor( 0,1,0 )
display.newLine(160,0,160,480):setStrokeColor( 0,1,0 )

local font = BitmapFont:new("demofont")
local str = BitmapString:new(font,44)

str:moveTo(160,240):setAnchor(0.5,0.5):setScale(1.3,1):setDirection(0):setSpacing(0):setFontSize(64)
str:setText("Another demo")
str:setModifier(modClass:new())

transition.to(str:getView(),{ time = 4000,rotation = 720, xScale = 0.5, yScale = 0.5})

This is actually more than is needed. the two lines are just drawing the lines, and the system will support fonts-by-name directly (e.g. you can write BitmapString:new("demofont",44) .  Some of the chained function calls are unnecessary (e.g. anchor is 0.5,0.5, direction is 0, spacing is 0 and you could put the 64 in the BitmapString:new() call) but just there so I can tinker with them.

The modifier (the first five lines) is implemented as a class but in can be implemented as a function as well (shorter but less flexible) and there will be a bunch of standard ones so people can have special effects without writing modifier classes/functions at all. The modifier kind of says "well, it's this character, this amount of time has elapsed, how do you want to muck about with this one ?" - in this case it's applying a sine curve to the yScale. If you applied it to yOffset the characters would move up and down but would all be the same height. In the final version (doesn't work yet) if you added elapsed into that formula the curve will move about. The standard ones will be much easier than this, you won't have to faff around with trigonometry to get some effect or other.

So you'd only need about half the code in the final version.

Saturday 3 May 2014

Bit more work done.

On the font thing. The main thing that's vanished is displaying the text at an angle ; you can still go in any of the 4 main directions, but you can't draw text at 45 degrees (except by rotating the view, obviously). The primary reason was that it was horrendously messy in terms of recalculating the bounding box.

I can't use the anchorChildren of view group which automatically gives an anchor system, because the actual display object boxes move and change size. The library has an idea of a 'core' text item, with  x/y scale, text size and so on, which is modified on an individual basis, so individual characters have their own scale, size, rotation as well. To do this - to have a zooming character means I have to change the display object size - but this will change the bounding rectangle of the view group.

It looks like it's going to work quite well. At present, the system seems to work fine with transform.to()

There is a problem though. If you use transform.to to scale it, the individual scaling will not work, I don't think this problem is fixable. x,y,alpha and rotation are fine and will work normally, but scaling with animated scaling - say having characters zoom in and out will completely confuse the drawing system.

It's not unreasonable really, it has two different things - the animation controller and the transition controller arguing about what scale it should be.

If you don't animate the text (in the sense of animating the individual characters), scaling works fine - the system just allows you to create the text then forget about it and transition it about like you would a sprite or anything else.

Having said that if you are animating the text and scale of the text and the individual characters as well it would probably do the user's head in. There is only so much spinning and zooming it can take.

Friday 2 May 2014

Font Manager

A bit of the Corona Simulator
The font library is starting to produce some results.

First thing I did was to write a lua script which converts the .fnt file that programs like bmGlyph produce to a lua file, so that I can require it rather than parsing it all the time.

Then I wrote a BitmapFont class which reads and stores the bitmap information, and creates image objects that can be manipulated.

This picture (from the repository https://github.com/autismuk/Font-Manager) shows the sort of thing I'm hoping to do, though this is the testing code that the BitmapFont class uses (the reason for the 'y' is to check descenders), and it doesn't show the animation, which is a bit eye-numbing :)

Basically it operates like a text item, except every character is a display object. They can be aligned horizontally or at any angle you like. There is an overall scale, horizontal and vertical (-ve flips individual letters not the whole thing). Letters can independently rotate (the 'O' of world is going in the other direction if you look closely).

Once you've done that though, additional to the standard scale and position you can apply individual scales and positions. You can see that the 'e' is scaled up and the 'w' is scaled down.  Also, the whole string has a sine curve applied to it that makes it wavy.  In the demo in the repository at the moment, these things are all being animated using enterFrame, so they are all spinning, and the 'e' and 'w' are zooming in and out.

The modifiers will be encapsulated in a function call which includes the character position and the clock, so you can either have static effects (the sine shaping) or active effects (the zooming and rotating).

At the moment it is just done by testing code, I wanted to make sure the code to position/scale/rotate the characters was pretty bulletproof first.

If you removed all these modifiers it would just display "Hello, worldy !" in a straight line neatly in the bounding box.

Besides this, while it will be an OOP library it is possible to access the view group, so that you can apply transitions to it, though only as a whole thing, the transition.to/from methods won't work on individual characters.

It's not actually useable as a library - yet - but it is available to download if anyone wants to look and/or make suggestions.

Thursday 1 May 2014

Composer with Objects

Pretty much completed this, for first project anyway - I'm putting together reusable components for a game, rather than simply writing it. Next thing will be a library which utilises .fnt / .png files to print text in a coherent fashion, I want to be able to animate them and scale them and so on to produce Amiga Demo style effects without too much difficulty.

The Composer library is probably useable if anyone wants to play with it, but the interface might change a bit. You never quite know how useable your components are until you write something with them.

So, some examples. These all come from the demo that is there, shortened, mostly removing either print statements for debugging or scene setup code.

This declares a scene class which can be reused easily, just to create test scenes easily really.

SimpleSceneClass = sm.Scene:new()
creates a new scene. sm is the singleton instance of the Scene Manager.

function SimpleSceneClass:create()
local vg = self:getViewGroup()
self.r = display.newRect(10,10,display.contentWidth-20,display.contentHeight-20)
self.r.anchorX, self.r.anchorY = 0,0
self.r:setFillColor( 0.4,0,0 ) self.r.strokeWidth = 42 self.r:setStrokeColor(0,0,1)
        vg:insert(self.r)
        (more of the same setting up simple display stuff.)
self.item = 0
end

this is analogous to the create event - it creates objects which are insert into the view group.

function SimpleSceneClass:tap(event)
if event.target == self.text then 
self:gotoScene(self.tgt)
else
self:gotoScene("over1")
end
return true
end

this is a tap event. You can tap the text bit to go to another scene, or you can tap something else to go to an overlay called "over1". It works the same sort of way, though I do allow dimming of the background scene, or not, as you like.

function SimpleSceneClass:enterFrame(a,b,c)
self.item = self.item + 1
self.textCount.text = self.item
end

This is quite useful.  Firstly, data can be stored in a scene, and won't be lost even if the scene is created and destroyed. So self.item is a counter. The enterFrame event is called automatically by the SceneManager if this is the current scene. What this does is display a counter which increments at 30Hz. (fps rate). You don't have to set up, or remove event handlers.

function SimpleSceneClass:getTransitionType() return "flip" end

This overrides the 'exit' transition from the class, so it uses flip.

function ShortDisplayClass:create()
self:insert(display.newText("And now ...",display.contentWidth/2,display.contentHeight/2,native.systemFont,24))
end
function ShortDisplayClass:nextScene() return "thirdscene" end
function ShortDisplayClass:sceneDelay() return 2500 end

This is fun. This is a Scene class which creates the scene (as normal), but it automagically waits (2500ms, e.g. 2.5 seconds) and then goes to the scene "thirdscene". Quite nice for transient information scenes.

DemoOverlayClass = sm.ModalOverlayScene:new()

function DemoOverlayClass:create()
local c = display.newCircle( display.contentWidth/2,display.contentHeight/2,100 )
c:setFillColor( 0,1,0 )
c.strokeWidth = 2
self:insert(c)
c:addEventListener( "tap", self )
end

function DemoOverlayClass:tap(e)
self:closeOverlay()
return true
end

The worlds dullest overlay. Just displays a circle, you tap on it, and it closes the overlay. There is a non modal overlay scene class as well.

So, we'll create three scenes and an overlay and wire them together.

s1inst = SimpleSceneClass:new():setup("One","secondscene")
s2inst = ShortDisplayClass:new()
s3inst = SimpleSceneClass:new():setup("3","firstscene")
ovinst = DemoOverlayClass:new()

these are instances of scene classes. It's OOP, so you create a scene class then an instance of it (though in LUA you can actually do both with the same thing). The set up method just puts some text to make the classes visually distinguishable, the second parameter is where you go after this. ShortDisplayClass has this hard coded (it goes to thirdscene, specify in the nextScene() method).

smgr:append("firstscene",s1inst):append("secondscene",s2inst):append("thirdscene",s3inst):append("over1",ovinst)

Then we tell the scene manager what they are and what they are called. I kept the Corona idea of naming scenes, but you can use the reference if you like. And I like chaining. And templates.

smgr:gotoScene("firstScene")

.... and it does.  So we've created with this code two scenes with the counter and the overlay button (1 and 3) and the transitional automatic screen (2) and an overlay scene. None of them actually do a great deal, but they could, of course.

All this stuff, incidentally, is under the MIT license, which pretty much amounts to 'help yourself'.