Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

23. May 2012

 

The developers over at Google have announced PlayN release 1.3!  Ok, I’m a bit late to theplayn-logo party, as they actually announced it two days ago, but hey… it was a holiday here in Canada, so I was allowed to be asleep at the wheel on this one! Winking smile

 

So, what have we got to look forward to in the 1.3 release?

 

 

- The Java backend has been rewritten to use LWJGL instead of Java2D.
This makes the Java backend behave more like the other OpenGL
backends, and allows one to write and test code that uses the GL20
(direct-to-OpenGL) abstraction on the desktop, just as one does for
the 2D PlayN APIs.

- HiDPI (aka Retina) support is implemented for the Java, iOS and
Android backends. Eventually we can probably make it work in the HTML
backend as well for games that wish to use HiDPI images for their web
incarnation. I will write an article explaining HiDPI support and how
to use it in the not wildly distant future.

Note that the Java backend now requires LWJGL's native libraries. The
new archetype contains the necessary changes to the POM to cause Maven
to automatically unpack and use the native libraries. I'll also update
the samples with the same changes. Please make these same changes to
your project's java/pom.xml when you upgrade to PlayN 1.3. Eclipse
users will probably need additional machinations, which can hopefully
be detailed by someone who has been using Eclipse with 1.3-SNAPSHOT
for the last month or so.

 

You can get the full details in the release notes.

 

To go along with PlayN’s 1.3 release, TriplePlay also has announced a 1.3 release.  TriplePlay is, in their own words:

Triple Play is a collection of game-related utility classes that can be used with the PlayN library on all of its myriad platform targets.

 

Basically it adds a heap of great functionality on top of PlayN, likes GUIs, animation controllers, etc…  The lead developer of TriplePlay, Michael Bayne, is probably the most unsung hero of the PlayN development, and is easily the most active developer outside of Google ( or perhaps, over all? ) and deserves kudos for his efforts.

 

TriplePlay 1.3 details are in the release notes.

 

 

 

To get up and running, follow these instructions.  Note, you need to set the version to 1.3 instead of the values mentioned in the tutorial.

 

EDIT: Big warning however!  The current build requires LWJGL native libraries or it will break.  They are in the process of making this part less… broken, but for now it simply won’t work unless you handle this dependency manually.

News ,

23. May 2012

It looks like GameFly, the Netflix of gaming, has decided to enter the mobile gaming space in a big way.

 

First, about a week back, it announced a partnership with Future US increasing their marketing reach:

 

The collaboration will encompass international 360-degree content, e-commerce and advertising. Both companies will also work on various content deals including cross-linking, mobile apps content and contextual e-commerce promotions.

The new deal will help grow GameFly's audience and revenue by tapping Future's established network of loyal gaming fans through both print and digital outlets, and will further GameFly's ability to offer promotions for mobile titles that can be downloaded directly from GameFly onto iOS and Android devices. Simultaneously, this partnership will advance Future's charge into the digital space by delivering an audience of over 10.8 million unique visitors, while expanding its GamesRadar network. Future's media offerings will also be diversified by representing GameFly's mobile app and GameFly Media in the advertising marketing sector.

 

Future US has a pretty impressive portfolio of gaming and tech magazines including PC Gamer as well as the official XBox and PlayStation magazines, so this is a pretty big deal for GameFly.

 

Then came todays big announcement of their iOS and Android development fund coupled with their upcoming Android game store:

GameFly will launch a development fund to support the creation of new mobile games, and expects to release its first title this summer. The company said it will seek to work with developers who are in the process of building great games but lack the financial resources necessary to properly publish and promote their efforts. GameFly is currently accepting submissions at GameDev@GameFly.com.

 

The forthcoming GameFly GameStore, expected to reach Android smartphones and tablets in time for the holiday season, will curate thousands of recommended Android games and offer daily deals. Ratings and reviews from the gaming community will accompany all Android titles sold in GameFly GameStore; GameFly also will leverage its social networking platform to drive discovery via friend recommendations. The firm already offers a Game of the Day spotlight feature within its GameFly App for iOS.



Oddly enough, beyond the GameDev@GameFly.com email address, no official details at all have been released directly from GameFly.

 

In somewhat related news, Facebook have entered the mobile game space with their Send to Mobile, although their solution will utilize existing app stores.

Facebook has detailed how its upcoming dedicated games and applications solution App Center aims to help developers drive mobile installs through convenience for users.

When accessing apps through the mobile App Center, Facebook will redirect the user to the specific App Store or Google Play marketplace pages, or load the app if it has already been installed before.

A "Send to Mobile" button will also be added to the browser version of the App Center, which will automatically install the app on any device connected to the Facebook account. Facebook says that the simplicity of the approach will make it easier for developers to increase install bases for mobile games and apps.

 

Truly interesting times to be a indie game developer!  With the horrid job Google did with the Android market, it's nice to see Amazon, and soon GameFly and Sony enter the fray.  Hopefully more developers will start making money on Android gaming now! 

 

News ,

22. May 2012

 

In this tutorial we are going to look at playing audio with the PlayStation Suite SDK.  This chapter is pretty simple over all, so it will be rather short. In the end you will have a UI driven application that can play sound effects and songs.

 

To get started, we are going to need a couple audio files, one or more songs for background music and one or more songs for sound effects.  File formats are extremely limited in the SDK, all music files must be in MP3 format, while all sound effects must be in WAV format.  If you need to convert your file, I recommend you check out audacity.

 

 

For my song files, I grabbed two freely available Mozart tracks from this site and saved them as Song1.mp3 and Song2.mp3.  For sound effects I went to freesound.org ( free login required ) and downloaded this and this which I saved as Sound1.wav and Sound2.wav respectively.  Of course, you can pick any mp3 or wav files you’d like, but these are the ones and the names I am going to use and the names I’ve chosen.

 

Now fire up UI Composer, if you haven’t already, you might want to read this tutorial, as I am not going to cover UI Composer in detail here.  Create the following UI, I called mine AudioPlayer.  Save the results and import into your project.

 

image

 

 

Let’s take a look at our GUI code in AudioPlayer.cs first, as it is the simplest.

 

using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Imaging; using Sce.Pss.Core.Environment; using Sce.Pss.HighLevel.UI; namespace Audio { public partial class AudioPlayer : Scene { public AudioPlayer() { InitializeWidget(); buttonNext.ButtonAction += delegate(object sender,TouchEventArgs e) { if(AppMain.currentSong ==0) AppMain.currentSong = 1; else AppMain.currentSong = 0; AppMain.songChanged = true; }; buttonPrev.ButtonAction += delegate(object sender,TouchEventArgs e) { if(AppMain.currentSong ==0) AppMain.currentSong = 1; else AppMain.currentSong = 0; AppMain.songChanged = true; }; buttonPlaySound1.ButtonAction += delegate(object sender, TouchEventArgs e) { AppMain.PlaySound("Sound1.wav"); LogText ("Playing Sound1.wav"); }; buttonPlaySound2.ButtonAction += delegate(object sender,TouchEventArgs e) { AppMain.PlaySound("Sound2.wav"); LogText ("Playing Sound2.wav"); }; } public void LogText(string outText) { this.labelOut.Text = outText; } } }

 

Everything here we have seen in prior tutorials.  Basically we wire up our four buttons we created in UI Composer.  nextButton and prevButton actually cheat a bit as the fact there are only two songs makes them identical in function.  Obviously if you had more songs you would require more logic.  Basically all either method do is update currentSong and songChanged values in AppMain.  We will see these variables in more detail in a second.  buttonPlaySound1 and buttonPlaySound2 simply call a PlaySound method in AppMain.  Finally LogText simply exposes the labelOut field so the AppMain class can change it’s value.

 

 

Now lets take a look at AppMain.cs:

 

using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Environment; using Sce.Pss.Core.Graphics; using Sce.Pss.Core.Input; using Sce.Pss.Core.Audio; using Sce.Pss.HighLevel.GameEngine2D; using Sce.Pss.HighLevel.GameEngine2D.Base; using Sce.Pss.HighLevel.UI; namespace Audio { public class AppMain { private static BgmPlayer songPlayer; private static Bgm[] songs; private static SoundPlayer soundPlayer; public static bool songChanged { get; set; } public static int currentSong { get;set; } public static void Main (string[] args) { GraphicsContext graphics = new GraphicsContext(); UISystem.Initialize(graphics); AudioPlayer audioPlayer = new AudioPlayer(); UISystem.SetScene(audioPlayer); songs = new Bgm[2]; songs[0] = new Bgm("/Application/Song1.mp3"); songs[1] = new Bgm("/Application/Song2.mp3"); songPlayer = songs[0].CreatePlayer(); songPlayer.Play(); audioPlayer.LogText("Playing song1.mp3"); while(true) { SystemEvents.CheckEvents(); List<TouchData> touchData = Touch.GetData(0); UISystem.Update (touchData); graphics.SetViewport(0, 0, graphics.Screen.Width, graphics.Screen.Height); graphics.SetClearColor(new Vector4(0,0,0,1)); graphics.SetClearDepth(1.0f); graphics.Clear(); UISystem.Render (); graphics.SwapBuffers(); if(songPlayer.Status == BgmStatus.Stopped) { if(currentSong == 0) currentSong = 1; else currentSong = 0; audioPlayer.LogText ("Song ended, swapped to song:" + currentSong.ToString()); songPlayer.Dispose(); songPlayer = songs[currentSong].CreatePlayer(); songPlayer.Play (); } if(songChanged) { songPlayer.Dispose(); songPlayer = songs[currentSong].CreatePlayer(); songPlayer.Play (); songChanged = false; audioPlayer.LogText("Song changed due to user request."); } } } public static void PlaySound(string soundName) { //if(soundPlayer != null) // soundPlayer.Dispose(); soundPlayer = new Sound("/Application/" + soundName).CreatePlayer(); soundPlayer.Play(); } } }

 

The UI code is identical to that we covered in the earlier UI Composer tutorial, so we will ignore those bits.  First we will declare our three audio related variables, a BgmPlayer, our Bgm songs array and our SoundPlayer.  BGM stands for Background Music ( I assume ), and these two variables represent our songs and the player required to play them.  Please note that both BgmPlayer and SoundPlayer have a dispose method and should be disposed of, something I do not do in this example ( given the primitive nature of the event loop ).  In your code, be sure to dispose of them when you are done.  The bool songChanged and currentSong are publically exposed so our UI has access to them, you will see them in action shortly.

 

In Main() we set up our graphics, initialize the UI system, create our UI and set it as active.  We then declare our song array to contain two songs, both of which are loaded from file using the constructor.  These (mp3 and wav) files need to be added to your project just like any other resource, right click your project-> Add Files… then right click the file, select Build Action and set it to content.  The actual BgmPlayer is created by calling Bgm.CreatePlayer(), which is what we do next, then we tell the player to start playing the song.

 

Next we start our never ending event loop just like before.  Unfortunately PS SDK has no callback facility to notify when a song has finished playing ( hopefully this is changed during beta! ) so we poll the songPlayer until the BgmStatus is Stopped.  If it is stopped, we simply set currentSong to our other index into the songs array.  As songPlayer has some unmanaged resources, we need to Dispose of it before creating a new player for the next song.  Next we tell the newly created player to play the next song.

 

Next we check if the songChanged flag was changed ( from AudioPlayer on button handlers ), if a song change has occurred, we perform the exact same logic as if a song had ended.  However instead of flipping to the next sound, the button press logic has already handled this step for us, so currentSong will already reference the next song to play.

 

Finally we expose a PlaySound method that was called earlier when we pressed a PlaySound1 or PlaySound2 button.  You are limited to one Bgm at a time, but this is not the case with SoundPlayer objects.  This code will allow multiple sound effects to play at once.  Remove the commented section to limit playback to a single sound effect at a time.  I am not sure what is proper form or if failing to dispose SoundPlayer before calling CreatePlayer again causes a leak, be wary!

 

 

And there you have a simple SoundPlayer application.  Normally at this point I post an image of our application in action, but that obviously doesn’t work for a tutorial like this, so I captured instead this video:

 

PlayStation Suite Audio Tutorial application in action

 

 

You can download the full project here.  This archive also includes all the songs and sounds used in this example.

Programming ,

18. May 2012

 

 

You often hear people say things like “It’s memory management that makes C++ difficult”, this is patently false.  What makes C++ so incredibly difficult for new users ( and experienced ones! ) is the complexity.  Note, I didn’t say difficulty, I said complexity.

 

Today was one of those perfect examples, one of those experiences that I want to point at and say “THIS IS WHY YOU SHOULD LEARN WITH A DIFFERENT LANGUAGE!”.  Yes, that was shouting. 

 

 

Here’s the story.  Today I had a reader request guidance on how to make a release build of my C++ tutorial.  This was a really good request, so I put it together in tutorial form.  Something quickly dawned on me… I’ve never built this tutorial in release mode.  It was pretty obvious that I hadn’t because, well, it didn’t work!   Oops, my bad.

 

 

Let’s take a look at what happened, I want to see if you can guess what the problem is.  A gold star to whoever gets it before I reveal the answer at the end of this post.  That gold star offer applies to C++ veterans and new developers alike, this is a somewhat tricky one, especially considering the starting point!

 

 

So, I was building Pang 9 ( my Pong tutorial ) in release mode.  I downloaded the project files from here if you want to follow along at home.  I simply extracted the project, then I downloaded the full SFML 1.6 SDK, imported the Visual Studio 2008 project into Visual Studio 2010 and compiled the DLLs for multithreaded release mode, and copied those DLLs into my release directory.  Code compiles just fine under release, so then I run it ( within Visual Studio ) and:

 

 

image 

 

Uhoh… this can’t be good!  The offending line of code is right here:

 

sf::Music* SoundFileCache::GetSong(std::string soundName) const { std::map<std::string,sf::Music *>::iterator itr = _music.find(soundName); if(itr == _music.end()) { sf::Music * song = new sf::Music(); if(!song->OpenFromFile(soundName)) <----- EXCEPTION IS HERE { delete song; throw SoundNotFoundExeception( soundName + " was not found in call to SoundFileCache::GetSong"); } ..... SNIP ......

Well, there is a big bad pointer right above the line, that seems an obvious candidate doesn’t it?   Well don’t waste your time on that train of thought, the pointer isn’t the issue.  The .find call seems a likely candidate too, it isn’t though.

 

Hmm, lets start looking there, ill set a breakpoint and trace into the _music.find() call.  Oh yeah, this a release mode only bug, so our hands our tied on the debugging side of things… great.  Alright, lets take a closer look.

 

image

 

 

<Bad Ptr>.  Oooh, that’s not good.  Obviously I’ve done a bad allocation here somewhere, but that just doesn’t make sense, not with the way this data type works.  In fact, the only place these pointers are even allocated is in this actual method, and we haven’t even got to that code yet!

 

For some reason, our empty map ( it hasn’t been used yet, this is the first call ), is returning a Bad Ptr instead of working as expected.  This can’t be right?  But wait… that’s a red herring anyways, isn’t it, after all our exception has nothing to do with the Bad Ptr or the std::map at all, this is just the IDE sending us on a wild goose chase. We can literally boil it down to exactly two lines of code:

 

sf::Music * song = new sf::Music(); if(!song->OpenFromFile(soundName))

 

Now we are getting somewhere, we have isolated our reproduce case down to exactly a two line program!  Hmmm, both are just standard SFML calls.  Short of being out of memory, nothing here should be able to fail.  So then, what the hell is causing this problem???

 

 

// ANSWER TIME, got your guess yet?  Did you get it right and I owe you a gold star?  Let’s find out!

 

 

Well, long story short, it’s our SFML dlls built for Visual Studio 2010.  See, this is our first method call into any SFML DLL and it’s causing an explosion… but, why the heck is that???

 

 

Well, lets take a trip over to the SFML 1.6 project and check out how I built them.  All I did was download the SFML 1.6 project for Visual Studio 2008, delete all the examples and set my build mode to Release DLL and compiled everything.  Hidden between the various warnings was one very very very important but cryptic message:

 

image

 

A bunch of warnings as a side effect of the import process, and one extremely important warning… the ahah moment if you will:

 

Warning    8    warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library    C:\temp\t\SFML-1.6\build\vc2008\LINK    sfml-graphics

 

Say what?

 

 

Now here is the thing, with C++ libraries need to be IDENTICAL.  You link debug to debug, multithread to multithread, etc…  At the same time, you have to link Visual Studio 2010 binaries to Visual Studio 2010 binaries ( although not all versions are binary incompatible, VS 2005 and 2008 could share libraries I believe ), and this here is the source of all the trouble!

 

The sfml-graphics graphics library statically links to a lib called freetype, and this library isn’t compatible with Visual Studio 2010.  Download the newest version, extract it into the extlibs folder, recompile and PRESTO, problem solved.

 

 

 

So there you go, an unhandled exception in a call to open an audio file ended up actually being caused by a statically linked font library in a 3rd party graphics dll!

 

 

Still think it’s memory management that makes C++ tricky for beginners?  The biggest problem is, new developers run into this stuff almost immediately.  You need to conquer so much to get up and running with C++, the linker being one of the earliest and most daunting obstacles.  I honestly don’t expect anyone with a few months of programming experience to have been able to puzzle this one out.  It’s exactly these kinds of things that make people throw up their hands saying “Oh screw it, programming is too hard!”.  I don’t like a quitter, but frankly in this case… they are right!

 

 

Of course, this is by no means limited to C++.  I have had very similar experiences with Java where some XML file feeding another XML file feeding a code generator called by Maven puked out a message code like “Error, unknown problem”.  Thing is, with no other programming languages do you encounter this kind of problem until you are ready to deal with the complexity.  In C++, you start dealing with this crap on day 1.

 

So this, is one such reason why I say C++ isn’t a beginner friendly language!

General ,

18. May 2012

 

Someone on the PlayStation Suite forum recently asked if there was an implementation of the Box2D physics library that would work with PS Suite.  Initially Box2Dx looked encouraging, but in the end it relied on some unsafe ( as in the keyword ) code, plus it was quite a bit out of date.  In my searching though, I did stumble upon the Farseer XNA a prominent XNA physics library.  It depends on some XNA data types, but nicely, the library includes them!

 

So I set about trying to get FarSeer working with PlayStation Suite, which proved to be a fairly simple task.

 

First you need to create a PlayStation suite library, then copy across all of the code/folders from the archive.  Make sure it is FarSeer Physics Engine class you download, the other versions have dependencies that don’t work.  Now you have to make one very small code change.  You need to open DynamicTreeBroadPhase.cs and change internal struct Pair : … to public, like this:

 

public struct Pair : IComparable<Pair> //MJF made public

 

And that’s it.

 

Compile it as a PlayStation Suite library and add it as a reference to your project and you are off to the races.  You can download the DLL I compiled for PlayStation Suite right here if you don’t want to or can’t build it yourself.

 

Now, the reason I’m not really calling this a tutorial is, I haven’t bothered to actually take the time to figure out how to use FarSeer, I just modified their sample enough to verify it runs on the PlayStation Vita.  Due to the screwy decision to make the origin the bottom left, you need to alter their examples accordingly, but otherwise everything works fine.  Here is a sample of extremely poorly configured gravity.

 

using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Environment; using Sce.Pss.Core.Graphics; using Sce.Pss.Core.Input; using Sce.Pss.HighLevel.GameEngine2D; using Sce.Pss.HighLevel.GameEngine2D.Base; using FarseerPhysics.Common; using FarseerPhysics.Controllers; using FarseerPhysics.Dynamics; using FarseerPhysics.Factories; namespace FarTest { public class AppMain { private const float MeterInPixels = 64f; public static void Main() { Director.Initialize(); Scene scene = new Scene(); scene.Camera.SetViewFromViewport(); Vector2 midPoint = scene.Camera.CalcBounds().Center; // Create circle and ground sprites Texture2D texture = new Texture2D("/Application/circleSprite.png",false); TextureInfo ti = new TextureInfo(texture); SpriteUV sprite = new SpriteUV(ti); sprite.Quad.S = new Vector2(98,98); sprite.Position = new Vector2(midPoint.X - 98/2,Director.Instance.GL.Context.GetViewport().Height-98); Texture2D texture2 = new Texture2D("/Application/groundSprite.png",false); TextureInfo ti2 = new TextureInfo(texture); SpriteUV sprite2 = new SpriteUV(ti); sprite2.Quad.S = new Vector2(512,64); sprite2.Position = new Vector2(midPoint.X - 512/2,0); //Physics time World world = new World(new Microsoft.Xna.Framework.Vector2(0,-10)); Body circleBody = BodyFactory.CreateCircle(world,96f /2f,1f, new Microsoft.Xna.Framework.Vector2(sprite.Position.X,sprite.Position.Y)); circleBody.BodyType = BodyType.Dynamic; Body groundBody = BodyFactory.CreateRectangle(world,512f, 64f/2,1f, new Microsoft.Xna.Framework.Vector2(sprite2.Position.X,sprite2.Position.Y)); ; groundBody.IsStatic = true; groundBody.Restitution = 0.9f; groundBody.Friction = 0.4f; // Now update the sprite //circleBody.ApplyLinearImpulse(new Microsoft.Xna.Framework.Vector2(0,-50)); sprite.Schedule( (dt) => { sprite.Position = new Vector2(circleBody.Position.X,circleBody.Position.Y); world.Step(dt); }); scene.AddChild(sprite); scene.AddChild (sprite2); Director.Instance.RunWithScene(scene); } } }

 

 

And here are the results:

 

physics

 

 

The only real gotcha in the code is to make sure you use the Microsoft.Xna.Framework.Vector2 when calling FarSeer code and PSS’s Vector2 when dealing with PSS code.

 

 

Obviously, my ground is a bit bouncy, my gravity is a bit wonky, but it is a working physics simulation! Smile

General ,

Month List

Popular Comments