Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

29. April 2013

We have been running a giveaway of my recently released book PlayStation Mobile Development Cookbook here on GameFromScratch.com.  Now we announce the lucky PSMwinners!

 

The lucky winners are ( by Disqus username ):

Neil Munro

Brian Beuken

Chaibi Mustapha

 

 

 

Congratulations to each of you. I sent you each an email in case you miss this thread.  I have submitted your email addressed to Packt.  Let me know if you don't hear anything shortly.

 

 

 

As to how I selected the winners… I wrote a program of course!

 

The follow is the Haxe source code for choosing a random value from an array:

 

 

package;

import neko.Lib;

class Main
{
	static function main()
	{
		var contestents:Array<String> =
			[
			"ComRevan",
			"Dave01x",
			"Neil Munro",
			"Kronaxx",
			"Liam Duffy",
			"Matin Habibi",
			"DynaVita",
			"Ayat Motevallian",
			"Brian Beuken",
			"Wojciech Musialkiewicz",
			"hdra",
			"BenjaminBrown",
			"Shawn A. Allen",
			"chaibi mustapha",
			"Calle Leppajoki",
			"Waldson Patricio",
			"Lior Tal",
			"Huy Pham",
			"Alessandro Stamatto",
			"ThePettyTyrant",
			"PSMHobbyist",
			"Joey Blaze",
			"ibai",
			"Alberto Gomez R",
			"violet",
			"pedgarcia"
			];

		var index : Int;
		var winner1, winner2, winner3: String;
		
		// Get random index between 0 and contestent array length
		// Get name at that position
		// Remove that name from the list so they cant win twice
		// Repeat two more times.
		Lib.print("Choosing first winner:");
		index = Std.random(contestents.length);
		Lib.println(index);
		winner1 = contestents[index];
		contestents.remove(winner1);
		
		Lib.print("Choosing second winner:");
		index = Std.random(contestents.length);
		Lib.println(index);
		winner2 = contestents[index];
		contestents.remove(winner2);
		
		Lib.print("Choosing third winner:");
		index = Std.random(contestents.length);
		Lib.println(index);
		winner3 = contestents[index];
		contestents.remove(winner3);
		
		//Display luck winners
		Lib.println("The winners are:");
		Lib.print(winner1 + "\n" + winner2 + "\n" + winner3 + "\n");
	}
	
}

 

 

Then from a terminal I did:

Winner

 

Congratulations to the lucky winners and thanks to everyone that participated.

,

29. April 2013

After literally years of waiting, SFML 2 is finally here along with a site redesign. If you've never heard of it, SFML is a C++ library for (mostly) 2D games, including graphics, audio, networking and io functionality. As you can see, there is also a new logo.

There aren't that many changes, this release was mostly about refactoring to eventually support iOS and Android. The 2 release has been waiting on documentation updates.

 

If you have a 1.6 SFML project, here are the code changes ( compiled by SFML user Nexus ) that can affect your code:

 


General

  • CMake instead of specific compiler solutions and makefiles
  • Use SFML_STATIC to indicate static linkage instead of SFML_DYNAMIC for dynamic linkage
  • Changed naming convention for functions from PascalCase to camelCase
System package
  • Added sf::Vector2u typedef for sf::Vector2
  • Added explicit conversion constructors from different vector types
  • All times (sf::Clock, sf::sleep(), ...) are now measured with the sf::Time class instead of float seconds
  • sf::Thread works now with function objects, no more inheritance
  • Split sf::Unicode::Text to high-level sf::String and low-level sf::Utf
  • Removed sf::Randomizer
  • Low-level memory functions operate on void* instead of char*
Window package
  • Added sf::InputStream for customized resource loading
  • Added events JoystickConnected and JoystickDisconnected to track plug/unplug of joysticks
  • Replaced sf::Input with 3 separate classes sf::Mouse, sf::Keyboard and sf::Joystick. They use global inputs, not window-specific ones.
  • Renamed sf::Window::GetEvent() to pollEvent()
  • Sizes are returned as vectors
Graphics package
  • Added low-level graphics API with sf::VertexArray, sf::Vertex, sf::Transform
  • Added sf::RenderTexture as another render target
  • Added viewport and rotation to sf::View
  • Split sf::Drawable functionality into sf::Drawable (stateless interface) and sf::Transformable (convenience base class for transformable entities)
  • Renamed sf::String to sf::Text
  • Renamed sf::PostFX to sf::Shader
  • Dynamic adaption of sf::Font, no more fixed size and character set
  • sf::Font requires the source (file, memory, ...) to remain valid throughout its lifetime
  • sf::RenderWindow::setView() now copies the sf::View
  • sf::Rect stores (left, top, width, height) instead of (left, top, right, bottom)
  • Changed sign of angles (concerns sf::Transformable rotations)
  • Split sf::Image into sf::Texture (OpenGL texture) and sf::Image (pure pixel container).
  • Renamed sf::Drawable::GetCenter(), SetCenter() to sf::Transformable::getOrigin(), setOrigin()
  • Made transformable interface to get size/bounds more uniform, now there are getLocalBounds() and getGlobalBounds()
Network package
  • Added more overloads for sf::Packet's operator<< and operator>>
  • Renamed sf::SocketTCP, sf::SocketUDP to sf::TcpSocket, sf::UdpSocket and made them non-copyable
Audio package
  • Added ability to seek in sound streams and musics
  • Fixed sf::Listener's target that was a relative direction instead of an absolute position

You can read more details about breaking changes in this thread.

 

Programming

29. April 2013

So we've already look at general development, graphics programming and handling input with Haxe with NME, now we are going to take a look at audio support.  This is by far going to be the shortest post of the series, as frankly, it's the simplest.

 

Let's jump right in with playing audio.

 

 

package gfs;

import nme.Assets;
import nme.display.Sprite;
import nme.Lib;
import nme.media.Sound;

class Main extends Sprite
{
	public function new()
	{
		super();
	    var song = Assets.getSound("audio/background.mp3");
		var soundfx1 = Assets.getSound("audio/effect2.wav");
		
		song.play();
		soundfx1.play();
	}
}

 

 

Well, that was pretty straight forward.  There are only a few things to be aware of here.  First, notice we loaded the sounds using the Assets class with the path "/audio/something".  This path needs to be defined in the NMML file.  Here is what mine looks like:

<assets path="Assets/audio" rename="audio" type="audio" include="*" />

The actual directory on your hard disk should be located within the folder Assets.  The next up thing to know is the file formats.  At the end of the day the supported formats are defined by the SDL_mixer library.  Notice how I used loaded the soundfx from a wav file, while the background music as an MP3?  There is a very important reason for this; you can only have one mp3 playing at a time.  Other more "short term" sound effects should be stored in a  lighter format.  Audio is going to be one of those tricky things, as different platforms can play different formats. It's also important to realize that mp3 is a patent encumbered format, so if you are looking to sell your game, be careful with mp3, or they could come back to you looking for licensing fees!  The ogg vorbis format is a free alternative, but isn't as widely supported.

 

Now let's take a look at a slightly more advanced sample:

 

 

 

package gfs;

import haxe.Timer;
import nme.Assets;
import nme.display.Sprite;
import nme.events.Event;
import nme.Lib;
import nme.media.Sound;
import nme.media.SoundTransform;

class Main extends Sprite
{
	var playLeft = true;
	var song : Sound;
	
	public function new()
	{
		super();
	    song = Assets.getSound("audio/background.mp3");
		var soundfx1 = Assets.getSound("audio/effect2.wav");
		
		var soundChannel = song.play();
		
		// Call our sound effect every second... forever.
		new Timer(1000).run = function() {
			soundfx1.play();
		}
		
		soundChannel.addEventListener(Event.SOUND_COMPLETE, onSongEnd );
	}
	public function onSongEnd(event:Event) {
			Lib.trace("Fired");
			var channel = song.play();
			playLeft = !playLeft;
			
			if (playLeft)
				channel.soundTransform = new SoundTransform(1, -1);
			else
				channel.soundTransform = new SoundTransform(1, 1);

			channel.addEventListener(Event.SOUND_COMPLETE, onSongEnd );
		}
}

 

 

This example is a bit more complex to show off a couple of the features of the audio libraries.  You may notice that play() returns a SoundChannel object.  This object has a number of useful features… you can manipulate the playback of the sound using this guy, by applying SoundTransform's like we do here, to pan sound left or right, you can modify the volume, get current playback position, etc…  In this particular example, we load our two sound effects, start the background music playing, then create a timer that fires ever second, playing our second sound effect over and over and over.

We also wire up an event handler that will be fired when your soundChannel gets to the end ( SOUND_COMPLETE event ).  When that occurs, we toggle the sound to either play only on the left channel, or right channel.  We then recursively wire up our onSongEnd event on our newly created SoundChannel.  This code worked perfectly on every tested platform, although Android had some weird issues… it didn't play properly at first, but once I lost and regained focus, it worked perfectly.

 

So, what about Video?

This is one area current NME is a bit lacking.  There are projects out there that provide native video playback on iOS as well as this project for playing back webm encoded video files, otherwise I believe you are currently out of luck.  So if you need to play cut screens, you are currently left rolling your own solution for each platform.  Fortunately, I do not need video support. :)

,

27. April 2013

One of the downsides to using the Tilesheet class in NME is that it can't receive events.  Just as earlier on we created a sprite object to hold our bitmap when we wanted it to receive events, how exactly do you handle this when working with the Tilesheet class?  In the Haxe/NME Input tutorial, I got asked exactly this question:

 

I tired to wrap the animation of previous tutorial before into this one.

but since the animation is an tileSheet object it doesn't want to be wrapped into a Sprite
it said

nme.display.Tilesheet should be flash.display.DisplayObject
for:
sprite.addChild(sprites); // sprite is my tileSheet and sprites is a sprite

any idea to solve the problem or it's going to come in a next tutorial

 

Hmmm… good question…  short answer is, I didn't know.  Slightly longer answer is, when you call drawTiles, you can specify where to draw.  In the earlier example we simply drew to the stage.  So, we simply create a Sprite around an empty Bitmap add it to the scene and add the sprite to the scene.

Let's look at some code:

package gfs;

import nme.Assets;
import nme.display.Bitmap;
import nme.display.DisplayObject;
import nme.display.Graphics;
import nme.display.SpreadMethod;
import nme.display.Sprite;
import nme.display.Tilesheet;
import nme.events.Event;
import nme.geom.Rectangle;
import nme.Lib;
import nme.ui.Keyboard;
import nme.events.KeyboardEvent;


class Main extends Sprite
{
	private var currentFrame: Int = 5;
	private  var sprites: Tilesheet;
	var sprite:nme.display.Sprite;
	
	public function new()
	{
		super();
		sprites = new Tilesheet(Assets.getBitmapData("img/mechwarrior.png"));
		var tileData = new Array<Float>();
		
		for (i in 0...11)
		{
			sprites.addTileRect(new Rectangle(0, i * 80, 90, 80));
		}
		
		sprite = new Sprite();
		var bmp = new Bitmap();
		bmp.width = 90;
		bmp.height = 80;

		sprite.addChild(new Bitmap());
		
		sprite.x = 0;
		sprite.y = 0;
		
		sprites.drawTiles(sprite.graphics, [0, 0, currentFrame,4],false,Tilesheet.TILE_SCALE);
		
		Lib.current.stage.focus = sprite;
		sprite.addEventListener(KeyboardEvent.KEY_DOWN, function(e) {
			graphics.clear();
			sprite.graphics.clear();
			if (e.keyCode == Keyboard.DOWN)
			{
				if (++currentFrame == 11) currentFrame = 0;
			}
			else if (e.keyCode == Keyboard.UP)
			{
				if (--currentFrame == 0) currentFrame = 10;
			}
			sprites.drawTiles(sprite.graphics, [0,0, currentFrame,4], false, Tilesheet.TILE_SCALE);
		});
		Lib.current.stage.addChild(sprite);
	}
}

 

You can run this application by clicking here. Press up and down to animate.

 

And there you go.  If you are working with a sprite animation populated by a Tilesheet that you want to receive events directly, this is one option.  A couple of things though…  handling keyboard events in this case works really really really poorly… it only works in Flash…  generally you will want to handle keyboard events at the stage level.  This code was more a proof of concept than anything else.  Simply put, it's probably a really stupid way to do this.

,

25. April 2013

 

As you may know from previous posts I am rather a big fan of Lua based game engines.  When I learned about a new one completely off my radar, I just had to check it out.  The game engine in question is Dreemchest.

image

 

As I mentioned earlier, Dreemchest is scripted using Lua.  Underneath Dreemchest is powered by a C++ core.  In terms of other Lua game engines, Dreemchest is probably most similar to Corona in scope.  It comes with a WYSIWYG editor and somewhat uniquely, enables you to use Flash to create your user interface.  Unlike Corona, you don’t need to authorize against and build on their servers, everything is done locally, I know some people really hate that about Corona and Gideros ( and more recently Loom ). Oh yeah, it’s also free(for now?).  Let’s jump in and take a look at Dreemchest.

 

First things first, you need to download Dreemchest, which you can do right here.  It is available for Windows and MacOS, although I have to admit, the MacOS version seems to be a lot less stable right now, so if you have a choice I would consider choosing the Windows version.  There is no installer, simply download the archive, extract it then run composer.  Dreemchest seems to be a Qt app, so I’m a bit shocked a Linux build isn’t available.  Then again, Linux is a fairly small sub-set of the population, so maybe that’s a down the road feature.

 

Meet Dreemchest Composer.

 

Dreemchest Composer in action

image

This is the WYSIWIG environment in action with the Animation sample loaded.  Currently there are over 20 samples available showing you how to perform various actions in Dreemchest.  As you can see from the Window above, it’s a pretty sparse environment, but most of the information you need is available.  Across the top is the toolbar you would use to configure and run your application.  Below the is the WYSIWYG editing area and below that is the output panel.  On your right hand side is the Property window, which is populated dynamically by your script objects, allowing you to view and configure values visually instead of in code.  Below that are your assets, that you can import, create then drag and drop into your scene.

 

The UI itself is incredibly customizable, every dialog can be detached, moved or closed, leaving you law things out exactly as you want.

image

 

Coding and documentation

 

So, where exactly do you do the coding?  If you have the Animation sample open, take a look at the assets panel and you will see a pair of script objects, App and Hero.

image

 

Double click one of these script files and it will open in the integrated text editor.

image

It’s a fairly barebones editor, but it does what you need including syntax highlighting, auto-completion and automatic indention.  It’s nice not having to switch apps to edit code.

 

The programming language itself is standard Lua 5.1, with an class inheritance system.  If you know Lua you will be immediately comfortable with Dreemchest.  If you press play or F5 to run your application, it runs directly inside Dreemchest:

image

As of right now, debugging options are quite light.  You can alter position, from portrait to landscape, simulate home button press and not much else.  Oddly enough, once the application is running, you see the options traditional debugging options, such as step in, step out and continue.  That said, I cant figure out how to add an actual breakpoint.  My guess is, this is a feature under active development.  I look forward to it too, as for now you would be limited with printing to the output window while debugging.  Build and load times are virtually non-existent, which is nice.

 

From a coding perspective, there is a pretty good amount of documentation, especially for such a young project.  As mentioned earlier, there are currently 20+ samples included with the download.  There are a series of tutorials available here as well as an API reference available here.  The API is quite straight forward, somewhat minimal, but still under developed.  Pretty much everything you need to create a 2D game is currently there, including graphics, tweening, audio and physics.  For physics, there is also an integrated shape editor which is rather convenient.  Still under development, new functionality is being added with each release.  This is critical though, as you don’t get source code, so you need all functionality needs to be in box.

 

Flashing

 

Perhaps the most innovative feature of Dreemchest is the ability to embed and communicate with Flash objects for creating your UI layer.  You can included an SWF file just like you do any other graphic file.  The swf file can contain ActionScript2 code, and the two languages can communicate back and forth.  Here is a simple example from the SDK on working with a Flash animation, showing how you can load and communicate between the languages.  uiButtons is the swf file that has been added to the scene.

class "Main"( StageObjectContainer )

function Main:main()
    -- Register necessary functions for Flash UI
    UIManager.registerFunction( 'nativeSetPitch', function( value ) trace( 'Pitch set to: '..value ) end )
        
    -- Attach to events dispatched from Flash UI
    UIManager.attachListener( 'uiStop', self )
    UIManager.attachListener( 'uiToggleMusic', self, 'onMusicToggle' )
    
    local ui = uiButtons.new()
    self:attach( ui )
        
    -- Notify Flash UI by dispatching an event
    UIManager.dispatchEvent( 'onRefresh', { version = 104, message = 'hi there!' } )
end
    
function Main:uiStop( e )
    trace( 'Stop the music' )
end
    
function Main:onMusicToggle( e )
    if e.pause then
        trace( 'Pause music' )
    else
        trace( 'Continue music playback' )
    end
end

This allows you to use the rich UI functionality of Flash/ActionScript for your UI layer, while performing game logic and rendering in Lua.

 

Building your application

 

When it comes to creating and deploying your application, that’s a pretty simple process.  Simply select the File->Export menu and select the platform.  You need to have a Mac to build iOS or OSX target.  You need to install the Android or iOS SDK and point Dreemchest at the proper directory before you can export to either platform.  The results of the build (an apk in the case of Android) are in the output subdirectory although I had to do a bit of searching to figure this out.

 

image

 

Conclusion

 

Dreemchest is certainly a young engine, but it has a great deal of potential.  I did experience crashes and a few UI glitches, although the newest release seems a great deal more stable.  I’m actually quite surprised by just how much it did improve in just a couple weeks, this bodes well for the future. This is certainly an engine worth keeping an eye on, especially if you like Lua and are targeting iOS or Android.  It may not be for everyone, if you need source code for example, Moai is a better fit.  But if you are looking for an all in one accessible toolkit, Dreemchest is a good pick.  Of course, it’s free too, so you’ve got nothing to lose by checking it out.

Programming ,

Month List

Popular Comments