Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

22. March 2017

 

One thing many programmers struggle with is finding art for their game.  There is a new site, The Open Pixel Project that aims to make life somewhat easier for people.  It’s essentially a community for publishing, requesting and downloading pixel art graphics.  It just went live and there are already hundreds of tiles and sprites available, all under the Creative Commons Zero license, which is about as liberal as they come.

 

I did a quick hands-on video on the Open Pixel Project available below.

 

The only immediate recommendation I have, beyond fixing the png links, is that they publish to a much higher resolution.  It’s easy to go down in resolution, but not so easy going up!  It will be interesting to see how this project turns out.

GameDev News, Art

20. March 2017

 

In this tutorial in our ongoing HaxeFlixel tutorial series we are going to look at using Sprites in HaxeFlixel.  Sprites are fundamental to HaxeFlixel development and can be simply thought of as a graphic that can move.  We are going to look at a couple different examples, one procedurally creating the graphic to draw, while the other loads the sprite from an image.  We are also going to quickly take a look at how we can move our sprite around the screen.  If you were curious, the term Sprite was coined by Texas Instruments for one of their early graphics chips.  The reason the term Sprite was chosen according to Wikipedia:

The term was derived from the fact that sprites, rather than being part of the bitmap data in the framebuffer, instead "floated" around on top without affecting the data in the framebuffer below, much like a ghost or "sprite". By this time, sprites had advanced to the point where complete two-dimensional shapes could be moved around the screen horizontally and vertically with minimal software overhead.

It was common in the early days of consoles and graphics cards to have dedicated hardware for drawing sprites (non-stationary images) and the number of supported sprites was a key selling feature for computers and consoles.  In HaxeFlixel, Sprite is actually a very important class, the FlxSprite.  Behind the scenes there is no special hardware for drawing sprites anymore, in fact a sprite is ultimately a 3D object that is parallel with the camera, but the terminology has stuck.  Ok, enough history, let’s actually jump in with some code.

 

In this first example, we are simply going to create a FlxSprite programmatically.

package;

import flixel.FlxSprite;
import flixel.FlxState;

class PlayState extends FlxState
{
   var sprite:FlxSprite;
   override public function create():Void
   {
      super.create();
      sprite = new FlxSprite();
      sprite.makeGraphic(300,300,flixel.util.FlxColor.WHITE);
      for(y in 0...300){
         for(x in 0...300){
            if(x%2 == 1 && y%2 == 1)
               sprite.pixels.setPixel(x,y,0x0000ff);
            if(x < 5 || y < 5 || x > 295 || y > 295 )
               sprite.pixels.setPixel(x,y,0xffffff);
         }
      }
      add(sprite);
   }

   override public function update(elapsed:Float):Void
   {
      super.update(elapsed);
      sprite.x += elapsed * 100;
   }
}

When we run this code we should see:

image

 

As the program runs the sprite will slowly advance to the right until it is off the screen.  Let’s just in and figure out exactly what is happening here. 

First thing to notice is the base class of our sprite is FlxSprite.  We allocate a new one then call it’s makeGraphic() method.  This gives us a 2D image to work with, in this case one that’s 300 pixels wide by 300 pixels high and filled with the colour WHITE.  As you can see HaxeFlixel has a handy utility class containing the numeric value of several of the most common colours available in flixel.util.FlxColor.

Now that we have a 300x300 white canvas to play with we simply loop over all the available pixels in the graphic, looping row by row, then through each pixel in that row.  We can then directly set the color value of a given pixel by accessing the setPixel() method of the pixel member of FlxSprite.  The parameters are the x and y location of the pixel within the graphic, relative to the top left corner, as well as the color to set it.  Notice in this example instead of using a predefined colour (which we could have if we preferred) we instead us a hexadecimal encoded number.  If you’ve ever done any HTML coding, this color scheme should be immeidately familiar.  If not each two digits represents first the red, then green, then blue component of the color from 0 to 255 ( or 0 to ff in hexidecimal).  So in this case we set every other pixel of blue ( no red, no green, full blue == 0x0000ff ).  We also have another check to see if we are within 5 pixels of the image edge and if so, draw the pixels in white.  This causes a 5 pixel wide border to appear around our image.

After creating our simple white bordered checkboard image you will notice a call to add().  This call is EXTREMELY important, as it adds the FlxSprite to the object collection of our FlxState derived class PlayState.  Being in this collection will cause the sprite to automatically be drawn and updated each pass through the game engines main loop.  Speaking of updating, notice we have also overridden the update method.  This is called every pass through the game loop and is where you should update the logic of your game world.  In this case we simply increase the x value of our sprite by elapsed * 100.

So... why did we do this?  What exactly are we saying with the line:

sprite.x += elapsed * 100;

This is actually a really common tactic in game development.  One of the challenge of creating games is getting them to run the same speed on various different computers.  If you are running a fixed game rate loop, say a game running at 60fps, and it never runs below that rate, it’s not a problem, you know how fast things are going to update.  However on faster or slower computers this is trickier to determine.  This is why elapsed is so important.  This is a value passed in to the update() function each pass through the game loop and it tells our game how long has elapsed in seconds since the last pass through the game loop.  You can then multiply this value by the amount you want to move by to get a consistent update regardless to the machine you are running on.

For example, if your game was running at 10 frames per second, the value of elapsed will be 0.1.  So to hit our target of 100 pixels per second, this means in updates we will move by 100 * 0.1 or 10 pixels.  However if we were running at 60 fps instead of 10fps, the value of elapsed will instead be 1/60 or 0.016.  So to hit our target of 100pixels per second we update instead by 0.016 * 100 or 1.66 pixels.  Over the course of a second, regardless to framerates, the sprite will be updated by the same total amount.

Before we move on it’s important to know the process of working directly with each pixel in a sprite like we just did is an extremely costly process!  This is the kind of task you want to perform very occasionally, not every frame!

Next, instead of creating an ugly graphic programmatically, lets load a sprite from an image file.  Let’s jump straight into the code.

package;

import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.tweens.FlxTween;

class PlayState extends FlxState
{

   var sprite:FlxSprite;
   override public function create():Void
   {
      super.create();
      sprite = new FlxSprite();
      sprite.loadGraphic(AssetPaths.enemy__png);
      sprite.x = 100;
      sprite.y = 0;
      add(sprite);

      FlxTween.tween(sprite, { x: FlxG.width - sprite.width, 
                         y: FlxG.height - sprite.height, 
                         angle : 360.0 }, 5, { type:FlxTween.PINGPONG });
   }

   override public function update(elapsed:Float):Void
   {
      super.update(elapsed);
   }
}

Now when we run the code, we see:

GIF

 

Notice in this case that our sprite is still a FlxSprite, although instead of creating it from scratch using makeGraphic() we load if from file using loadGraphic passing in the value AssetPaths.enemy__png.  In this case enemy.png is the name of the image we are using for our sprite.  If yours has a different filename, this value will change.  A bit of a note on the image, I added it to the directory assets/images that was automatically created when we created our project.

image

 

As we add new assets to these folders, Haxe is smart enough to automatically create a reference to it for us.  This is a handy feature of the Haxe language and is invoked by this code in AssetPaths.hx:

package;

@:build(flixel.system.FlxAssets.buildFileReferences("assets", true))
class AssetPaths {}

Throwing any applicable asset in the assets directory will automatically generate file references that we can then use in code, like so:

image

 

Very cool.  Behind the scenes loadGraphic is actually doing a lot more than you might think.  In addition to loading the file into memory, it’s actually caching it.  This means that if other code loads the same asset it will get the version from cache instead of creating yet another version.  This improves performance and reduces memory usage.

So now that we have our sprite loaded from an image we set it’s initial x position to 100 pixels.  Notice that graphics are drawn relative to their top left corner and the top left corner of the applications window.  So an image with x = 100 and y = 0 is drawn starting at it’s top left corner 100 pixels right of the top left corner of the window and 0 pixels down from the very top of the application window. 

The final detail of this example is the use of a Tween, called via FlxTween.tween().  FlxTween is another cool way of handling updating your game objects, but it takes care of the timing and calculations for us.  Instead of moving our sprite each pass through the game loop via update() like we did earlier, we simply fire off a Tween and it takes care of things for us.  Tween comes from  “In-Between” and basically it’s a function that you give an end goal and a timeline and it figures out all the in-between calculations required.  In this case we are saying “take this sprite, move it to the bottom corner of the screen, rotating 360 degrees over a period of 5 seconds” and HaxeFlixel figures out how much it needs to move each frame and does it for us.  The final parameter we are saying we want to ping pong the tween, which is to say repeat it, but in reverse forever.  There is a ton more we can do with Tweens and we will cover them in more detail later.

 

That’s it for sprites for now, but there is a lot more we will cover later including texture atlases, animations and more, stay tuned!

 

The Video

Programming , , ,

17. March 2017

 

Now that we have covered getting your development environment up and running, we are going to jump into our first HaxeFlixel application.  Let’s start from the very beginning and create a new application.  As mentioned in the Getting Started tutorial, we can create an application using the simple command:

flixel tpl –n “HelloWorld”

This creates a directory with a skeleton application to get us started.  It actually creates a bit more code then we need, we are going to strip it down to just two source files.

image

 

It is pretty much tradition to make your first program a simple Hello World application, so that is what we are going to do.  We will simply print the text “Hello World” on screen, but since this is ultimately a game we are creating here, we will also animate it!  Ok, code time, let’s start with Main.hx, the entry point of our application.  Here is the source code:

import flixel.FlxGame;
import openfl.display.Sprite;

class Main extends Sprite
{
   public function new()
   {
      super();
      addChild(new FlxGame(0, 0, GameState));
   }
}

 

One thing that might immediately seem awkward is that our Main class inherits from Sprite.  This is a throwback to the Flash development world, just think of a Sprite as “something that is visible on screen”.  When our Main object is created it’s constructor is called and really it does just one thing, creates a new FlxGame object passing our GameState class in as a parameter.  The first two parameters to the FlxGame constructor are the width and height of our game window.  In this case we didn’t specify a value, meaning the value from the Project.xml file will be used instead.  If you look at Project.XML (which was generated for you) you will see the lines:

   <!-- ____________________________ Window Settings ___________________________ -->

   <!--These window settings apply to all targets-->
   <window width="640" height="480" fps="60" background="#000000" hardware="true" vsync="true" />

   <!--HTML5-specific-->
   <window if="html5" resizable="false" />

   <!--Desktop-specific-->
   <window if="desktop" orientation="landscape" fullscreen="false" resizable="true" />

   <!--Mobile-specific-->
   <window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" />

Due to this configuration by default our application will have a resolution of 640x480, while on mobile devices we will instead use the full screen.  As you can see it’s possible to set multiple definitions using the if=”platform” conditional.  If you want to have FlxGame create a larger or smaller window you can either specify the value when creating your FlxGame object, or you can change it’s value in the <window> tag.  Ok, back to our code...

As mentioned earlier, we created a FlxGame object, which is the heart of your application and contains the game loop.  Every single game or game engine has a game loop in some form, it’s essentially a loop that runs over and over until your game is done and is responsible for polling input, updating the world and drawing graphics on screen.  We don’t actually use FlxGame directly however, our game is instead broken into multiple states.  We see this in action in GameState.hx, here is the source:

import flixel.FlxG;
import flixel.FlxState;
import flixel.text.FlxText;
import flixel.util.FlxColor;

class GameState extends FlxState
{
   var text:FlxText; 
   override public function create():Void
   {
      super.create();
      text = new FlxText(0,0,FlxG.width,"Hello World",64);
      text.setFormat(null,64,FlxColor.RED,FlxTextAlign.CENTER);
      add(text);
   }

   override public function update(elapsed:Float):Void
   {
      super.update(elapsed);
      text.y ++;
      if ( text.y > FlxG.height)
         text.y = 0 - 64;
   }
}

This is the meat of our application.  You will notice that GameState inherits from FlxState.  FlxState is a very important concept in HaxeFlixel development.  Essentially you break your game logic up into a number of different states, how exactly you do do this is up to you.  A common division might be  Title Screen State, Game Playing State, High Score State, Game Over State for example.  Another option is to break your game up into screens, so instead have it look something like Splash Screen State, Main Menu State, Game Playing State, Game Credits State, etc.  Or alternatively you could break your game into levels such as Main Menu, Level One, Level Two, etc.  Really it comes down to whatever fits the structure of your application the best.  Just keep in mind that FlxState are the logical units for breaking down gameplay complexity into manageable pieces and if you hate the idea completely, no problems, you can just throw everything together into a single state if you prefer.

At the end of the day though, the FlxState is a pretty simple data structure with two primary tasks.  First, it contains all the “stuff” that makes up that portion of your game.  In this particular example that “stuff” consists of a single FlxText node, but it could contain dozens or thousands of objects.  Just realize when we call the add() method, we are adding to a collection of Objects contained in the FlxState class.  The second important part of FlxState is to provide a number of callback methods that FlxGame can call.  As I said earlier, FlxGame contains our main game loop.  Each pass through this loop however it calls a series of functions on the currently active FlxState, the most important of which are draw() and update().  It is through these two callbacks that your FlxState derived class is modified over time.  Let’s look back at our example and walk through the code.

First in our create() method, we call our parents constructor so we are properly set up and configured.  We then create a new FlxText object, which is a special sprite (aka, something visible on screen) object for displaying text.  In this case we display the string “Hello World” at 32px height in the default font.  Notice we used a call to FlxG to get the width of the screen.  FlxG is a special global helper class containing handy information such as width and height of the screen, the default camera, access to input and more.  You can also get read only access to the FlxGame class we created earlier.  Once we create our FlxText object, we format the text so it’s aligned in the center and drawn in red.  Next we call the add() method, adding the text object to the GameState.  Once added it will automatically be drawn every frame unless disabled.

Next we implement the update() method.  As mentioned earlier, this is a callback function that is going to be called by FlxGame every pass through the game loop.  The one parameter it receives is a Float with the amount of time that elapsed since the last pass through the game loop.  This is extremely handy as it enables us to determine just how fast our game is running.  In this particular case all we do is update the text object’s y coordinate ( we will talk more about coordinates shortly, don’t worry ) scrolling until our text is off screen, at which case we go back to the top and start all over.  Please note that this particular code will run at different speeds depending on how fact the device it runs on is!  We will look at ways to make the code run at the same speed on all machines in a future tutorial.  For now, when you run this code you should see:

Hello

 

In the next tutorial we will dive a bit deeper into drawing graphics on screen.

 

The Video

Programming , , ,

24. January 2017

 

Are you perhaps… artistically challenged?  This tutorial will give you passable 8-bit or 16-bit style pixel art results with a minimum of artistic ability.  Of course it assumes you know a bit about Blender, but dont worry if you don’t.  We have a pair of ground up tutorial series that will0001-0060 teach you everything you need to know to follow along, this Blender text tutorial series and this Blender video tutorial series.  Alright, let’s jump right in.  We are going to use a combination of vertex painting, cycles renderer and freestyle in Blender to create an image like the one to the right.  Not the most impressive thing you’ve ever seen I’m sure… but it was exceptionally easy.

 

 

Without further ado, let’s jump in.  For this example I am not going to model the sprite, if you are interested in seeing that process, watch the full video.  Instead we start with a simple model like the following:

image

 

Now let’s look at first colouring it, then cartoon rendering it and finally how to render it in pixel art style.

 

Vertex Painting The Object

First we start off by painting our surface.  The nice thing about Vertex Painting is it draws the colour information directly on the model, so you dont need to worry about UV maps or textures at all.  We just published a video on Vertex Painting in Blender if you want more details.  In the end we are going to use the Cycles renderer, but for now it’s easier to get started painting using the built in default Blender renderer.  This will enable us to easily see the painted vertices in the Blender viewport.  In the default material make sure that Vertex Color Paint is enabled:

image

 

Now it’s time to start filling out our different colors.  In Edit mode, simply select the faces you want to be a specific colour, like I have done here for the cockpit area:

image

 

Now switch over to Vertex Paint Mode:

image

 

Now select “Face Selection Masking For Painting”

image

 

This limits your painting to the faces currently selected in edit mode.  In the Tools menu ( T ), select the color you want to paint with.

image

 

Now hit SHIFT + K to fill the selection with the current colour, like so:

image

 

Now repeat this process for the rest of the ship.

 

Toon Shading In Cycles

Now that you’ve got your ship coloured, it’s time to switch over to the cycles renderer.  If using a default layout, simply select Cycles Render in the dropdown:

image

 

With the change to Cycles Render, we should now have a new option in the Materials dialog

image

 

Click Use Nodes.  Then select Toon BSDF.

image

 

Out of the box Vertex Colors aren't going to work in Cycles, we need to make a simple shader graph to get things to work.  Don’t worry… it’s super easy.  When you do a vertex paint, the data is stored in the mesh data, like so:

image

 

That “Col” data is about to become very useful.  Switch to Node Editor

image

 

Now what we want to do is add an Attribute input and wire it into the Color field of our Toon shader, like so:

image

 

Notice the name “Col”.  This is the link back to our vertex color data.  This causes the Toon shader to use the painted vertex colors as it’s color source.  If you do a render now, it should look something like…

image

 

Better, but still quite fugly…

 

Using Freestyle

Now to get a bit of a more hand-drawn effect, we want to enable freestyle in the Blender renderer:

image

 

Notice I increased the Line Thickness a fair bit from the default… this is a personal choice.  It’s possible you don’t like the default lines it chose to highlight, but don't worry, you can control that if you prefer.  Simply go to Edit Mode, select the edge you want Freestyle to render, select Ctrl+E then Mark Freestyle Edge:

image

 

Now in the Render Layers property panel, locate the Free Style Line Set, then enable Edge Mark.

image

 

Now when we render, it should look like:

image

 

Ok, that looks a bit better!  Now how about that Pixel art look?

 

Compositor Time

The compositor is a process that runs AFTER the image is rendered and can be used to create all kinds of special effects.  In this case we are going to pixelate the result.  In the Renderer dialog, make sure under Post Processing, that Compositing is enabled.

image

 

Now, back in Node Editor, switch to Compositor mode:

image

 

Now we want to edit our graph like so:

image

 

Essentially we take our input Render Layers, scale down the resulting image to 1/5th its size, apply the Pixelate filter, then scale it back to it’s regular size and finally send it to the Composite output.  Now let’s render and see what we’ve got:

image

 

TADA!  Pixel art in just 20 easy steps.  Granted, at that size it doesn’t look great, but at actual game scale:

image

 

It looks pretty solid… for a purple, yellow and emerald model that is!  You can download the Blend used in this example here.

 

The Video

Art , ,

12. January 2017

 

Today we are going to take a quick look at the Tilengine 2D game engine.  Tilengine in their own words is:

Tilengine is a free, cross-platform 2D graphics engine for creating classic/retro games with tilemaps, sprites and palettes. Its unique scanline-based rendering algorithm makes raster effects a core feature, a technique used by many games running on real 2D graphics chips.Untitled 3

Tilengine is open source (sorry, the core isn't open ), available on Github however I never could locate what license it’s released under.

EDIT—Since posted, there has been a bit of conversation about the licensing since this was posted, read here.

  It’s a C library, but contains bindings for Python, C# and Java.  I’m actually going to use the C# bindings for the example in this review as it’s the least documented of the available bindings.  There is a single page class reference available here and a small manual available here.  The engine is geared towards creating retro sprite style games and handles graphics, animations, palettes, input and window management, but has no sound or physics engine built in.  It is also designed to be used as a backend solution to an existing front end renderer.  There are several C based examples available here, and this represents the primary way you will get up to speed.  The graphics system is designed to emulate classic sprite systems like Sega’s SuperScaler arcade board but with Super Nintendo’s Mode 7 style graphics effects available.  Tilengine is layered over SDL and is cross platform, capable of running on most desktop operating systems, as well as Raspberry Pi devices.

Tilengine is composed like so:

image

 

Tilengine has direct support for tiled map files created using the Tiled map editor.  If you want to learn more about Tiled, I have done a complete tutorial series available here.

 

As a pretty straight forward game engine, let’s jump right in with the example created using the C# bindings:

using Tilengine;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var engine = Tilengine.Engine.Init(320,240,1,16,16);
            var window = Tilengine.Window.Create("",Tilengine.WindowFlags.Vsync);
            
            // This is the clear color drawn each frame.  Think of it as the sky color
            engine.BackgroundColor = new Color(0,128,238);

            // Load tsx and tmx file.  These are created in the Tiled level editor
            // tsx is a collection of tiles, tmx is a map painted using those tiles
            var tileset = Tileset.FromFile("SOTB_bg.tsx");
            var tilemap = Tilemap.FromFile("SOTB_bg.tmx","Layer 1");
            
            // create a new layer using our just loaded tiles.  Games can have multiple layers
            var layer = new Layer();
            layer.Setup(tileset,tilemap);
            layer.SetPosition(0,0);

            
            // Now we are loading an animated sprite riped from the 90s classic Shadow of the Beast
            // Spriteset is simply the image collection composing our game Spriteset
            // SequencePack is simple text format describing the available animations, their frames, speed etc
            // While Sequence is a named entry in the SequencePack text file
            Spriteset ss = Spriteset.FromFile("SOTB");
            SequencePack sp = SequencePack.FromFile("SOTB.sqx");
            Sequence walk = sp.Find("walk");

            // Now finally create a sprite using our spritesheet
            Sprite sprite = new Sprite();
            sprite.Setup(ss,TileFlags.None);

            int spriteX = 15;
            sprite.SetPosition(15,215);
            
            // Now play the animation sequence named "walk".  We also pass the final 0 in to tell it how many times the animation
            // should loop.  Zero equals forever
            Animation anim = new Animation();
            anim.SetSpriteAnimation(0,walk,0);
            
            
            int frame = 0;

            // This is your game loop
            while(window.Process()){
                // Draw the current frame of graphics (sprites, layers, etc)
                window.DrawFrame(frame++);

                // Now check if left or right arrow/gamepad are pressed, in which case move in that direction
                // IF moving left, flip the sprite over on the X axis
                if(window.GetInput(Input.Right)){
                    spriteX ++;
                    sprite.Flags = TileFlags.None; 
                }
                if(window.GetInput(Input.Left)){
                    spriteX --;
                    sprite.Flags = TileFlags.FlipX; 

                }
                sprite.SetPosition(spriteX, 185);
                if(spriteX > engine.Width) spriteX = 0;
            }
            

            //Cleanup
            tilemap.Delete();
            tileset.Delete();
            window.Delete();
            engine.Deinit();
        }
    }
}

 

The comments pretty much describe everything that is going on there.  For more details, be sure to check the video version of this tutorial available here [coming soon].  This example loads a sprite and animation from the game Shadow of the Beast, an Amiga platformer classic.  The SequencePack file format is extremely simple XML file, here is the example used:

<?xml version="1.0" encoding="UTF-8"?>

<sequences>
  <sequence name="walk" delay="6" loop="0">
    1,2,3,4,5,6
  </sequence>
</sequences>

 

The tsx and tmx files are generated using the Tiled level editor, another open source and free tool.  As you can see, it’s extremely simple to get up and going.  Run this code you will see:

SOTB

 

This is of course a primitive example, but does show the many parts of a game.  A game loop, sprite loading, animations, level loading, etc.  The major features of the engine, that I’m not covering here, are the various sprite effects it emulates.  You can see these effects demonstrated here or in the samples.

 

The Video

Programming , , ,

Month List

Popular Comments