Showing posts with label game. Show all posts
Showing posts with label game. Show all posts

Thursday, September 3, 2015

Marble GP - multiplayer game prototype + source code



Playing with Android, I recently completed a prototype of a simple game involving multiplayer mechanisms.

But before diving into technical details, I suggest you to watch a short demo:


Written in Java using the Android SDK, Marble GP  features:
- physics managed by JBox2D
- a home-made simple 2D Open GL ES 2.0 renderer
- a home-made TCP socket multiplayer system
- a home-made parser for levels importing in SVG format

The Open GL renderer is a direct port of the C++ Open GL ES 2.0 renderer Toto2DEngine I have written for the Raspberry PI. It is primarily a sprite batch renderer working with an atlas texture. It is quite simple to use and you could even build your own high-level graphical 2D API from it.

The client-server system is quite original because the socket server is designed to be run directly by one the devices involved in the game. So the game is self-reliant  in the sense that it doesn't need a central big and expensive distant game server. In other words, the game is local wifi multiplayer.

Finally, I was looking for a very simple way to biuld levels. I didn't want to hardcode my levels by hand, because it is tedious and it rarely gives interesting results. But because it is a prototype, I didn't have the time to code a level builder tool. So I choosed to write a simple SVG parser, generating Box2D primitives from SVG XML files. Always in the way to keep things simple, I have drawn my levels with SVG-edit.


Sources

If you are curious, you can find the sources of my 2D Open GL renderer as well as my core client-server socket classes. They are part of a my new framework Simple-Android.

Friday, May 8, 2015

Toto2DEngine : demos and sources

Toto2DEngine is a convenient C++ API to program 2D GPU accelerated graphics on the Raspberry PI.

You can watch some demos:




The code source is available as alpha release:

Sunday, March 15, 2015

Preview : TotoEngine2D

TotoEngine2D is a library I develop. It exposes a convenient C++ API to display accelerated 2D graphics through OpenGL ES.

I target the Raspberry PI platform. Why the Raspberry PI ? Because at my knowledge, despite the presence of a GPU, the Rasp still doesn't have any descent API for accelerated 2D graphics. At first glimpse, the problem with the Rasp come from his incapacity to deal with OpenGL. Indeed, his architecture allows only the use of OpenGL ES 2.0, which can be seen as a fragment of an old version of OpenGL (2.0). So that's why popular libraries such SDL (accelerated through OpenGL) cannot give their full potential on the Rasp.

If you are interested by the project, have a look to the features of the engine.

Batching

The rendering process in TotoEngine2D is through batching. It means that on every frame, we begin with an empty list of objects to display, then we pile up any number of objects in it. When we filled our list with everything we want to show, we ask to render the whole in the window.

The important things to understand:
- the objects doesn't have any kind of persistence, the object list is totally cleared out after each render call
- the objects are rendered in the window in the same order we piled up them, from back to front

Here is an example of rendering sequence:

Toto2DEngine toto2d;
// sequence :
toto2d.clear(); // fill the window with the default background color
// ...
// pile up our objects
//...
toto2d.swap(); // swap the buffers to render


Atlas map

For performance purpose, only one single texture can be used when triggering the rendering process. In consequence we must work with texture atlas (or sprite sheet). TotoEngine2D manages 2 values of opacity. One pixel in the texture atlas can be full opaque of full transparent. Because texture atlas can only be made from 24bits colors (8bits by channel RGB), one color is sacrificed to play the role of the transparent color. By default this color is the plain fuchsia #FF00FF.

example of sprite sheet as texture atlas

However, several textures atlas can be loaded into memory and switched between different rendering:

toto2d.uploadAtlas(0, "atlas_1.tga"); // attach first atlas on slot 0
toto2d.uploadAtlas(1, "atlas_2.tga"); // attach second atlas on slot 1
toto2d.activeAtlas(0); // active the atlas attached to slot 0

When adding an object to the render list, sub-textures can be selected by the use of simplified UV mappings as axis-aligned rectangles on the texture. Such rectangles are defined by 4-uplet (x, y, w, h) where (x, y) defines the top-left corner coordinate, w the width and h the height. The coordinate system has (0, 0) coordinate at the top-left corner of the texture atlas, the x-axis goes positively on right, the y-axis goes positively on down and the unit is the pixel.

x = 80, y = 45, w = 40, h = 35


Sprites

The sprite object is the most powerfull object implemented in TotoEngine2D. Any single sprite may have its own sub-texture (UV coordinates) and his own transformation 3x3 matrix. It means that all sprites rendered can be independantly scaled, rotated and translated. Also, each sprite can display a different part of the texture atlas. That last feature guarantees the possibility to implement frame-based animation on top of TotoEngine2D.

Additionnally, each single sprite may be applied various color effects, such that tint or saturation.

Here is a sample of code, showing how to add a sprite:

glm::mat3 transf;
toto2d.getSpriteBatcher().addSprite(80, 45, 40, 35, transf);
toto2d.getSpriteBatcher().applyTint(255, 0, 0, 127);

Where (80, 45, 50, 35) defines the sub-texture on the texture atlas as (x, y, w, h) and transf is the 3x3 matrix that will be applied. Finally, a plain red tint (255, 0, 0) is applied with 50%  of intensity (127 as half of 255). Color effects always apply to the last sprite added.



As a result this sprite will render with the identity matrix transformation, so it will show on the top-left corner of the window. Because neither scale not rotation are involved, pixels from the texture align exactly on the pixels of the window. It is a pixel perfect situation, so no texture filtering will be involved.

TotoEngine2D uses the matrices from GLM library so we can find many ways to configure them on the GLM code sample page, Scales and rotations always occur around the (0, 0) origin of the coordinate system, being by default the top-left corner of the window. Translations unit is the pixel,  the x-axis going right and the y-axis going down along the window.

In order to place efficiently and accurately the sprite anywhere on window, TotoEngine2D gives the opportunity to use the TRST tool. The TRST tool is dedicated to set efficiently a matrix as an ordered sequence of Translation, Rotation, Scale, Translation.

Here is n example of TRST usage to rotate, scale and place a sprite exactly at the window center:

glm::mat3 transf;
float t2x, t2y, rot, sx, sy, t1x, t1y;
// the first translation places the sprite to match his local center with the origin:
t1x = -20.0f;
t1y = -17.5f;
// from that we can scale and rotate safely around the local center of the sprite:
sx = 4.0f; // horizontal scale x4
sy = 4.0f; // vertical scale x4
rot = 0.43f; // rotation in radians, approx. 25°
// finally we place the sprite at the center of the 320x240 window:
t2x = 160.0f; 
t2y = 120.0f;
// configure the matrix with the TRST tool
Utils::mat3TRST(t2x, t2y, rot, sx, sy, t1x, t1y, transf);
// add the sprite in the batch list
toto2d.getSpriteBatcher().addSprite(80, 45, 40, 35, transf);
toto2d.getSpriteBatcher().applyTint(255, 0, 0, 127);

Tiles

The tile object is a similar to the sprite, but it is constrained to reach better performance. First, several tile objects can share the same sub-texture. Additionnaly, the tile supports only the translation transformation, so it can be neither scaled nor rotated. Finally, the tile doesn't support color effect.

Here is an example of code, showing how to display 2 tiles sharing the same sub-texture:

int uvID;
toto2d.getSimpleTileBatcher().addUV(5, 173, 30, 25, uvID);
toto2d.getSimpleTileBatcher().addTile(uvID, 50.0f, 100.0f);
toto2d.getSimpleTileBatcher().addTile(uvID, 90.0f, 100.0f);

Where the addUV method registers a sub-texture as a 4-uplet (x, y, w, h) and link it to an ID. Then that ID can be used several times through the addTile method, specifying the position of the top-left corners of the tiles in the window.



Repeat tiles

The repeat tile object is similar to the tile object, but allowing to draw large rectangular surfaces in the window, with repetition of the sub-texture.

Here is an example of code, showing how to display a large surface with a small sub-texture:

int uvID;
toto2d.getRepeatTileBatcher().addUV(82, 205, 32, 16, uvID);
toto2d.getRepeatTileBatcher().addTiles(uvID, 50.0f, 20.0f, 220.0f, 200.0f, 0.0f, 0.0f);

Where addUV method registers the following sub-texture:



And addTiles method draws large rectangle with top-left corner coordinate (50, 20), width 220 and height 200:


Here is the complete signature of the addTiles method:

addTiles(int uvId, float x, float y, float width, float height, float scrollX, float scrollY)

The two last parameters scrollX and scrollY allow to scroll within the sub-texture, meaning that the starting point in the texture that matches the top-left corner of the drawn area will be moved. This feature allows to animate large background translations very easily and efficiently.


Distortion effects

The repeat tile object supports various distortion effects that will affect how the sub-texture will be mapped into the drawn area.

Starting from that 42x42 sub-texture:

Drawing it in a 320x240 window:



Here is the result of a vertical wave distortion with amplitude 10, period 84 and phase 0;

applyDistoWaveVertical(10.0f, 84.0f, 0.0f)

Same parameters but with a horizontal wave distortion:

applyDistoWaveHorizontal(10.0f, 84.0f, 0.0f)

Both cumulated:



Here is the result of horizontal accordeon dirstortion wit amplitude 20, period 84 and phase 0;

applyDistoAccordeonHorizontal(20.0f, 84.0f, 0.0f)

Same parameters but with a vertical accordeon distortion:

applyDistoAccordeonVertical(20.0f, 84.0f, 0.0f)

Both cumulated:



Camera

TotoEngine2D manages a camera system. The most simple feature is to scroll the content in the window. For example, starting from that scene:



 we can move our camera 50 pixels right and 100 pixels down:

toto2d.setCamera(50.0f, 100.0f); 

Resulting in scrolling all the content 50 pixels left and 100 pixels up, showing large drawn area that was outside the window before:



The camera allows us to do more, by focusing directly on a part of the window with opporunity to add a zoom effect:

toto2d.setCameraLookAt(200.0f, 175.0f, 2.0f);

Resulting in scrolling all the content such that the (200, 175) point becomes center of the window and zooming it by a factor 2 around that new center:





Wednesday, February 11, 2015

Bitmap triangulation extraction demo

Simply draw on the surface below. Then press SPACE to extract the triangulation from your picture and embed it into Box2D and see what happen. Press ENTER to clean and play again.



The algo is fast and accurate for almost all pictures. It naturally manages holes and interlocked shapes.

How does it work ? Just few lines of code with the help of Daedalus Lib. Have a look to the wiki page if you need to be conviced !



Monday, February 9, 2015

Guns !

I just upgraded my previous playable dungeon map generator demo with 6 new weapons ! I hope you will like them. You can go directly at the bottom of the article to play the demo.



Here is the complete list of weapons:

1. Energy gun
Very basic weapon. Given for free, it has infinte ammos.




2.  Shotgun
Very popular since Doom, the shotgun disperses a range of high-damage bullets.




3. Machine gun
It quicktly throws an accurate line of bullets.




4. Plasma gun
Faster and stronger version of the energy gun.




5. Rocket gun
The rockets are slow but accurate and the explosions are devastating. Do not use near the walls !




6. Flame thrower
Short range but pass through flock of enemys.




7. Multi-shots energy gun
Upgrade of the energy gun. It throws a range of 5 balls.




8. Chain gun
High-speed frequency and rotating barrel. Devastating.




9. Megablaster
A large and continuous blast of energy ! But it takes some time to charge...




10. Laser
Continuous and accurate ray of energy.




11. Tinyrocket gun
Hybridization between a chain gun and a rocket gun ! Definitely my favorite.




You can experiment the result below. Generate a map (with custom parameters or randomly) and then click  the "play it" button. You can directly catch the 11 weapons. Additionally, you can run by pushing quickly the UP key 2 times and dodge with LEFT or RIGHT keys quickly 2 times.


Tuesday, November 25, 2014

61 Cygni - Game prototype

I hope you will enjoy this new prototype.

Some screen captures:






I built it in 2 months. I used Box2D for physics. I used musics from Super Metroid and sounds from Doom PS1.

I used Daedalus Lib to triangulate automatically the entire level. It made things fast and easy for pathfinding, fast bullet collision detection and fog of war. A great save of time allowing me to focus deeply on gameplay.

I would love to continue the production of that game. If you are producer or publisher, feel free to contact me. We could target Steam as well as mobile platform.

Click below to play the game (fullscreen mode)

Friday, September 12, 2014

Introducing Daedalus Lib


Project on GitHub

Daedalus is a library I develop. It manages 2D environment modeling and pathfinding. I really hope this library will help designers and developers to invent new gameplays.

When I began to code Daedalus, I had many ideas in mind:

1- focus on 2D
2- fastness and accuracy
3- simplicity of use


1- Why focus only on 2D and not on 3D ? Because constraining to 2D allows to gain simplicity and efficiency. Many great games today are still based on 2D engines involving 2D mechanics, 2D physics and 2D display ; so I hope Daedalus will find his place as a new component for new 2D projects.


2- Fastness and accuracy are reached by using among the best techniques available in the fields of computational geometry : quad-edge structure and fully dynamic Delaunay triangulation. Daedalus algorithms are based on many research publications, among them:

Fully Dynamic Constrained Delaunay Triangulation by Kallmann, Bieri and Thalmann
An improved incremental algorithm for constructing... by Anglada
Efficient Triangulation-Based Pathfinding by Jon Demyen


3- For simplicity, I assumed that the library should work without any pre-generated data. Everything should work in real time : obstacles insertion/motion/deletion and path generation. Also I assumed that the library should be fault tolerant to designer/developer mistakes : obstacles can overlap and can be of any shape : open, convex, concave... At last, the path generation manages non-null size objects in order to avoid any obstacle collision.


Now the basics are exposed, I can show you some demos :



Today Daedalus is coded in Actionscript. But because the library has no dependancies from any other library (I wrote the whole mathematics), it can easily and quickly be translated in any other language. The project is not open-source at this moment, so not available for free download. I plan to use it in some new projects before release it in the open world.

So I am now looking for some collaboration. If you feel interested by Daedalus for your game engine, for a commercial game project or any other application, you can contact me directly at flash dot cedric at google mail service.

Monday, January 6, 2014

Daedalus : group pathfinding and FOV


Today 2 new demos made with Daedalus, showing in action 2 new components: group pathfinding and field of view.

The group pathfinding has many interesting features:
- it can manage any number of entities
- it can manage any size of entities
- generated paths are automatically sampled in order to synchronise the entities and avoid collision between them


We could just reproach the single common path the entities use. Indeed, if the entities have different sizes, it could be legitimate to expect them to reach the goals by different optimized paths and keep synchronisation to avoid collision. But in fact, this behavior is the subject of a new component coming soon, more focused on synchronisation for entities having completely different start and goal positions.


Then the field of view, while looking not so impressive, is a very important component to give awareness to AI entities, allowing them to detect cleverly the other entities. The features are:
- radius, opening angle, position and direction as dynamic properties
- the FOV is broken by constrained edges (other entities can hide behind walls)
- it manages non-null size entites



In the details, the FOV implementation is simply an accurate clipping system. So it can really manages the visibility of an entity through very complex situation with partially overlapping walls.


Tuesday, October 15, 2013

Chinese checkers on a spherical board



Do you like board games ? Do you like to experiment new game concepts ?

If you answered yes to one of these questions, I think you will appreciate this article. Indeed, here I offer you a variation of the chinese checkers game... on a spherical board ! This was already done for chess, but I think it is the first time for chinese checkers. So, just stop to speak now and have a game.

Choose to play against a friend on the same computer (Human VS Human), against the machine (Human VS AI), or just see the machine against herself. Then, drag the screen to navigate around the sphere and just follow instructions :


Content displayed within Unity Web Player


This project was a good opportunity for me to learn more about Unity 3D, C#, data structures and IA.

First I built the board in 3D Studio Max (from the geosphere primitive) and then I imported it into Unity. The most boring part in my C# code was to write a parser able to analyze the mesh board structure and generate automatically the core graph data structure. Indeed, it was out of question to generate the graph structure "by hand" ; I wanted a flexible solution, able to work quickly with new board designs without any long and boring new configurations. So maybe the next version of the game will offer you a large set of original boards, with some strange topologies...

Then I built my game code following a very simple MVC pattern. If you are curious about how we can apply MVC to board games, I think it will be interesting for you to look into my package structure. Maybe you could think that this is a very large package for such a simple game, but I always work in a way that allow me to extend my projects. Here my package structure is suitable to add new boards, new AI, new game modes...


  • [_] chineseCheckers
    • [_] controlers
      • [_] ai
        • AIControler
        • DistanceTable
      • [_] human
        • HumanControler
      • AbstractControler
      • MoveData
    • [_] data
      • CellData
      • DataManager
    • [_] games
      • AbstractGame
      • AIVsAIGame
      • HumanVsAIGame
      • HumanVsHumanGame
    • [_] gui
      • [_] elements
        • InGameHud
        • Menu
      • GameGui
    • [_] navigator
      • DragNavigator
    • [_] parser
      • BoardParser
    • [_] view
      • Cell3D
      • CellColors
      • Pawn
      • View
[_] FOLDER
CLASS

Finally, I coded an AI, trying to keep it very simple and CPU-light. I will explain the algorithm in a future article, but you can see now that it is very fast (so fast that I must slow-down the run in order to keep the "AI vs AI" game comprehensible).

I hope you enjoyed the game !