-
Notifications
You must be signed in to change notification settings - Fork 197
Using C code for path finding in your ActionScript game
If you’ve been wondering how to use C++ code in a Flash game, you’ll be happy to hear that Adobe has introduced Flash C++ Compiler (FlasCC). Flascc is a complete BSD-like C/C++ development environment based on GCC that lets you compile your C/C++ code and create full SWFs or SWCs to be used in the development of Flash games.
This article introduces ActionScript 3 developers to flascc by walking through the development of a C++ path finding library for a simple Flash game. If you are going to use C++ code in your Flash game or if you just want to learn how flascc fits into the Flash ecosystem, this article is a useful guide for getting started based on a real world use case.
To see the chasing game that you will build in this article live, visit http://renaun.com/flash/pathfinder. The article will cover creating, debugging, and optimizing SWCs with flascc, as well as how to integrate an SWC into your Adobe Flash Builder ActionScript 3 project.
The flascc SDK comes with helpful documentation for getting started. Installation instructions for both Windows and Mac OS are found in the README.html file at the root of the flascc package. The following are some installation notes for following along with this article. The files you are interested in are located at sdk/usr/bin/g++ and sdk/usr/lib/asc2.jar
, both relative to the flascc installation root folder.
Note: The recommended installation root folders for flascc, C:\flascc\
on Windows and ~/flascc/
on Mac OS, are used for this article.
The flascc samples and the sample files of this article include makefiles. On Mac OS you might need Xcode to get the required make application, so for this article I’ll also show you how to use the command line instead of make. If you’re using Window you can get a version of make by installing Cygwin. I recommend using the included run.bat file to install the flascc-specific Cygwin version that includes all the required packages.
To simplify instructions for the remainder of this article, I’m going to prescribe a location for saving and building the samples for this article.
1.Go to the flascc samples
folder and create a new folder named PathFinder
.
2.Download the sample files for this article.
3.Unzip the sample files in the samples/PathFinder
folder you just created.
You should see subfolders named Step1 through Step10; these contain the code that is shown throughout the article. You can use them to follow along if you don’t want to write code or commands by hand. The compile.sh, debug.sh, or optimize.sh files in the Step folders also contain the commands to run the specific steps in the command-line shell. For more explanation of the files and folders in the sample files refer to the README file that is included in the root folder of this article's sample files.
Note: The article references paths relative to the samples/PathFinder folder. If you unzip the sample files in another location you will need to change the path values and commands given in this article.
Compiling a SWF from a C app (Step 1) Follow these steps to compile a SWF from a C application:
- Open a command-line shell to execute commands. This is the Cygwin command prompt on Windows or Terminal on Mac OS.
- Change to the samples/PathFinder/sandbox folder that you created above.
- Create a text file with your favorite editor and name it hello.c. Insert the following simple C code (found in the Step1 folder):
#include <stdio.h>
int main()
{
printf("Hello World!\n");
}
- Save the file and return to the command line.
- Now you are ready to compile this application with the special flascc compiler tools. Use the appropriate command below in your command-line shell:
Mac> ~/flascc/sdk/usr/bin/gcc hello.c -emit-swf -o hello.swf
Win> /cygdrive/c/flascc/sdk/usr/bin/gcc.exe hello.c -emit-swf -o hello.swf
You can run the SWF in a standalone Flash Player and see the Hello World text display in the Flash application. Notice the use of the –emit-swf
flag, which is not commonly used with GCC. Typically GCC creates an executable; flascc supports this option as well with the ability to create a Flash projector application with a copy of the ActionScript Virtual Machine (AVM) runtime. For a list of flascc specific GCC compiler flags see the reference documentation under "FlasCC-Specific GCC Command Line Options". You will learn more of these flascc specific GCC command-line options as you progress through the steps in this article.
Compiling a C++ class with flascc (Step 2)
Now that you’ve compiled a simple C application, you are ready for something a little more advanced: compiling an application with a C++ class.
1.In the samples/PathFinder/sandbox
folder create three files named pathfinder.h, pathfinder.cpp, and main.cpp (you can find sample copies in the Step2 folder). You will create a basic C++ class with two properties x and y and one method called move.
2.Declare the C++ class in the pathfinder.h file:
class Pather {
public:
int x, y;
void move(int dx, int dy);
};
- For the implementation, open pathfinder.cpp and add this code:
#include "pathfinder.h"
void Pather::move(int dx, int dy) {
x += dx;
y += dy;
}
The move method is implemented by adding deltas to the x and y properties of the class.
To try out the class you’ll need to compile a SWF. But this class by itself is not an application so you need to create one in the main.cpp file.
4. Add the following code to main.cpp:
#include <stdio.h>
#include "pathfinder.h"
int main()
{
Pather *p = new Pather();
p->x = 10;
p->y = 15;
printf("Pather x/y: %d/%d\n", p->x, p->y);
p->move(5, 10);
printf("Pather x/y: %d/%d\n", p->x, p->y);
}
The application will create an instance of the Pather class, set the x and y properties, and then call move to update the x and y values.
5.Compile this application with one of the following commands:
Mac> ~/flascc/sdk/usr/bin/g++ pathfinder.cpp main.cpp -emit-swf -o main.swf
Win> /cygdrive/c/flascc/sdk/usr/bin/g++.exe pathfinder.cpp main.cpp -emit-swf -o main.swf
Notice that you are using g++ instead of gcc now since you are compiling a C++ class. Also you need to specify all the classes to compile, which means you include both main.cpp and pathfinder.cpp file in the compiler arguments.
Run the resulting main.swf file and inspect the output.
You have created a full SWF application from C++ with no ActionScript 3 code. The goal, however, is to create a SWC library from the C++ code with flascc and use it in a normal ActionScript 3 project.
Flascc relies on the Low Level Virtual Machine (LLVM) compiler infrastructure to turn C/C++ code into an intermediate representation (IR) format. The flascc compiling tools take the IR and generate ActionScript bytecode. As you may know, code in the ActionScript Byte Code (abc) format runs in the AVM when a SWF container file is run in Flash Player. Traditionally, the Flex compiler (mxmlc) or Flash compilers (asc and asc2) produce SWF files but some of the tools can create abc code directly, which I’ll cover later.
The magic of the tools goes only so far. It doesn’t automatically make your C++ code work as Flash Player classes. It also doesn’t magically know all the Flash Player APIs and hook up everything for you. This is important to understand because it means you have to help bring the two sides together. This is done in a few ways and there are a few options on the C++ side to bring ActionScript 3 into your code through the C++ inline feature.
There are several basic changes that need to be addressed. The big one is memory. Flash Player has a garbage collector, whereas in C++ you have to manage all memory allocation and deallocation explicitly. To facilitate manual memory management Flash Player added a feature called domainMemory. It allows direct access to a block of memory. This allows the IR code for malloc and new in C/C++ to work inside Flash Player.
This means the Pather class you created in the last section needs to be created and destroyed manually inside the domain memory, not automatically like a normal ActionScript object. From an ActionScript 3 developer standpoint this is very important to understand, because you will have to manage code generated by flascc in the C/C++ memory mindset.