6/26/2010

1 Year Stuck, A New Flash Game, And Much More...


So! 1 year without a single update, huh! That's quite much, specially when I promissed I'd update this blog quite regularly. But today, I'll brake this post fasting, and introduce you guys to my latest game!

But first, let me tell you what happened on the last year. First, I learned AS3 (this time, for good! That includes hacks 'n tricks and dealing with errors), then, I started re-coding Darkness 2. It was pig-coded and needed many optimizations. Said and done, reduced the 'GameLevel.as' file (the core of the game) line counting from 1500 to 1164. It's not final, but it was a great reduce. And no, I did not remove any feature, but re-coded most of it, with a cleaner and faster design in mind.

Then, later this year, I bought a new computer! Great! Now I have 4 3.0Ghz cores to my delight. Much more faster Flash compiling = much more faster releases!

But enough with the chit-chat, for now I introduce you to...

Yes! It's alive! Alive!

But! That's not all! it's up on Flash Game License for sponsorship, right here: http://www.flashgamelicense.com/view_game.php?game_id=12020

Yes. That was the 'new game' I was talking about on the post introduction.

That's all for today, folks! Hope you enjoyed.

-Luiz

11/24/2009

Chronotron-like Time Warped Player Replay

When Chronotron came out, the idea of playing with an early 'you' was not new, but was technically complex for most of programmers to 'copy' over. I must say when I first saw it, I thought about a million ways to achieve the effect, but couldn't think on any GOOD way to do it.

I had a simple concept to keep in mind: There would be a Recorder. This recorder would save the state of whatever I wanted to replay into a 'Replay' array, and then there would be a Runner. The runner would interprete the Recorder saved states and would playback it, much like a tape recorder. But I was yet to find a good implementation of the 'recorder' and 'runner'. That sent me in my journey of tries for a perfect Chronotron-like mechanics.

My first try was with a simple script (less than 20 lines, not counting the event handlers) that would store the player's position and animations at every frame. Any programmer with some experience in game coding (and general programs, whatnot) will figure the memory and performance issue we would run into after running that thing for a while. The idea of an array filled with hundred of indices scares me! That said, code scratched out and back to zero.

Second try, this time, I'd only store the player position when it changed. That is, in a rest state, no data would be saved, as it'd be silly to have an array that gone like ...[200, 150], [200, 150], [200, 150]... repetedly. But still, I had the issue of not knowing when it should change state, more precisely, when the 'runner' would skip to the next Replay indice. Oh, headaches, and back to complete nothing.

Third try, this time, I was convinced to complete my quest sucefully! And what a surprise when I tought of a good, simple and elegant way of doing it during a brainstorm session with my MP3 player running Metallica out loud! This time, the idea would be more complex than simply storing the player replay data as a set of position, or states. The recorder would store the Keyboard input into the Replay array, and then, the Runner would feed from it and spit the same movements the player did! That gave me this:



So, let's cut the crap and see how I did it:

The Recorder:

It must listen and process all of the keyboard input. It chews raw input data in the format of KeyboardKey:Array, where each indice is actually the number of frames the key was kept held down (being 0 = released, 1 = key was kept 1 frame down, 2 = key was kept 2 frames down, etc)
It then listens for when the key is released, and stores the key inside the Replay array 'KeyPress', in this order:

[key:uint, startInterval:uint, duration:uint];

This data is ordered using the startInterval value (for the sake of the Runner), being keys with lower startIntervals stored first. This sorting is done as the keyboard key is released, in a loop that runs backwardly, like this:



// If not, run a backward loop, assuming the nearest position is at the end
// of the array:
for(var i:int = Run.length - 1; i >= 0; i--){
// Checks to see the event order:
if(i == 0 || (Run[i][1] < start)){
// If this event happened before the event on [i], insert this event
// after it:
Run.splice(i+1, 0, [key, start, interval]);

break; // Break as soon as we hit the desired insertion point
}
}



Got it? Next, to the Runner!:

The Runner:

The Runner hides inside the Mc_NPC (the past You instance) code. It simply takes this Replay data and interpretes it by creating a virtual keyboard that is used by the Mc_NPC clip. Since the Mc_NPC and Mc_Player (the actual you) uses functions of same name to check whether a key is being held down (keyDown function), you can simply paste the code inside the main loop of the player character directly into the NPC past you, and as long as they share the same methods, it'll work like a charm!

But back to the runner, shall we? The Runner keeps track of time, just like the Recorder. It does so to better run the Replay with no issues. It does so in Frames (not millisecs! That'd bring the whole thing to chaos if it lags for even a fraction of a second). Since our Recorder sorts the Replay array in order of events (being the older event at the start of the array), we can simply keep track of the current event using a posNow value. This value tells us where we are in the Replay array. Then, we iterate through the Replay array catching any event that overlaps the posNow value. Let's see how it does so?:

// Iterate at Run[posNow(n)] until there are no events left:
while(Run[posNow] != null && (Run[posNow].length == 3 && Run[posNow][1] <= Runtime)){ // Register key:

// Store the key to the KeyHeld object:
KeyHeld["k" + Run[posNow][0]] = Runtime + Run[posNow][2];

KeyEmu["k" + Run[posNow][0]] = true;

posNow ++;
}


And that does it. In the same method, just above this part, there's another small loop that checks if a key expired (that is, it was released):

// Check for keys that already 'expired':
for(var s:String in KeyHeld){
if(KeyHeld[s] <= Runtime){ KeyHeld[s] = false;
KeyEmu[s] = false;

delete KeyHeld[s];
delete KeyEmu[s];
}
}


The KeyHeld and KeyEmu are two objects used to make up the simulated keyboard. KeyHeld states when the key was pressed (in ints) and KeyEmu stores boolean values (whether or not the key is being held down). The 's' variable used to iterate is equals to:

s = "k" + Run[posNow][0]; // This is the keyCode in int

I know, it's not ideal, but it was made so we could use delete on the no longer needed keys. I think it was a stupidity of mine back at the time I wrote the code.


I know there may be many more suitable implementations to this method, but I found a keyboard emulator would be more flexible than storing positions. There is no Mouse support, also, but I figured since you'd have to store the mouse positions on every frame, it'd defeat the purpose of being a clean and low-memory consuming implementation. It could be done very easily, tough!

And of course, here's the source code:

<<< (Flash CS3) >>

(sorry about the code ident, but BlogSpot broke everything!)

So, this is about everything I have to say about my experience. I hope you find some non-apocalyptic practical use for the code!

See you in a later,

-Luiz

11/07/2009

Tweening texts kills FPS?

Long time no see!

It has been a while since I made my last post. In order to kill this spare time, I thought it'd be cool to bring this blog back to life.

I'll start with this tech post explaining difficulties I had with Flash text rendering system.

In my latest game, Darkness 2, there is a simple intro, with animated texts. Even though there may be only one simple text with 'Readable' Anti-Alias on-screen at a time, the framerate would drop between the alpha tweens, and even when the text was static on screen.

The workaround for this would be simply breaking the text appart, but the FPS got even lower:

So I created a separate project, applied the text with the same font and settings, and tried tweening the text with the same tween. The result?


What's the problem? Wasn't it supposed to run at the same speed? Would it be somehow an issue with the project itself? Well, seems so, because after a little experimentation I found out that a simple white backdrop that was tweening at a lower layer of the intro MC to make the transition effect was forcing the text movieclip to re-render every frame.

It wasn't even supposed to behave like that, after all, the tweening backdrop was behind all the other elements, including the texts, and when the text was idle, so was the backdrop tweening.

I guess after that I'll have to stick back to .png texts, faster, better and looks nice.

-Luiz

6/21/2008

Avoiding .sol hacking

Some of you may know (and may use) the famous 'Flash cookies'.
I'm talking about a Shared Object that is used by the developer to store data to the users' computers. It can be used to store a highscore, the last level and even password information.
You may think 'Why would somebody hack a .sol file?' well, nevermind, but people were thinking the same about hacking a .swf file.

Ok, I'll make a example:
On Kongregate, all game saves are made using Shared Objects.
Games use this method to store a highscore, a level score, the last level reached, the cash the player has and other stuff.
Now, with a simple program called SOL Editor I could easily hack a game save data and win a badge for it.
Now, if someone also had this brilliant idea, (s)he would hack it to.
It would be a catastrophe if everybody think the same thing.

How to solve this?
Well, unlike .swf, you cannot encrypt a .sol object via Flash, but you can use some nasty tricks to obfuscate the .sol object:

1: Using fake data:
Store a variable called 'MONEY' (yes, with caps) in the .sol object and give it a unique value.
like: 18948
In the .swf, load this value, and test if it still 18948. If not, someone hacked it! If someone did hacked it, just reset the data on it.

2: Using encrypted data:
In the case some smart user found that there's no money in your pinball game, you can use obfuscated data to avoid malicious changes.
Like:

currentl = "adskGrh";

As the variable shown up there does not follow a logic (not explicit), the user will not know what do do.

3: Using swapped vars:
As the name says, you just need to swap two variables values and save it.
Like:

score = 13245;
currLevel = 12;

Swapping on the SharedObject, it would sound like this:

score = 12;
currLevel = 13245

4: Using japanese chars to crash the editor:
the saved .sol!This is my favorite way to do the job, but I must warn you that doing this you run the risk of lose the .sol!
But anyway, it's as simple as 123:
Save the normal data, and when finished, save a random variable with a japanese/other strange language char:

貘 = 譞

When the editor try to load , it will crash.
But some .sol editors skip these vars.


Well, that's all for today! You can stude more using our favorite tutorial finder!

Bye!

6/11/2008

Making a Scroll Bar in Flash 8

Other day I was making a rate system for a site and then I faced with a BIG trouble: The scroll bars.

it took me 3 hours before figuring out how to do one and with help of a video tutorial!

So, as many of you who are reading this may be needing some help, I decided to make this small tutorial to teach you how to make a small Scroll bar with dynamic resizing ;)


Ok, so let's start with a 300x1000 MovieClip with a bunch of stuff in it (that forms a 300x1000 MC), rename it 'Content'.
Now, to start making the scrollbar, you need first mask the scrolling MC with a 300x300 shape.


Here I made this and I applied a drag system so you can see what I'm talking about:




You can see that the MC is being masked, but where's the scroll bar?
So we'll start by the slider:

create a MC with the same height of the mask and place it a little bit to the right of the scrolling MC. Just like this:



Convert it to a MovieClip and rename it 'slider'.
To make the thumb, just duplicate it and make it darker:


You can't really se the slider becouse the thumb is covering it, but even if the content is smaller than the masking area (therefore, the thumb is no needed) it (thumb) will be hidden.

Anyway, now whe REALLY need start scripting. Let's start by resizing the thumb:

resizeFactor = 100; // Resizing factor, the less this is, the smaller the thumnb will be.
thumb._yscale = (300/Content._height)*resizeFactor; // 300 of the masking shape's heigth
if(Content._heigth < 300) // Hide the thumb if the content is smaller than the visible area
thumb._visible = false;

Now, calculate tha max y position of the thumb for dragging intentions:

yMax = (slider._height-thumb._height);

The dragging, for me, is the hardest part. We'll have to figure out how to move the content MC the right amount as the thumb goes down.
And the best way to do this is using percentage calcules! :D
The idea is this:

thumb._y/yMax = percentage of scrolling.

So, if we do a little math...

Content._y = -(Content._heigth - maskHeigth)*(percentage of scrolling);

this will result in a nice, smooth scrolling system :D

but before!

The boooring dragging system:

drag = false;

// the resizing code goes here.

thumb.onPress = function(){
yOff = thumb._y - _ymouse;
drag = true;
}

thumb.onRelease = function(){
drag = false;
}

thumb.onReleaseOutside = function(){
drag = false;
}

thumb.onMouseMove = function(){
if(drag){
thumb._y = _ymouse+yOff;
}
//APPLY SCROLLING CODE HERE!
}


In the place of the APPLY SCROLLING CODE HERE! comment we'll put the scrolling code (duh!).

I'll save you're time an provide a ready-to-past code:

Content._y = (Content._height-300)*(thumb._y/yMax);

But wait! I forgot to script the bondaries code xD
This code goes right after the if(drag) code:

thumb._y = Math.max(thumb._y,0);
thumb._y = Math.min(thumb._y,yMax);

Putting togheter all this mess, converting it to a MC, applying a final 'touch', this is what we get:


http://www.swfme.com/view/1103912


And why not download the source!

Thanks for reading! Bye :)

6/08/2008

gotoAndLearn

I'm here to talk about a great Flash video tutorials site I found on my wandering around the internet. I'm talking about gotoAndLearn. You may think: "Oh yeah... Another paid site..."
But ALL tutorials are FREE and they come with source! :D

There are ActionScript 2 and 3 tutorials, and even 4 Astro tutorials!


It's great, worth to check out ;)

http://www.gotoandlearn.com

6/06/2008

FlashDevelop

No, I'm not talking about the blog, but the FlashDevelop, a software that I found on my wandering on LivesInABox's Adventures in Actionscript blog.

I think it's a great software with a really good potential, but before saying anything, why don't you try downloading it?


And for those who're wondering, it's an ActionScript tool with many (many!) features, which are listed here.
But if you're lazy:

Summary

FlashDevelop is a popular open source ActionScript 2/3 and web development environment.
FlashDevelop seemlessly integrates with Adobe Flash IDE, Adobe Flex SDK, Mtasc, Haxe and Swfmill.

Main Features

* AS3 Project management with seamless and optimized Adobe Flex SDK integration
* AS2 Project management with seamless Swfmill and Mtasc integration (using a portable standalone command line tool)
* Advanced ActionScript 2 and ActionScript 3 completion & code exploration with automatic classpath detection (even without project)
* Smart contextual Actionscript code generators
* SWF and SWC classes and symbols exploration
* Test movie in Adobe Flash IDE and with clickable error results (Flash CS3)
* MTASC compilation/code checking with clickable error results

Other Features

* Types Explorer
* Automatically cleans ASO files of modified AS2 classes
* Files explorer (can create Flash 8 Trust Files for you)
* Automatic JavaDoc creation from methods
* Smart Actionscript help websearch on F1
* Jump to class/member declaration on F4
* XML, HTML/PHP, JS, CSS code highlighting,
* Multibyte character encoding
* Program menu customization with XML files
* as2api GUI for documentation generation
* Snippets
* Lines bookmarks
* Code folding
* Zoom

Resources

* Special shortcuts for Actionscript coders
* Support: AS3, usefull threads to get started
* Support: AS2, usefull threads to get started
* Support: AS2, samples & tutorials
* Region folding in ActionScript
* Quick Build with @mtasc command (@mxmlc works the same)
* Argument processing in FlashDevelop (in menus or snippets)
* Contributing: getting started with FlashDevelop development
* Team members and contributors

(taken from the FlashDevelop site).

And the best... It's FREE! :D
AND OPENSOURCE! :D AND IS WRITEN IN C# (my mother language :3) :D

Ok, think I'm being a bit too happy...
Anyway, visit the website, be happy, and buy a beer to Emanuele! :D