Lunea is a set of: preprocessor and libraries for D oriented to make games or multimedia applications using an enviroment oriented to processors (little threads).
There is several languages similar to Lunea:
Originally div had Pascal sintax and it was limited to the API its served. It was only for DOS.
Fenix intends port DIV to several SOs and Systems through SDL and a interpreted byte-code. SDL -> Portable.
CDIV is a set of libraries and defines to program using the "process orientated" programming philosophy. The sintaxis is tricky and has the needed to use pointers. Sintaxis inherited from C++. Allegro -> Portable.
Lunea is a set of libraries and a preprocessor to program using the "process orientated" programming philosophy.
The sintaxis is simple and you haven't to use pointer. Sintaxis inherited from D. Inheriting all the advantages
of D.
SDL + OpenGL -> Portable. Hardware accelerated; compiled. Very Fast.
Furthermore, Lunea introduces new features in comparison of cdiv and fenix.
Currently I have been working on it for months and now it works with enough features to allow making simple games. Now I'll intend to establish a work group and add new features to the pseudo-language and release a prior beta version of project.
Below, you can see a screenshot of a demo i have done and the sourcecode.
Image moon; Image light; // Here we have a process with several actions we can swap in execution time. process MyMoon { real vx = 0, vy = 0; // main action is executed firstly but we can change the action executing after action main { graph = moon; new MyMoonShadow; frame(); while (true) { // We change the velocity of process using keyboard if (key[_right] && vx < 8) vx += 2; if (key[_left] && vx > -8) vx -= 2; if (key[_down] && vy < 8) vy += 2; if (key[_up] && vy > -8) vy -= 2; // We change the action executing for this instance of process if (key[_m]) action(main2); // We update the position throgh the velocity variables x += vx; y += vy; // Here we decrease the velocity variables if (vx != 0) vx = (vx < 0) ? vx + 1 : vx - 1; if (vy != 0) vy = (vy < 0) ? vy + 1 : vy - 1; // We change the angle and size values causing bitmap spining angle += 0.05; size = 1.0 + (cos(angle) / 3); frame(); } } action main2 { while (true) { angle += 0.05; //size = 1.0 + (cos(angle) / 3); frame(); } } } process MyMoonShadow { action main { // We'll use the same graphic that uses its parent graph = father.graph; group.z = father; group.priority = father; /* It's a dump of process hierarchy: We can see how MyMoonShadow process is a child of Moon process in Z and PRIORITY trees so even when, for example, the Z value of MyMoonShadow is minor than the Z value of MyMoon since MyMoonShadow is a child of MyMoon it will be render after as well as all process that have MyMoon or MyMoonShadow as group.z. DUMP { DUMP(ALL) { - (1, MainProcess) - (2, Light) - (3, MyMoon) - (4, MyMoon) - (5, MyMoonShadow) - (6, MyMoonShadow) } DUMP(Z) { -[0] (0, ProcessManager) { -[-1] (1, MainProcess) -[1] (4, MyMoon) { -[0] (6, MyMoonShadow) } -[1] (3, MyMoon) { -[0] (5, MyMoonShadow) } -[5] (2, Light) } } DUMP(E) { -[0] (0, ProcessManager) { -[0] (1, MainProcess) -[0] (2, Light) -[0] (3, MyMoon) { -[0] (5, MyMoonShadow) } -[0] (4, MyMoon) { -[0] (6, MyMoonShadow) } } } } */ while (true) { z = father.z - 1; angle = father.angle; size = father.size; alpha = father.alpha / 3; tint = 0x00000000; x = father.x + (((father.x - Screen.width / 2) * 30) / (Screen.width / 2)) * size; y = father.y + (((father.y - Screen.height / 2) * 30) / (Screen.height / 2)) * size; frame(); } } } // Its a very simple process that blends "light.png" at middle of screen. // Its alpha is changing. If "angle" variable is minor than 0 or over 2 * PI, // Process Manager changes it to a equivalent value inner ]0, 2 * PI[ process Light { action main { graph = light; x = 320; y = 240; z = 5; while (true) { alpha = 0.7 + (cos(angle += 0.1) / 4); frame(); } } } /* "program" is a process instanced at beginning: int main(char[][] args) { try { return pmanager.start(args, new MainProcess); } catch (Exception e) { writefln(e.toString); } } The Process Manager (pmanager) has the task of execute all process orderer by priority and render them orderer by z. */ program { // Code executed just after the process is instantiated this() { Screen.set(640, 480, "Lunea Test"); moon = Image.fromFile("moon2.png"); light = Image.fromFile("light.png"); } // Code executed when program process is destroyed ~this() { Logger.add("Finishing the program"); } action main { // Set fps of game to 60 fps = 60; // Instances a new Light process new Light; // Instances a new MyMoon process // setting its x, y, z values with (new MyMoon) { x = 320 - (moon.w / 2); y = 240 - (moon.h / 2); z = 1; } with (new MyMoon) { x = 120 - (moon.w / 2); y = 140 - (moon.h / 2); z = 1; } // Change the z value of MainProcess (a shining blended box) z = -1; // Running main process until ESC key is pressed while (!key[_esc]) { // Changing angle of process angle += 0.01; if (key[_f]) fps = fmin(fmax(30, Mouse.y / 4), 120); frame(); } // Removes all process and finalizes the program exit(); } // We use direct-opengl to render a shaded filled box // We can override default draw method of process action draw { // We use angle to establish the alpha value we'll use to render the box float alpha = 1 - (fabs(cos(angle)) / 2); glEnable(GL_BLEND); glBegin(GL_POLYGON); glColor4f(0.0, 0.0, 1.0, 1.0 - alpha / 2); glVertex2i( 0, 0); glColor4f(0.0, 0.0, 1.0, 1.0 - alpha / 2); glVertex2i(640, 0); glColor4f(1.0, 0.0, 0.0, alpha); glVertex2i(640, 480); glColor4f(1.0, 0.0, 0.0, alpha); glVertex2i( 0, 480); glEnd(); glDisable(GL_BLEND); } } /* Using Lunea we haven't makefiles or something similar. We use the "lunea" command (even without parameters) and the program search .lun files in current directory searching for config blocks and obtaining how to compile from there. */ config { title: "Lunea Test"; console: "false"; driver: "gl2d"; output: "test"; import: "std.stdio"; import: "std.math"; icon: "icon.ico"; comments: "Comments"; companyname: "CompanyName"; filedescription: "FileDescription"; fileversion: "1, 0, 0, 1"; internalname: "InternalName"; legalcopyright: "LegalCopyright"; legaltrademarks: "LegalTrademarks"; productname: "ProductName"; productversion: "1, 0, 0, 1"; }