|
162
|
Developer / Technical / Re: colorizing part of the bitmap (white) with custom colors
|
on: October 28, 2011, 05:32:48 AM
|
Yep, Fallsburg has the standard getPixel/setPixel method down, that technique will definitely work, and depending on your needs, might be fast enough. What scenario are you using? Will you be re-coloring things often? Are these big sprites? Are you swapping out multiple colors on one sprite, or just one? Here's my pixelbender kernel for "swap 20 colors at once" <languageVersion : 1.0;>
kernel test < namespace : "com.fortressofdoors.colorswap"; vendor : "FortressOfDoors"; version : 4; description : "Specify 20 input colors and 20 output colors - pallete swap!"; > { #define PIX 1.0/255.0 input image4 src; output pixel4 dst; parameter pixel4 in_1 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_1 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_2 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_2 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_3 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_3 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_4 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_4 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_5 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_5 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_6 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_6 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_7 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_7 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_8 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_8 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_9 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_9 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_10 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_10 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_11 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_11 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_12 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_12 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_13 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_13 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_14 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_14 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_15 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_15 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_16 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_16 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_17 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_17 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_18 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_18 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_19 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_19 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 in_20 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>; parameter pixel4 out_20 <minValue: pixel4(0.0,0.0,0.0,0.0);maxValue: pixel4(1.0,1.0,1.0,1.0);defaultValue: pixel4(1.0,1.0,1.0,1.0);>;
void evaluatePixel() { dst = sampleNearest(src,outCoord()); pixel4 delta; pixel4 pix = pixel4(PIX,PIX,PIX,PIX); bool4 check; bool done = false; delta = abs(dst-in_1); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_1; done = true;}} delta = abs(dst-in_2); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_2; done = true;}} delta = abs(dst-in_3); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_3; done = true;}} delta = abs(dst-in_4); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_4; done = true;}} delta = abs(dst-in_5); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_5; done = true;}} delta = abs(dst-in_6); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_6; done = true;}} delta = abs(dst-in_7); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_7; done = true;}} delta = abs(dst-in_8); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_8; done = true;}} delta = abs(dst-in_9); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_9; done = true;}} delta = abs(dst-in_10); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_10; done = true;}} delta = abs(dst-in_11); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_11; done = true;}} delta = abs(dst-in_12); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_12; done = true;}} delta = abs(dst-in_13); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_13; done = true;}} delta = abs(dst-in_14); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_14; done = true;}} delta = abs(dst-in_15); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_15; done = true;}} delta = abs(dst-in_16); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_16; done = true;}} delta = abs(dst-in_17); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_17; done = true;}} delta = abs(dst-in_18); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_18; done = true;}} delta = abs(dst-in_19); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_19; done = true;}} delta = abs(dst-in_20); check = lessThan(delta,pix); if(dst.a == 1.0){if(check.r&&check.g&&check.b&&check.a){dst = out_20; done = true;}} } }
It's super redundant code because it's a pixel shader and so you pretty much have to write everything straight out - but don't let that fool you, it's still waaaaay fast because it's a pixel shader. I can post the compiled pbj for you if you like. Here's how I use it in the actual AS3 code: My technique works like this: 1) I set up all my sprites so that they have a vertical column of pixels in the upper-left hand side of the first animation frame, which is the palette used in the sprite (I put it in the sprite instead of meta-data so if I recolor the base sprite, it changes the palette to. Putting this handy reference in keeps me from having to getPixel() the ENTIRE image just to get the palette) 2) First thing I do is getPixel() those 20 pixels or so, store them, and erase them from the image 3) In other metadata, I provide an array of uints for the colors I want to replace with 4) I pass in both lists of colors, originals and replacements, as parameters to my pixel bender filter 5) Voila, instant palette swap! Here's what the first 4 frames of one of my sprites looks like. I've blown it up and stuck a photoshop-esque checker background in there to display the transparent pixels.  So, in code: First, I have the pixel bender kernel embedded somewhere in my code where I can access it. In this case, it's in my "BasicEntity.as" class which extends FlxSprite: [Embed(source = 'data/gfx/pixelbender/colorswap20.pbj', mimeType = 'application/octet-stream')] private static var Swap20:Class;
Now we have the Pixel Bender filter that we can do something with. Next step, get the colors in the sprite's pallete: //First, GET the default color pallete for (i = 0; i < MAX_CUSTOM_COLORS; i++) { //...search the first X pixels down from the //...upper-left hand corner of the first frame var p:uint = _pixels.getPixel32(0, i); //if it's not a blank transparent pixel... if(p != 0x00000000){ //store that pixel in the "pallete" old_colors[i] = _pixels.getPixel32(0, i); //clear it from the image _pixels.setPixel32(0, i, 0x00000000); } }
Okay, we've got our pixel bender filter, we've got our pallete, now we need to swap some things out. shader = new Shader(new Swap20());
i = 0; for each(var px:uint in old_colors) { //convert colors to float components var r:Number = px >> 16 & 0xFF; var g:Number = px >> 8 & 0xFF; var b:Number = px & 0xFF; r /= 255; g /= 255; b /= 255; var _px:uint = list_colors[i]; var _r:Number = _px >> 16 & 0xFF; var _g:Number = _px >> 8 & 0xFF; var _b:Number = _px & 0xFF; _r /= 255; _g /= 255; _b /= 255;
var j:int = i + 1; shader.data["in_" + j].value[0] = r; //set up shader params shader.data["in_" + j].value[1] = g; shader.data["in_" + j].value[2] = b; shader.data["in_" + j].value[3] = 1.0;
shader.data["out_" + j].value[0] = _r; shader.data["out_" + j].value[1] = _g; shader.data["out_" + j].value[2] = _b; shader.data["out_" + j].value[3] = 1.0; i++; }
var bmp:Bitmap = new Bitmap(pix); //create a bitmap wrapper bmp.filters = [new ShaderFilter(shader)]; //apply the shader _pixels.draw(bmp); //draw the results back to the bitmapdata bmp.filters = null; bmp.bitmapData = null; bmp = null;
You'll get the best overall performance, regardless of technique, if you only recolor when you absolutely have to and the save the results. So, if you need 100 red enemies and you have a base sprite, recolor the sprite once, save the results, and each time you spawn a "red" enemy, look up the saved pixel data for each one and just copyPixels() or whatever to get their pixel data.
|
|
|
|
|
163
|
Developer / Technical / Re: colorizing part of the bitmap (white) with custom colors
|
on: October 28, 2011, 05:07:41 AM
|
I did this in my flixel game, Defender's Quest. You can see it in action when you hire characters with different colored pallettes, and I'm also using it for all the monster sprites to get variations. There are two ways to do it (that I know of): The first approach is to just crawl through your entire sprite & and getPixel() and then setPixel(), replacing color A with color B. This was my first technique. This is not particularly fast, especially if you're doing it multiple times on a large number of sprites, but it works, and can get you by in a pinch. If you REALLY need some heavy lifting, the best approach I've found is to use a pixelbender kernel (that's Adobe's pixel shading language) and write one that searches for a specific color and swaps it out with one of your choice. I wrote such a kernel to swap up to ~20 color pairs at a time. This technique comes with a few weird edge cases to watch out for, but you can get it to work with a small amount of massaging, and then it's WICKED fast. If this sounds interesting to you, I can write it up in more technical detail.
|
|
|
|
|
164
|
Developer / Technical / Re: Adobe AIR Question
|
on: October 27, 2011, 06:18:06 PM
|
|
What do you mean by "packaged installer?"
When I deploy for Linux I can create a .deb file that I can install with Linux Mint's package manager. Maybe this will still serve your needs?
Whatever works for you. If Linux isn't a big priority for you I wouldn't worry about it - but unless you use an Adobe AIR feature that's in version 3.0 but not 2.5+, you should still be able to hit Linux.
|
|
|
|
|
165
|
Developer / Technical / Re: Adobe AIR Question
|
on: October 27, 2011, 10:15:07 AM
|
|
Sorry for the oversight - I should have phrased that better so he didn't misunderstand.
What I meant to say is they're not adding any more FUTURE support. I was really looking forward to using the new 3D Molehill API on Linux, which looks like it won't be happening.
|
|
|
|
|
166
|
Developer / Technical / Re: Adobe AIR Question
|
on: October 27, 2011, 08:33:01 AM
|
|
Definitely gonna ditto Richard Kain here - HaXe is something I'm looking into myself these days now that Adobe has frustratingly dropped support for Linux. HaXe will let you compile your game to native C, which is your best bet for performance without needing any extra runtime environments.
Donwside is it's a bit more complex to work with than regular Flash and documentation is a bit thin, but it's a really exciting development and my next project will almost certainly be in HaXe, so I can get a nice executable for download, but still have a web-enabled public demo in flash.
|
|
|
|
|
167
|
Developer / Technical / Re: Adobe AIR Question
|
on: October 27, 2011, 05:56:35 AM
|
Okay, Eli, as I understand it basically you want to see if you can: 1) Keep working in Flash like you like, without major changes 2) Get some sexy new features to do stuff vanilla Flash won't let you do 3) Write some save files out to data 4) Not have to muck about with SharedObject 5) Etc, etc The answer to all the above is YES! Now, here's what happens when you use Adobe AIR : an Adobe AIR app is basically like Adobe JAVA, sort of. It's basically a super-flash-player, that's installed on the person's computer as a runtime VM. Adobe has made it so that it's *mostly* automatic and seamless to install Adobe AIR - it's one of those things that as soon as you try to start the application it prompts you then installs/updates to the latest version of AIR in the background. Now, you can embed an AIR app in a website, OR you can deploy it as a downloadable/installable app, OR you can do both and have a little button in the browser version that installs the download version. I've only messed with downloadable/installable. Now, there's two ways to create an Adobe AIR installer - the normal way creates a cross-platform executable that brings up this ugly-ass installer. You need a certificate for this (that you buy from VeriSign or whatever) or else you'll have to self-sign it and it will warn everyone that your app might give them Herpes because the source can't be trusted. At any rate, after that it installs Adobe AIR to their computer and then your app. This works for Mac/Win/Linux. Don't know about mobile, I don't do any mobile development, but pipeline shouldn't be much different - maybe another packaging step at the end there, and deployment would probably be different, as the above commenter suggested it wouldn't be installing, just ready-to-run. SO! There's also another way to create an Adobe AIR installer - by using the NativeApp API. This requires a bunch of monkey-fiddling-around, so I won't bore you with those details unless you're interested. What this does, for the record, is makes your AIR app "targeted" for a specific platform with an additional layer of wrapping - it doesn't compile it down to Native C code or anything, but it does do the following: 1) Remove the ugly-ass installer and replace it with a slightly less ugly-ass version 2) Remove the unsigned certificate warning so you don't have to pay VeriSign, et al. 3) Add the ability to call native applications from your target os So, I use this functionality to deploy Defender's Quest on Mac/Win/Linux. I wrote/found command-line apps for each platform to output the legal resolutions of the monitor, and also change the resolution to an inputted value, then stuck those in the install directory of my game. The game has a video menu that does resolution switching, and it checks which os the game is running in, then calls the right command-line app and passes it the value the user chose from the menu. This is VERY useful for anything Flash doesn't natively support. Ie, you could have a .ogg music player that you could call silently in the background like this to drive your audio instead of Flash's internal sound player, which only runs mp3s, etc. Okay, so back to something more relevant to you. So, NativeApp in Adobe AIR (only available in AIR 2+ and Flash Player 10+) opens you up to the bowels of the operating system to do pretty much anything. But AIR itself gives you a lot of nice tasty features vanilla Flash doesn't have. Chief among them are: 1) RIGHT MOUSE CLICK EVENTS!!!!!! OMG!!!!! 2) Save / Load text files from data WITHOUT user prompting 3) All sorts of fun server/database connectivity 4) Open multiple windows (a la Mac-style photoshop, Gimp) 5) Run command when program closes Here's the Adobe Flash API. ANY entry that has that little red techno-triangle next to it (the AIR logo) is an AIR-only feature. That's the best way to learn what other fun stuff Adobe AIR can do that flash can't by itself. Okay, so a few other things while I'm at it that might be relevant: Vanilla Flash CAN load from files all day long, so long as they're in a directory its allowed to access. Can't remember what the permissions are exactly, but basically anything in the same directory or within a few folders that you have to "../" to should be fine. This super changes if you put it up online, because then you've got the whole web-only/desktop-only security sandboxes to figure out, and it can't access content from another domain without some hacking. Here's another thing - recently a feature was added allowing you to pop open load/save dialog boxes from Vanilla flash. This means, that in a normal non-AIR flash app, you can pop open a box to open a file, and also save one to disk. The restrictions are: 1) It MUST be tied to user action. Ie, a mouse event on a button, etc. 2) For save dialog, you can't set which folder it defaults to 3) Might be file size limitation on open dialog If you play the defender's quest demo, I added a feature where you can export your save file to XML, which you can later import into the full version when it comes out. I've disabled importing in the web version, but technically it would work just fine. So, let me finish by talking a little bit about File, FileReference, etc. Here's a code snippet from Defender's Quest to read the player's config.xml file (where options are saved): public static function readOptionsFile():XML { try{ CONFIG::air { var pathToFile:String = File.applicationStorageDirectory.resolvePath("config.xml").nativePath; var file:File = new File(pathToFile); var fs:FileStream = new FileStream(); fs.open(file, FileMode.READ); var xmlString:XML = XML(fs.readUTFBytes(fs.bytesAvailable)); fs.close(); return xmlString; } }catch (e:Error) { trace("ERROR @ Main.readOptionsFile() couldn't read options, defaulting!"); return null; }return null; }
The "CONFIG::air" bit is a pre-compiler directive specific to the FlashDevelop IDE which makes that block only compile if I'm using my Adobe AIR build - the Vanilla Flash build (what I use for the web demo) just reads the file from a flash cookie (sharedobject) instead. File.applicationStorageDirectory is the special directory I was talking about before. This is a variable that basically means "Wherever the particular OS I'm in puts this app's files." That will be different in each OS, but it will be a standard location specific to your app. I really don't like that that's where they put stuff, but hey, that's how it goes. It might be smart to put a button that's like "go to my files" that calls the equivalent of an explorer window on that os and pops open that folder. Okay, so if you have any more specific questions, or need any other flash help, just let me know. I've been working in flash for over a decade so I know most of the ins and outs and obscure weird problems it has. If something doesn't work or you need me to help debug syntax, can do that too. Your best first bet is just to crawl over the API whenever you want to find out how something works - that's how I learned most of my stuff. Good luck!~
|
|
|
|
|
168
|
Developer / Technical / Re: Adobe AIR Question
|
on: October 26, 2011, 06:41:07 PM
|
|
I'm creating defender's quest in AIR for Win/Mac/Linux - you can do definitely access the local file system and read/write - even better, if you use NativeApp functionality, you can call arbitrary external exe's - I use that to call command-line utilities for each OS to drive fullscreen resolution switching functionality.
Gotta run for now but will post more detailed instructions tomorrow.
QUICK UPDATE before big post tomorrow:
There are limits to how much you can store in a localobject, but if it's just basic variables, it shouldn't be a big deal. Keep in mind users with the firefox plugin "better privacy" will very easily accidentally nuke all their save files whenever they close the browser.
Your best bet with Adobe AIR is to use the FileReference and File classes from the API to write out data to a text file. Now, you'll have a special directory you'll have to write to - you can't just write anywhere, for instance, inside of the program's install directory is off-limits because of OS read/write permissions. So, either you'll have to have the user specify a directory, or you'll have to put it in your app's default data directory, which is something like C:\users\appdata\blah\blah\YourAppName\ on windows, etc, and different on each Os.
If you use this method, you can also read/write binary data - for instance, you can easily write out legal PNG files, or any other arbitrary binary blob.
|
|
|
|
|
169
|
Player / Games / Re: Indie Royale Bundle #1
|
on: October 26, 2011, 03:46:16 PM
|
|
Sent a tweet out to Simon Carless asking what the split is ... imagine I won't be hearing back for a while as he's probably got his hands full just trying to keep the servers up.
|
|
|
|
|
170
|
Player / Games / Re: Indie Royale Bundle #1
|
on: October 26, 2011, 02:20:41 PM
|
|
It looks like the IndieGames/Gamasutra/GDC/IGF people are behind it. Simon Carless has been tweeting about it and it looks like he's directly involved.
|
|
|
|
|
171
|
Player / General / Re: IGF Thread 2012
|
on: October 25, 2011, 12:54:22 PM
|
|
Cool! Great reply, Paul. I think I agree with pretty much all of that. Hope it does well and doesn't get disqualified on some technicality!
|
|
|
|
|
172
|
Player / General / Re: IGF Thread 2012
|
on: October 25, 2011, 12:33:57 PM
|
Wow, big conversation! Took me a while to read all the way through. Conversation keeps revolving back to Fez, so if nobody minds I'd like to ask a question that was touched on earlier but never fully explored - What are people's thoughts on the Pirate Kart? 1) Does it have a chance? 2) Is it a good thing? 3) Is it fair to the other entrants? My own answers to 1,2,3 are :  /  /  . And might as well plug my own entry, Tower Defense / RPG hybrid "Defender's Quest", while I'm at it: Play the Game!
|
|
|
|
|
173
|
Developer / Business / Re: Quitting game development
|
on: October 24, 2011, 01:25:55 PM
|
|
Okay, here's a shot, Fallsburg:
Basically, there's a lot of grants flying around in Academia right now (at least in the U.S.). There's no central clearing house, exactly, so you'll have to start networking and getting known in Academic circles, but I can point you in the general direction.
First and foremost there's the MacArthur foundation / HASTAC - their Digitial Media and Learning competition is something you can apply for most directly and with the least BS. It also has a lot of competition. This is how CellCraft, a game I worked on, was funded. (What happened was the team leader, who I didn't know at the time, won the grant, then hired me for the project).
In terms of goverment grants, I've been involved with committees seeking funding from the NSF and the USDA. In terms of serious games the NSF is all about STEM, STEM, STEM (Science, Technology, Engineering, Math), so you'd better be making a game teaching about those concepts. I think the STEM-thing is a bit obsessive, but that's what the current climate is.
USDA is all about health, nutrition, and obesity education. So, health and nutrition games. (The fact that the USDA has basically created the obesity epidemic through heavily subsidizing high-calorie commodity crops, then spending gobs of money on researching high-technology fixes for the problem is extremely ironic, but hey.)
If you're going for NSF or USDA grants you have to be part of a larger academic team with experience writing and seeking grants. The best way for a games developer to get involved in this is to brand yourself as a game development consultant and market your skills towards the committees that are winning these grants. I wouldn't recommend seeking government grants directly unless you have an experienced academic partner or ARE an experienced academic yourself.
What's happening right now is that academics highly interested in game design, but with close to zero experience, are getting this money and then hiring second year computer science students to flail around miserably for a few semesters programming a game the committee has meticulously designed for them in power-point. Then they test the semi-working game on a few dozen undergrads or elementary school kids, write a research paper, and declare victory, leaving the game itself to rot and die on a forgotten hard-drive in the basement. There's a real need for actual competent game designers. Ideally, you should be able to do a little bit of everything, particularly programming.
There's a few RARE shining lights in serious games right now, but I've been on a lot of these projects, and that's how it turned out. If you're VERY lucky you'll get on a team with a lot of game design experience, but largely, it will be YOUR job to bring that perspective to academia.
See if you have a local "Serious games" chapter in your area, like the Houston Serious Games consortium (I live in Texas). Get involved with these guys, meet some academics doing research in this industry, get plugged in and find out who has the grants and who needs the help. Groups like these generally are a mix of academics, game developers, and those that bridge the gap, so the culture is a tick up from the bowels of academia itself.
The need is there. If you've got the skills you can help these people out and hopefully get paid, too!
Also - Academia is a totally different world. Instead of resume's (work you've done), it's all about CV's (papers you've written). You will be marketing yourself on your game development credentials, but you'll also have to start working academic ones as well. It's a VERY different culture from for-profit company work, and has just as many gotchas and downsides, but of a different sort.
Good luck!
|
|
|
|
|
174
|
Developer / Business / Re: Quitting game development
|
on: October 24, 2011, 10:19:40 AM
|
@mikejkelley: Sent you a PM, didn't realize you'd posted here first. I'd post it for everyone's benefit, but I forgot to save a copy in my outbox, and.... I'm lazy  If anyone else is interested in academia, lemme know and I'll try to retype it.
|
|
|
|
|
175
|
Developer / Business / Re: Selling a game. Questions.
|
on: October 24, 2011, 06:52:50 AM
|
Definitely use a payment provider (FastSpring/BMT Micro) instead of something like paypal/google checkout - the % charge is slightly higher but you get much better customer service, and someone who can help you out with problems, and auto-handle hassle like currencies / tax, etc. As for upgrading, the best sure-fire way is to build that right into your game and have it dial a server or something. Less elegant solutions include popping in a timer that expires and prompts the user to visit your website. Super cheap-o solution is just to put a link to your website in the game so users actively searching for an update can find one. Support: Why not include something in your game like "Report bug!" that sends you an e-mail or something? Portals / Reviewers: Keep a big spread-sheet 
|
|
|
|
|
176
|
Developer / Business / Re: Quitting game development
|
on: October 23, 2011, 01:14:43 PM
|
|
If you have any connections to academia, there are a STUPID amount of grants right now for "serious games" projects, etc.
Most of these grant committees are in DESPERATE need of someone who knows
1) Anything about game design 2) Anything about software development
It's probably a totally different world from what you're used to, but there's opportunities there.
|
|
|
|
|
177
|
Developer / Playtesting / Re: Novus Dawn Prologue
|
on: October 09, 2011, 10:58:04 AM
|
|
Cool. I'll be sure to follow it!
Good luck with the collaboration! With such a large team it can sometimes be difficult keeping everyone on task and motivated, but if you're dedicated you can make it work for sure.
|
|
|
|
|
178
|
Developer / Playtesting / Re: Novus Dawn Prologue
|
on: October 08, 2011, 08:29:47 AM
|
|
Hey, REALLY impressed with your stuff so far. The engine looks like it runs at a decent clip and the graphic / sound of course are really nice.
Is the engine 100% original? Does it build off of flixel or any other AS3 framework?
Also, in terms of gameplay, are you doing anything new with the tactical RPG formula?
Looking forward to what you guys do with this!
|
|
|
|
|
179
|
Developer / Playtesting / Re: Defender's Quest - Tower Defense / RPG
|
on: October 07, 2011, 08:49:24 PM
|
|
Hey, thanks!
There's 6 classes in the final version of the game.
I'll check on the skills system - what exactly are you noticing? Is the problem that after you put 1 or 2 points into the skill, the next point doesn't give any visual benefit?
|
|
|
|
|