Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
18. March 2013

Right off the hop, this post has absolutely nothing to do with game development, but does have something to do with creating this site.

 

As a bit of a throwback to the 1990s, I on occasion make use of animated gifs on this site.  Here is an example post making use of animated gifs. When you have several simple clips required to illustrate a point, and a series of images would take up too much space, animated gifs can be your best friend.  Of course you could host the clip on Youtube, but first off, embedding dozens of YouTube videos in a single page can cause some browsers to go on strike.  Additionally, who wants to watch a 3 second video?  One of the biggest downsides to making animated gifs like this is that frankly, it's time consuming.  I generally created a series of screenshots using IrFan and compose them together into an animated gif using The GIMP.  I describe my process here under the poorly titled How to creating animated gifs.  Generally it would take 20 minutes or more to create a single image.

 

I tried a number of simpler processes that made use of video; some local applications, others websites you upload your video to and they make it into a GIF.  The universal problem, they give you very little control and end up generating either horrible quality or MASSIVE images.

 

Now that I am authoring these posts more from Mac, and felt the need to make another animated gif but no desire to go through the entire process again, I decided to check if there is an easier way, and there is...

 

Gif Brewery

 

It's one of those little 5$ utilities that will literally save me hours.  When I first fired it up I was a bit confused, as there is no app, nor an icon.  You need to go up to the menu and select File->Open.  At this point in time you are left asking… open what?  The answer of course is a video.  This is a non-inuitive start to what ended up being a very intuitive program.  

 

So I needed a video to work with.  I simply loaded up QuickTime Player and did a few seconds of full screen capture.  I export that video then open it in Gif Brewery.  Then I am finally presented with a UI and it's smooth sailing from here.  Here is the UI in action:

Gif Brewery in action

 

From this point on, its dirt simple… you can crop or scale your selection ( I scaled mine down ), set the start and end points, apply filters and finally export your gif.  When you create the gif you get a preview, with resulting file size, then you can play around a bit to get the file to a size you like.  The app itself was virtually instant, much much much faster than the gimp was working with individual frames.

 

Here is the above gif, weighing in about about half a MB.  In most of my captures I would use a much lower frame rate and bit rate, thus achieving an even smaller size.

Demo

 

That same GIF through other services would have weighed in at a several MB.

 

So, if you are on MacOS and looking to create an animated GIF ( yes… there are uses! ), this is certainly 5$ well spent.

 

If you are the author, first off, great job.  Second, I would recommend you add a window when the app first loads, as well as the ability to skip sections in the videos timeline.  Both are nitpicking though for a 5$ application.


12. March 2013

This is part 3, the following are links for part one and part two in this series.

 

Alright, we've installed the tools, got an editor up and going and now how to run the generated code, both on our computers and on device ( well… Android anyways… I don't currently have an iOS developer license from Apple ), so now the obvious next step is to take a look at code.

 

Let's get one thing clear right away…  I know nothing about ActionScript, never used it, and I didn't bother taking the time to learn how.  As unfair as that sounds, frankly when it comes to scripting languages, I rarely bother learning them in advance… I jump in with both feet and if they are good scripting languages, you can generally puzzle them out with minimal effort.  This is frankly the entire point of using a scripting language.  So today is no different.  This may mean I do some stupid stuff, or get impressed by stuff that makes you go… well duh.  Just making that clear before we continue… now, lets continue...

 

LoomScript

 

 

Apparently LoomScript is ActionScript with a mashup of C# and a smattering of CSS.  ActionScript is itself derived or based on JavaScript.  I know and like JavaScript and know and like C#, so we should get along fabulously.

 

Let's look at the specific changes from ActionScript.

 

First are delegates, a wonderful feature of C#.  What exactly is a delegate?  In simple terms it's a function object, or in C++ terms, a function pointer.  It's basically a variable that is also a function.  This allows you to easily create dynamic event handlers or even call multiple functions at once.

Next was type inference, think the var keyword in C# or auto keyword in C++ 11. 

They added support for the struct data type.  This is a pre-initialized and copy by value (as opposed to reference) class.  I am assuming this is to work around an annoyance in ActionScript programming that I've never encountered.

They also added C# style Reflection libraries.  I assume this is confined to the System.Reflection namespaces.  If you are unfamiliar with Reflection in C# land, it's a darned handy feature.  In a nutshell, it lets you know a heck of a lot about objects at runtime, allowing you to query information about what "object" you are currently working with and what it can do.  It also enables you load assemblies and execute code at runtime.  Some incredibly powerful coding techniques are enabled using reflection.  If you come from a C++ background, it's kinda like RTTI, just far better with less of an overall performance hit. 

Finally they added operator overloading.  Some people absolutely love this feature…  I am not one of those people.  I understand the appeal, I just think it's abused more often than used well.  This is an old argument and I generally am in the minority on this one.

 

Hello World

 

 

Now let's take a look at creating the iconic Hello World example.

 

First is the loom.config file, it was created for us:

{

  "sdk_version": "1.0.782",

  "executable": "Main.loom",

  "display": {

    "width": 480,

    "height": 320,

    "title": "Hello Loom",

    "stats": true,

    "orientation": "landscape"

  },

  "app_id": "com.gamefromscratch.HelloLoom",

  "app_name": "HelloWorld"

}

 

This is basically the run characteristics of your application.  This is where you set application dimensions, the title, the application name, etc.  Initially you don't really even have to touch this file, but it's good to know where it is and to understand where the app details are set.

 

Pretty much every application has a main function of some sort, the entry point of your application and Loom is no exception.  Here is ours in main.ls

package

{

    import cocos2d.Cocos2DApplication;

 

    static class Main extends Cocos2DApplication

    {

        protected static var game:HelloWorld = new HelloWorld();

 

        public static function main()

        {

            initialize();

            

            onStart += game.run;

        }

    }

}

 

Here we are creating a Cocos2DApplication class Main, with one member, our (soon to be created) Cocos2DGame derived class HelloWorld.

We have one function, main(), which is our app entry point, and is called when the application is started.  Here you can see the first use of a delegate in LoomScript, where you assign the function game.run to the delegate onStart, which is a property of Cocos2DApplication.  In a nutshell, this is the function that is going to be called when our app is run.  We will look at HelloWorld's run() function now.

Speaking of HelloWorld, lets take a look at HelloWorld.ls

package

{

    import cocos2d.Cocos2DGame;

    import cocos2d.Cocos2D;

    import UI.Label;

 

 

    public class HelloWorld extends Cocos2DGame

    {

        override public function run():void

        {

            super.run();

 

            var label = new Label("assets/Curse-hd.fnt");

            label.text = "Hello World";

            label.x = Cocos2D.getDisplayWidth()/2;

            label.y = Cocos2D.getDisplayHeight()/2;

            

            System.Console.print("Hello World! printed to console");

 

            //Gratuitous delegate example!

            layer.onTouchEnded += function(){

                label.text = "Touched";

            }

            

            layer.addChild(label);

        }

    }

}

 

We start off with a series of imports… these tell Loom what libaries/namespaces we need to access.  We added cocos2d.Cocos2D to have access to Cocos2D.getDisplayWidth() and Cocos2D.getDisplayHeight().  Without this import, these methods would fail.  We similarly import UI.Label to have access to the label control.

 

Remember about 20 seconds ago ( if no btw… you may wish to get that looked into… ) when we assigned game.run to the Cocos2DApplications onStart delegate?  Will, this is where we define the run method.

 

The very first thing it does is calls the parent's run() method to perform the default behaviour.  Next we create a Label widget using the font file Curse-hd.fnt (that was automatically added to our project when it was created ).  We set the text to "Hello World" and (mostly) centre the label to the screen by setting its x and y properties.  You may notice something odd here, depending on your background…  the coordinate system.  When working with Cocos2D, there are a couple things to keep in mind.  First, things are positioned relative to the bottom left corner of the screen/window/layer by default, not the top left.  Second, nodes within the world are by default positioned relative to their centre.  It takes a bit of getting used to, and can be overridden if needed.

Next we print "Hello World was printed to the console" to demonstrate how to print to the console.  Then we follow with another bit of demonstrative code.  This is wiring a delegate to the layer.onTouchEnded property.  This function is going to be called when the screen is released, as you can see, this is an anonymous function, unlike run we used earlier.  When a touch happens, we simply change the label's text to Touched.  Finally we add the label to our layer, inherited from Cocos2DGame.

 

Run the code and you will see:

Loom2

 

While if you check out your terminal window, you will see:

 

Loom1

As you can see, Hello world is also displayed to the terminal.

 

Now lets take a look at one of the cool features of Loom.  Simply edit an .ls file in your text editor of choice and if you are currently running your project, if you flip back to the terminal window you will see:

 

Loom3

 

Loom is automatically updating the code live as you make changes.  This is very cool feature.  Ironically though, in this particular case, it's a useless one as all of our code runs only when the application is first started.  However in more complicated apps, this will be a massive time saver.

 

On top, this is also how you can easily detect errors… let's go about creating one right now.  Instead of label.Text, we are going to make an error, label.Txt.  Save your code and see what happened in the Terminal window:

 

Loom4

 

As you can see the error and line number are reported live in the Terminal without you having to stop and run your application again.

 

 

Pretty cool over all.  In the next part, we will look at more real world code examples.

 

You can read the next part dealing with graphics right here.


8. March 2013

Version 1.6 of the cross platform Java based game library PlayN was released recently.  PlayN enables you to target desktop, HTML 5, iOS and Android all using a single Java code base. 

 

  

Here are the release notes for this release:

PlayN v1.6

  • The complete API changes are summarized in this JDiff report.
  • Below is a summary of the interesting changes.

Project Layout

  • The way projects are organized has changed, please see Migrating15to16 for details.

Core

  • Implemented tinting for layers (only on GL backends). See Layer.setTint and Layer.tint.
  • Added Log.setMinLevel to allow suppressing log messages below a certain level. (Recommended by Google for Android release builds.)
  • Added Sound.release for releasing audio resources sooner than waiting for GC to do it.
  • Added Assets.getMusic which allows backends to make some optimizations relating to large audio files.
  • Graphics.setSize was removed, and special setSize methods were added to individual platform backend code that can reasonably support them (e.g. HtmlGraphics.setSize).
  • Added GLContext.Stats for debugging rendering performance on GL backends. (See Triple Play's HUD class for an easy way to display these stats.)
  • Deprecated Canvas.setTransform because it interacts poorly with automatic scale factor management in HiDPI modes.
  • Added CanvasImage.snapshot which can be used to create an immutable snapshot of a canvas image which has higher render performance.
  • Added TextLayout.ascent/descent/leading for cases where an app needs to know more about the text that will be rendered by aTextLayout (for underlining, for example).
  • Added Json.Writer.useVerboseFormat to cause the JSON writer to generate pretty printed output (rather than compact, everything on one line output).
  • Added support for nested clipping regions (e.g. clipped groups inside of clipped groups).

Java

  • Made the Java backend look for .wav audio files and then fall back to .mp3. This allows a game to use uncompressed .wav audio files, and only compress them when preparing an Android, iOS, or HTML build.
  • Made playback of large MP3s work (when loaded as music).

HTML

  • Added HtmlAssets.ImageManifest which can be used to pre-load the dimensions of all images known to your app, and enableAssets.getImageSync to (sort of) work in the HTML backend. A wiki article explaining this will be forthcoming.
  • Added support for HiDPI mode. See HtmlPlatform.Config.scaleFactor and HtmlAssets.setAssetScale.
  • Added HtmlGraphics.registerFontMetrics for overriding the (hacky) measurement of font line height.
  • Removed source code from the stock POMs. HTML backends now need to add the source jar files to their html/pom.xml. See playn-samples for an example.

Android

  • Fixed issue with audio not stopping when device was put to sleep.
  • Images loaded locally are now marked as "purgeable" and "input shareable". Google for "android" and those terms to learn more.
  • Added AndroidGraphics.setCanvasScaleFunc which allows games to use lower resolution canvas images if desired. This is useful on devices with low memory.
  • Added AndroidAssets.BitmapOptions which allows games to downsample images if desired. This is useful on devices with low memory.
  • Added GameActivity.prefsName for customizing the name of the Android preferences file.
  • Added GameActivity.logIdent for customizing the Android log identifier. It defaults to playn which is what was hard-coded before.
  • Rewrote sound backend based on SoundPool. Music (large audio files) still relies on the old more-hardware-resource-intensive approach.

iOS

  • Added IOSPlatform.Config for specifying configuration options.
  • Added IOSPlatform.Config.frameInterval for specifying target FPS on iOS.
  • Added IOSImage.toUIImage for custom platform code that needs to manipulate an image loaded via IOSAssets.getImage.
  • Numerous bug fixes and performance improvements.

 

Additionally, TriplePlay 1.6 was also released.  TriplePlay is a library built over top of PlayN to support higher level functionality like UIs and animation.

The following are TriplePlays release notes:

 

TPUI:

  • Added Scroller makeVisible.
  • Added LongPressButton which supports both a normal press interaction and a long-press interaction.
  • Added AxisLayout.Policy CONSTRAIN off-axis sizing policy.
  • Added Field MAXIMUM_INPUT_LENGTH style.
  • Added TableLayout colspan for configuring a column span on an element.
  • Added ValueLabel.
  • Added Style ICON_CUDDLE and UNDERLINE (the latter for underlined text).
  • Added TableLayout.Column free to allow weighting of free columns.

TPAnim:

  • Added AnimGroup for creating a group of invoked-in-parallel of animations that are either added to an Animator later, or are added to a serial animation chain.
  • Moved animation creation methods from Animator to AnimBuilderAnimation then now returns an AnimBuilder which is a cleaner design.
  • Clarified behavior of Animator add and then, made then freak out if used incorrectly.
  • Fixed bugs with repeating animations.

TPSound:

TPParticle:

  • Added Transform randomScale and randomOffset.

TPFlump:

  • Various bug fixes and small API improvements. See API changes.

TPPlatform:

  • Added NativeTextField Validator and Transformer for (native) text validation and transformation.

TPShader:

  • TintingShader was removed as PlayN layers now support tinting directly.

TPUtil:

 

 

For existing PlayN 1.5 developers, there is a guide for migrating to 1.6.


7. March 2013

Pretty much just a bug fix release:

 

Interface

  • Fix #34357: Image editor scope and clip editor track preview did not resize properly with different DPI settings. (r54760)
  • Fix #33466: Alt+MouseWheel changes frame as well as buttons (r54929)
  • Fix UI/DPI: user preferences window size now takes into account DPI, otherwise the buttons don't fit properly. (r54945)
  • Fix soft shadow at top edge incorrectly drawn (r54954)
  • Fix #34418: Screencast could be started twice (r54961)
  • Fix #34509: Panel color were not updated from old files properly (r54996)
  • Allow trackpad and magic mouse swipes to control brush size for circle select. (r55027)
  • Fix (regression) #34391: Window position not saving correctly for next start-up (r54879)
  • Fix #34390: quicktime video codec menu showing blank (r54942)

 

Viewport

  • Fix #34378: GLSL materials using multiple UV layers fail in editmode (r54783)
  • Fix #34347: View3D Mini-Axis drawing in error with overlay (r54789)
  • Fix #34426: Manipulator handles drawn incorrectly by depth (r54923)
  • Fix glitch rotating the camera in camera mode drawing helper-line in random locations (r54928)

 

Animation

  • Fix zoom for graph-editor (and other editors) (r54910)

 

Sequencer

  • Fix #34439: Strip modifier - Mask multiply failure (r54901)
  • Fix #34453: Added RGBA|RGB channels toggle to sequencer preview (r54904)
  • Fix sequencer crash when pasteing strips after creating new file (r54935)

 

Composite/Nodes

  • Fix #34356: Inputs list in file output doesn't appear properly. (r54754)
  • Fix #34359: Crash when using image output node (r54746)
  • Fix #34474: "Record Composite" image op segfaults in compositor code (r54948)
  • Fix #34461: Inconsistent behavior of "Color Mix Node" and "Alpha Over Node" (r54960)
  • Fix #34507: Adding reroute node into invalid links would crash the compositor (r55047)

 

MovieClip/Tracking

  • Fix memory leak when loading multilayer EXR as movie clip (r54934)
  • Fix for incorrect subpixel precision of marker when using track offset (r55028)

 

Render

  • Fix #34351: Displacement map Bake margin does not work (r54748)
  • Fix #34436: Node editor delete texture crash (r54908)
  • Fix #34493: Image Sequence texture didn't allow "Offset" with fcurves. (r55012)
  • Fix #34475: Weird noise bug with Texture nodes (r55021)
  • Fix for texture preview render with show alpha enabled (r55026)
  • Fix image transparency backwards compatibility. Now the texture datablock has a 'Use Alpha' option again. (r55022)

 

Render (Cycles)

  • Fix #34421: viewport render stuck with no objects in the scene. (r54885)
  • Fix #34480: hair render in dupligroup did hide the emitter properly in some cases. (r54959)

 

Modifiers

  • Fix #34358: Shrinkwrap modifier project along normal did not work correctly (r54793)
  • Fix #34369: applying screw modifier turns object to black (r55004)

 

Tools

  • Fix #34384: Border select in UV Image window crashed (r54816)
  • Fix for weight paint using values over 1.0 when blending (r54833)
  • Fix for regression in 'object.shape_key_transfer' operator since BMesh merge (r54834)
  • Fix #34415: Edge slide results in segmentation fault on certain mesh (r54875)
  • Fix #34455: Origin to Center of Mass is missing in menu Object > Transform (r54891)
  • Fix selecting linked faces (r54920 r54921)
  • Fix #34366: mesh.select_mode operator could not be configure the use_extend and use_expand properly. (r54944)
  • fix #34486: Selection of bones in armature edit mode only toggles between two bones (r54969)
  • Fix #34534: Copy/Paste objects hangs (r55051)
  • Fix (regression) #34438: Solidify crease error (r54882)
  • Fix missing select menu for weight, vertex, texture paint modes. (r54883)
  • Fix joining meshes could loose crease/bevel weights (r54899)
  • Fix (regression) #34449: Edge toggline bevel failed (r54900)

 

Sculpt

  • Fix #34370: Collapse-Edges crash in dyntopo (r54827)
  • Fix #34431: Crash when dyntopo enabled and using view plane mode (r54971)
  • Fix #34473: Blender Crashes on toggling modes, dynatopo sculpt/object mode. (r55007)

 

Game Engine

  • Fix projection clipping (r54733)
  • Fix #34349: Character walkDirection ADD mode -#INF error. (r54738)
  • Fix #18967: Enable alpha buffer (useful for TV broadcasting). (r54745)
  • Fix #34353: Ray cast on Triangle mesh bounded Rigid Body Object crashes (r54757)
  • Fix #34219: Webcam support under Linux in Standalone broken (r54764)
  • Fix #34330: Action Actuator "caching" the previous ran actions (r54766 r54767 r54769)
  • Fix error using actions with multiple scenes (r54767)
  • Fix object color channels can now be animated separately without zeroing out the other channels (r54772)
  • Fix error using uninitialized variables for rendering (r54776 r54781)
  • Fix #34377: Game-Engine - Multi UV mesh's materials not backwards compatible (r54780)
  • Fix Game-Engine crashing when on material conversions (r54837)
  • Fix #34440: Motion blur (2d filter) not working in osx (r54912)
  • Fix #34428 #20856 #20281: converting multi-uv layers. (r54972)
  • Fix #34523: 2D-Filter produces render error (r55010)
  • Fix #34517: 2D-Filter causes mouselook script drifting effect (r55011)

 

Rigid Body

  • Fix motion paths calculation being incorrect for rigid bodies (r54799)
  • Allow rigidbody collision groups to be animated (r54818)
  • Fix #34410: Planes with Rigid Body always keep distance to colliding objects (r54855)
  • Fix #34420: Rigid objects not resetting original properly after running a simulation. (r54862)
  • Fix inconsistency with world rebuilding with the start frame (r54990)

 

Text Editor

  • Fix Fix text editor bug: ctrl+F is not configurable (r54878)
  • Fix #54907: freeze when turning on syntax highlight (r54907)
  • Fix crash when overwriting ascii character with multibyte character (r54917)

 

Python

  • Fix Python console bug: "autocomplete" doesn't advance cursor properly when completion includes UTF8 characters (r54824)
  • Fix #34423: foreach_get crash for any non existant attribute (r54865 r54866)
  • Fix #34372: mesh.verts.foreach_set not working with normals (r54943)
  • Fix for python exception getting the ID from an operator button (r54835)

 

Other

  • Fix freeing all bakes in particle mode (r54822)
  • Fix file with packed images crashes on load (r54790)
  • Fix image alpha version patch with library linked files (r54794)
  • Fix #34427: Collada export crash with armature (r54856)
  • Fix X3D import error loading UV's (r4325)
  • Fix X3D import for images (r4327)
  • Rigify fixes (r4321 r4334 r4335)

 

You can head on over and download it here.

News Art


4. March 2013

This is the second part in our look at the Loom game engine, you can read part one here

I said I was going to get to coding next, but I ran into a bit of a roadblock, and figured I would document it in case any of the rest of you encountered the same issue.  It also looks at what the troubleshooting and support experience is like when dealing with Loom.  Basically, as the title suggested, I wanted to see the sample application running on my Android device.

To do so, open up a terminal window, cd into your loom project directory then type:

loom run --android ( thats two '-' by the way )

 

The result:

The android sdk does not appear to be installed, please run one of the following commands

loom android install <------- Auto-installs Android sdk
loom config --global android_sdk_path <path> <------- Point to existing installation


Easy enough, I already have an Android SDK installed, so I call

loom config --global android_sdk_path /Users/Mike/Development/android-sdk

Then I run 

loom run --android 

Again and:

Loom1

 

DOH!

 

Well, this gives me a chance to check out Loom's support, always a good test, especially with a new engine.  

First the good news, I found an answer thread.  TheEngine.co seem very responsive on their support forums, I have to applaud that.  In a nutshell here, the tell is INSTALL_PARSE_FAILED_NO_CERTIFICATES.

 

Anyways, back to the problem at hand… it appears they require JDK 1.6, while I've installed JDK 1.7.

 

On Windows, this is no big deal.  On MacOS, with Apple's ongoing war on Java, well to be honest it's rather a pain in the ass.

Here is how I downgraded to Java 1.6.  There may be a better way, but I didn't find it.

 

First, I removed the currently version of Java 1.7.  To do so, open a terminal window and navigate to /Library/Java/JavaVirtualMachines then remove the versions you don't want with the command sudo rm -rf [JDKVersionToRemove]  Theres a pretty good choice there is a more elegant answer than this, but frankly, I don't really care to keep Java 1.7 around so I took the brute force approach.

Then it's a matter of locating a JDK 1.6 download… this is the tricky part.  There was one on the Apple developer site, but it seems to have been removed.  Fortunately you can download it at http://support.apple.com/kb/DL1572.  Download that file, open it, double click the pkg and install.

 

Now, open a new terminal window and again run:

loom run --android 

 

and now...

 

Hello Loom running on Android

 

That's the loom project running on my Galaxy Note.

 

 

So what's the take away from this?

 

Well first off, Java 1.7 is still rather a pain in the butt, especially on MacOS.  Apple and Oracle probably share equal blame on that.

Second, the one time I needed support on a topic, I found the answer I needed.  With you game engines, this often isn't the case, so, kudos there.  TheEngine.co seem to be pretty responsive to support questions.

 

 

You can now read part three here.


AppGameKit Studio

See More Tutorials on DevGa.me!

Month List