Creating a small game with tengine
- Tutorial
Most recently, I posted a post about my small tengine project . For me, it was rather unexpected that many showed interest in his ideas and developments. And since there is interest, this is an occasion to continue publishing.
This article is a tutorial on creating a small game. The need for it is obvious: ideologically, creating something in tengine without a level editor (MapEditor3, hereinafter me3) is virtually impossible. It is with the help of it that resources are attached to the objects of the game, files with identifier constants are generated, a scene, sound schemes, etc. are created. And most importantly, me3 generates ready-made binary level files necessary for the tengine logic to work: a file with general data (o-file), data files for each level (l [0..n] files) and files with text data ( t [0..n] files)
First, create the space_invaders folder and the folder structure inside it:
After running me3, you should configure the paths for working with resources: “File-> Configure paths” and set the path to the “rawres” folder. Then go to “File-> Editor Settings” and set the global settings: type of graphic resources. In the current version of me3, it is possible to work only with bmp or png formats. If bpp <32, the color 0xff00ff is considered transparent, if bpp == 32, the alpha channel is responsible for transparency. Set the resource type to png.
After setting the global settings, you can start creating the scene: “File-> New Project”. Now create the first scene (map): "Project-> Create Map". A window appears with the settings of the new card:
Level 0 has been created, but I want to dwell on one important point. While the map is empty, we need to think about whether we need such small fragments of the map (8x8), with such a large screen. Probably no. Therefore, we simplify the work of the render and increase their size, thereby reducing their number. To do this, go to the “Background of the Game-> Set Background Elements” menu, set the new width and height of the fragment to 32 pixels, put a checkmark on “Save map size ...” and click “Apply” (I agree, it’s a bit uncomfortable and not intuitive). You can check whether everything is normal with the dimensions by looking at the map settings: "Project-> Map Settings".
A bit more information about maps (scenes): tengine can load several maps and draw them simultaneously (one on top of the second) onto the specified render plane. Loaded maps in tengine are called layers. Up to 4 independent rendering planes are supported architecturally (each platform has its own implementation of a rendering plane). A theoretically infinite number of logical layers can be attached to one rendering plane, but only one of them can be the primary layer and can draw background tiles, have objects with loaded animation, play musical circuits (calls to the described functions in non-basic layers are either ignored, or give an assert error). In addition to these features, logical layers do not intersect with each other in logic. An example of using multiple layers:
First, create a background. To do this, go to the background mode: press F2 (or the icon on the panel with the background image). A palette of background objects appears. You can associate empty palette cells with graphics in several ways: element-by-element (move the cursor over the desired element and press "Enter" or double-click the mouse) or the function "cut the finished picture". We will use an easier way: place the cursor on any element of the palette, which will be the first element of the cut picture, select layer 0 of the mixer (Active layer) and click the scissors icon. In the menu that appears, select the desired picture and click "Apply." As a result, we see a group of cells associated with a graphic resource.
A bit about the layers of the mixer. The background can consist of many layers, for this you need to set the desired number of layers in the background settings: "Game Background-> Set Background Elements". Layers are drawn in ascending order, or, in other words: layer 1 overlaps layer 0. Thus, more interesting tile map combinations can be achieved. The Active Layer: All setting draws all layers, showing how they will be drawn on the map.
So, the palette of background objects is ready. They are transferred to the map very simply: select the desired area of objects with the mouse, copy (ctrl + c), put the cursor in the right place on the map and paste (ctrl + v). Moreover, the copy-paste operation works on the palette itself, you can copy and paste objects anywhere in the palette, you can copy and paste background tiles anywhere on the map. There is another useful function to “multiply” (or “bridge”): copy a certain area of the background objects, select another area of the map (or the entire map ctlr + a) and press ctrl + alt + v, as a result - the entire selected area will be filled with repeating fragment of the copied area.
A bit of additional information about background elements: You can set some properties for the background object of the palette. To do this, create types of background properties in the background properties manager (menu "Game Background-> Types of Background Properties"). In the properties, you can set the logical "passability" of the elements, as well as assign a certain additional digital parameter that can be used in game logic. After creating property types, in the palette of background objects, you can assign properties by pressing “Enter” or double-click on the selected object and select the desired type in the window that appears (the “Fragment Type” drop-down list). From now on, all tiles of a map of this type will have the specified properties (checked by pressing ctrl + p on the selected tile under the mouse cursor).
The only condition for all these manipulations: the background mode must be active (the "Background mode" icon in the "pressed" state on the toolbar).
In order for sounds to appear in the game, you need to create a sound scheme. It has already been described above that sound schemes should be created only on cards that will become the main layers. It should also be noted that sound schemes belong to the cards, and not to the game as a whole: each level requires its own sound scheme, if you plan one set of sounds for the whole game - copy and paste one sound scheme between all the cards that will be the levels of the game.
First, switch to the object mode: press F1 (or the icon on the panel with the image of objects). In the lower window of the object palette, switch to the "System" tab, grab the "SOUND SCHEME" object and drop it anywhere on the map. Then we go into the properties of the object on the map (ctrl + p or use the right mouse button to call the context menu of the object and select "Properties"). In the window that appears, add sound files, give them identifier names and set them to SFX (effect) or BGM (background music) parameters.
Before creating game objects, you need to create a list of animation types and states. First, run the animation type manager ("Project-> Animation Types") and add two types that should be enough for our small game: "ANIM_ACTIVE" and "ANIM_DAMAGED". Now create state types of objects. We start the state type manager ("Project-> States") and add two states: "STATE_ACTIVE" (to which we tie the animation "ANIM_ACTIVE") and "STATE_DAMAGED" (we tie the animation "ANIM_DAMAGED").
A bit of additional information about states: all the logic of game objects is wrapped around states. It is the states that give the object a logical (logical, since the names “up”, “down”, “right” and “left” are introduced only to dereference the four options of directions) the direction of movement, especially when the object is attached to the path nodes, and also set the name animation that you need to play now.
The second most important parameters after states for an object are properties. They are created in the property manager as a template ("Project-> property template"). We add two important properties: “PRP_ENABLE” and “PRP_SPEED”. Properties of an object can be invented as many as you want, but only tengine responds to these two with internal logic. If “PRP_ENABLE” does not equal 1, the object is not drawn and does not participate in the logic of the game process. The "PRP_SPEED" property sets the speed of moving along the path nodes. If these properties are not created, it is considered that "PRP_ENABLE" == 1, "PRP_SPEED" == 0.
We will also create one event, we will need it, to determine the end of the animation of the death of a space alien, in order to know the moment when you can remove it from the scene. To do this, run the event manager ("Project-> Event Types") and create the event type "EVENT_END_ANIM_DAMAGE_INVADER".
It is important to know: you can add or remove types of animation, states, events or properties at any time at any stage of project development.
Now you can create our first type of game object. First, switch to the object mode: press F1 (or the icon on the panel with the image of objects). In the lower window of the object palette, switch to any tab “General” (you can rename it). Right-click in the window to call up the context menu and select the "Add Object" item. Let the first object be a space alien.
The window for creating a game object consists of two main tabs: General and Animation Editor.
The General tab contains the settings:
Let's name the object SPACE_INVADER, set its default state to STATE_ACTIVE and go to the second tab, where we can create the animation.
Animation Editor Tab The very first thing to do is to select the desired animation name from the list and create the first frame. Select the animation "ANIM_ACTIVE", go down just below the animation selection field to the frame window, right-click on the context menu and select the "Add empty frame" item. We created the first frame of animation. Now you need to cut the graphic elements for the graphic component of the frame. To the right of the empty frame we see an auxiliary window. We make sure that in this window the active tab “Graphics” contains the active sub-tab “Standard”. Right-click on the still empty window-palette of graphic elements, call the context menu and select "Edit". A window for editing the graphic image of the object has appeared. Here graphic elements are created (cut out), from which animation frames will be created. First, create a new group into which we will collect the elements of aliens. To do this, right-click on the window of groups of graphic elements (the leftmost window with the inscription "General") call the context menu and select "Create Group". We call the group "INVADERS". Now we make this group active (left mouse button) and right-click in the group to call the context menu in which we select “Add” (or press the Insert button). An empty cell appeared in the group. We make it active. Go to the "Source File" window and select the "characters.png" file. After that, in the picture that appears, select the image area of the alien of the first phase of the animation (for convenience, use the arrow keys to move the selected area, as well as the combination of ctlr + arrows to resize the selected area, also use the sliders to zoom in). Add another frame to the INVADERS group and select the image area of the alien of the second phase of the animation. Click "Apply." We are back in the animation editor. Now is the time to create the alien animation frames. Select the desired alien image in the palette of graphic elements, put the mouse on the frame field, call the context menu with the right button and select the "Set" item. By analogy with the first frame, add another empty frame and set the second frame of the alien. Let's see what we got. We press the “Start” of the player and see how our first animation works. Are the frames changing too fast? Set the time for each frame. Click Stop. We switch with the mouse in the frame window for each frame and set in the "Frame Time" field of the "Current Frame" group to 200 (ms). Check again. Now the animation works as it should.
It's time to add a bit of a logical component to the frame: collision area (collision zone). It will be needed to determine the zone of a bullet entering an alien. It is important to know that in tengine an object’s graph does not take part in the logic of computing collisions or “visibility” zones. Two logical parameters have been introduced for these needs (these concepts are conditional, since tengine does not operate with these zones in any way):
There is another way to determine the collision area: using an additional “collision” raster map. For more information about working with this functionality, see the documentation (prHasAlphaCollideMap () and prGetAlphaCollideMapValue () functions).
Select the first frame of the animation. Switch the tab of the auxiliary window from “Graphics” to “Logic”. For convenience, the image graphics disappears. In this case, we need to see the image in order to outline it with a zone-zone. We put a tick on the option “Graphics and Logic” (the lower part of the animation creation window). In the auxiliary window we put a check mark on the properties "workspace of the object", thereby activating its editing. We enter the parameters W = 40, H = 30, then grab the resulting rectangle with the mouse and place it so that the “alien” is inside it (for the convenience of moving objects, you can use ctrl + arrows). Copy the selected area (if the selection is gone, click the mouse on the edge of the rectangle, thereby selecting it) using the keyboard shortcut ctrl + c, switch to the second frame and insert (ctrl + v) the zone zone for this frame as well. Thus, we get an animation of a space alien with a kolizh zone in each frame. One thing remains: create an icon for the object selection palette. We select the first frame, call the context menu of this frame and select the "Create Icon" option. Now that’s it, you can click “Apply”. Our first object appeared in the object palette.
We build on an alien map. To do this, grab the object with the mouse and drag it onto the map. Since we will have many aliens, you can use the "clone" function of the context menu of the object on the map.
To simplify working with objects, the editor has an object manager (ctrl + o). It is more convenient to monitor the number of objects, change their position in the rendering list, properties, etc.
By analogy, we create an animation of death for the alien ("ANIM_DAMAGED"). The only thing on the last frame of the animation in the "Event" field is to select "EVENT_END_ANIM_DAMAGE_INVADER" from the drop-down list. We also create objects with the TURRET cannon, the BASE base and the MISSILE rocket. We put them on the card. Moreover, we put several missiles on the card, set them properties PRP_ENABLE = 0, we need them for the pool.
A bit about pools: the tengine ideology forbids the generation of objects. Therefore, all the objects that you plan to “create” during the game must be in sufficient quantity on the map and have the property PRP_ENABLE = 0. Additional logic is also written in the game logic to use this pool.
Some additional information about working with texts in me3:
Text fields are dynamic and static. The text of dynamic fields can be changed from the application code using special functions. We do not change the text of static fields; an identifier is assigned to it for a string that automatically changes its value depending on the selected current language.
Create another map. We will use it to display text messages. This will be the logical layer of the game menu. “Project-> Create a map”, put the dimensions 25x19 (800x608), the dimensions of the map - 1x1 screen. Let two languages be available in our game: Russian and English. Go to “File-> Editor Settings”, select the “Text Editor” tab. We click on the "Edit" button under the window of available languages and in the window that appears, change the language "DEFAULT" to "LNG_ENG", "LNG_1" to "LNG_RUS". Then I found an annoying editor error, initially in the manager window that appears there is no choice of languages. You need to enter any letter in the search box and delete it, only then you can see the list. This will be fixed in the next version of me3. After that, click “Apply” and check off our languages “LNG_ENG” and “LNG_RUS”. Click Apply again. Now you need to check if the project has fonts available for use. If there are no files with the extension * .fnt in the “rawres” folder, you need to create a font.
A bit about fonts: all fonts for working with tengine and me3 are created by a separate utility “Bitmap font generator”. It was chosen due to its free and easy to learn, located in the "tengine \ tools \ BMFont" folder. More information about the utility is described on the website www.angelcode.com/products/bmfont , but in short, creating a font consists of several steps:
Create a text message “The game is over”: “Project-> Text Editor”, switch to the tab “LNG_ENG”, click “Create”. We call this text “TXT_GAMEOVER”, set the desired font, write the text “GAME OVER”, and see how the text will look in the visualizer. Here, in the editor, you can set the alignment, set the color and size of the canvas for the current message. Close the text editor window, switch to the “LNG_RUS” tab, see that there is no text yet, click “Edit”, write “THE GAME IS FINISHED”. Thus, we localized the message “TXT_GAMEOVER” in two languages.
Now create a text object on the map. Go to the "System" tab of the object palette, put the TEXTBOX object on the map. This will be the text box for the static text TXT_GAMEOVER. We go into the properties of this object, select "Static text", call it TXTBOX_GAMEOVER, click the "..." button, select the desired text and click "Apply." An object inherits the color and dimensions of the canvas of a text message, but it can be changed individually for each object with the proposed settings.
Create another text object for fps output. We go into its properties, give it the name TXTBOX_FPS, set the “dynamic text” item, set “lines” to 1, “letters per line” - 10. Set the font to “system”, then set the background color and dimensions of the area displayed for the tex: 64x18
You can change the current language in "View-> Current language".
We created everything we need in the game. It's time to generate maps and constants for tengine. For starters, in “Project-> Map Information” you can see on each map what resources are used and in what quantity. You can also find warnings about potential problems here. After that, you need to generate a * .h file with constants. To do this, run “Project-> Variable List” and save the constants in the “game” folder as “constants.h”. After that, run “File-> Save Map (s)” and specify the folder “assets \ data”. Now everything is ready to work with tengine, it remains only to convert resources.
Create an empty file “make_res_bmp.bat” in the root directory of our project with the following contents:
for %% i in (rawres \ *. Png) do .. \ .. \ tools \ bmpcvtr.exe %% i -5551 -2n -oassets / data
copy rawres \ arial_28.fnt assets \ data \
copy rawres \ system.fnt assets \ data \
copy rawres \ *. wav assets \ data \
pause
We will convert all * .png files to r5g5b5a1 format, automatically set all sizes to textures, multiples of 2 ^ n and copy them to the “assets / data” folder, then copy the font and sound files to the same folder. Please note that in the 32bpp resource (arial_28_0.png), when converting to 5551 format, additional data was created with information about the alpha channel, so even with 5551 format translucency is not lost. You can find out more about the parameters of the “bmpcvtr.exe” utility by running it without input parameters. Run the file "make_res_bmp.bat".
Now it remains only to write the logic of the game and compile the project. See source, more information is in “tengine \ src \ tengine \ manual”
All sources of this article are in the tengine repository tengine / samples / space_invaders
Ready-made game binaries space_invaders_demo1.zip
This article is a tutorial on creating a small game. The need for it is obvious: ideologically, creating something in tengine without a level editor (MapEditor3, hereinafter me3) is virtually impossible. It is with the help of it that resources are attached to the objects of the game, files with identifier constants are generated, a scene, sound schemes, etc. are created. And most importantly, me3 generates ready-made binary level files necessary for the tengine logic to work: a file with general data (o-file), data files for each level (l [0..n] files) and files with text data ( t [0..n] files)
Project folder structure:
First, create the space_invaders folder and the folder structure inside it:
- _win32
This folder contains the project files for MS VS - assets
This folder contains the resources prepared for tengine: graphic resources converted by the bmpcvtr.exe utility, me3 data generated and sound (* .wav) files - game
This folder contains the source code of our game - mapeditor
This folder contains the me3 project file. For convenience, while creating a game, the MapEditor3.exe file from "tengine \ tools \ editor" is transferred to this folder - rawres
This folder contains non-converted graphic resources (* .bmp or * .png), sounds, font files, etc.
Getting started with me3:
After running me3, you should configure the paths for working with resources: “File-> Configure paths” and set the path to the “rawres” folder. Then go to “File-> Editor Settings” and set the global settings: type of graphic resources. In the current version of me3, it is possible to work only with bmp or png formats. If bpp <32, the color 0xff00ff is considered transparent, if bpp == 32, the alpha channel is responsible for transparency. Set the resource type to png.
After setting the global settings, you can start creating the scene: “File-> New Project”. Now create the first scene (map): "Project-> Create Map". A window appears with the settings of the new card:
- Screen sizes (in units of map fragments)
Here we adjust the screen sizes. This value is abstract: for the scroller, the screen size does not play a big role, but for single-screen games this is an important parameter. The idea to divide the card into the number of screens was introduced after the request of the designer, it was easier for him to navigate, creating areas of the game world. The screens in the editor are separated by a grid, but you can turn it off ("View-> Grid"). The default map fragment is 8x8 pixels. We set the height to 38 and the width to 50, let our game screen be 800x600. - Map dimensions (in screens)
The game is planned for us on one screen, but I want to show the scrolling functionality of the map for demonstration, the background stars will move, so we set the map: 2 screens in height and one in width. - Number of zones
This setting is used for large cards in which game zones can be turned on or off. What is this I described in the tengine documentation. Our zones will not be used, or rather there will be only one zone.
Level 0 has been created, but I want to dwell on one important point. While the map is empty, we need to think about whether we need such small fragments of the map (8x8), with such a large screen. Probably no. Therefore, we simplify the work of the render and increase their size, thereby reducing their number. To do this, go to the “Background of the Game-> Set Background Elements” menu, set the new width and height of the fragment to 32 pixels, put a checkmark on “Save map size ...” and click “Apply” (I agree, it’s a bit uncomfortable and not intuitive). You can check whether everything is normal with the dimensions by looking at the map settings: "Project-> Map Settings".
A bit more information about maps (scenes): tengine can load several maps and draw them simultaneously (one on top of the second) onto the specified render plane. Loaded maps in tengine are called layers. Up to 4 independent rendering planes are supported architecturally (each platform has its own implementation of a rendering plane). A theoretically infinite number of logical layers can be attached to one rendering plane, but only one of them can be the primary layer and can draw background tiles, have objects with loaded animation, play musical circuits (calls to the described functions in non-basic layers are either ignored, or give an assert error). In addition to these features, logical layers do not intersect with each other in logic. An example of using multiple layers:
Work with background
First, create a background. To do this, go to the background mode: press F2 (or the icon on the panel with the background image). A palette of background objects appears. You can associate empty palette cells with graphics in several ways: element-by-element (move the cursor over the desired element and press "Enter" or double-click the mouse) or the function "cut the finished picture". We will use an easier way: place the cursor on any element of the palette, which will be the first element of the cut picture, select layer 0 of the mixer (Active layer) and click the scissors icon. In the menu that appears, select the desired picture and click "Apply." As a result, we see a group of cells associated with a graphic resource.
A bit about the layers of the mixer. The background can consist of many layers, for this you need to set the desired number of layers in the background settings: "Game Background-> Set Background Elements". Layers are drawn in ascending order, or, in other words: layer 1 overlaps layer 0. Thus, more interesting tile map combinations can be achieved. The Active Layer: All setting draws all layers, showing how they will be drawn on the map.
So, the palette of background objects is ready. They are transferred to the map very simply: select the desired area of objects with the mouse, copy (ctrl + c), put the cursor in the right place on the map and paste (ctrl + v). Moreover, the copy-paste operation works on the palette itself, you can copy and paste objects anywhere in the palette, you can copy and paste background tiles anywhere on the map. There is another useful function to “multiply” (or “bridge”): copy a certain area of the background objects, select another area of the map (or the entire map ctlr + a) and press ctrl + alt + v, as a result - the entire selected area will be filled with repeating fragment of the copied area.
A bit of additional information about background elements: You can set some properties for the background object of the palette. To do this, create types of background properties in the background properties manager (menu "Game Background-> Types of Background Properties"). In the properties, you can set the logical "passability" of the elements, as well as assign a certain additional digital parameter that can be used in game logic. After creating property types, in the palette of background objects, you can assign properties by pressing “Enter” or double-click on the selected object and select the desired type in the window that appears (the “Fragment Type” drop-down list). From now on, all tiles of a map of this type will have the specified properties (checked by pressing ctrl + p on the selected tile under the mouse cursor).
The only condition for all these manipulations: the background mode must be active (the "Background mode" icon in the "pressed" state on the toolbar).
Create a sound scheme
In order for sounds to appear in the game, you need to create a sound scheme. It has already been described above that sound schemes should be created only on cards that will become the main layers. It should also be noted that sound schemes belong to the cards, and not to the game as a whole: each level requires its own sound scheme, if you plan one set of sounds for the whole game - copy and paste one sound scheme between all the cards that will be the levels of the game.
First, switch to the object mode: press F1 (or the icon on the panel with the image of objects). In the lower window of the object palette, switch to the "System" tab, grab the "SOUND SCHEME" object and drop it anywhere on the map. Then we go into the properties of the object on the map (ctrl + p or use the right mouse button to call the context menu of the object and select "Properties"). In the window that appears, add sound files, give them identifier names and set them to SFX (effect) or BGM (background music) parameters.
Creation of game objects
Before creating game objects, you need to create a list of animation types and states. First, run the animation type manager ("Project-> Animation Types") and add two types that should be enough for our small game: "ANIM_ACTIVE" and "ANIM_DAMAGED". Now create state types of objects. We start the state type manager ("Project-> States") and add two states: "STATE_ACTIVE" (to which we tie the animation "ANIM_ACTIVE") and "STATE_DAMAGED" (we tie the animation "ANIM_DAMAGED").
A bit of additional information about states: all the logic of game objects is wrapped around states. It is the states that give the object a logical (logical, since the names “up”, “down”, “right” and “left” are introduced only to dereference the four options of directions) the direction of movement, especially when the object is attached to the path nodes, and also set the name animation that you need to play now.
The second most important parameters after states for an object are properties. They are created in the property manager as a template ("Project-> property template"). We add two important properties: “PRP_ENABLE” and “PRP_SPEED”. Properties of an object can be invented as many as you want, but only tengine responds to these two with internal logic. If “PRP_ENABLE” does not equal 1, the object is not drawn and does not participate in the logic of the game process. The "PRP_SPEED" property sets the speed of moving along the path nodes. If these properties are not created, it is considered that "PRP_ENABLE" == 1, "PRP_SPEED" == 0.
We will also create one event, we will need it, to determine the end of the animation of the death of a space alien, in order to know the moment when you can remove it from the scene. To do this, run the event manager ("Project-> Event Types") and create the event type "EVENT_END_ANIM_DAMAGE_INVADER".
It is important to know: you can add or remove types of animation, states, events or properties at any time at any stage of project development.
Now you can create our first type of game object. First, switch to the object mode: press F1 (or the icon on the panel with the image of objects). In the lower window of the object palette, switch to any tab “General” (you can rename it). Right-click in the window to call up the context menu and select the "Add Object" item. Let the first object be a space alien.
The window for creating a game object consists of two main tabs: General and Animation Editor.
The General tab contains the settings:
- Entity name input field
- Will the object be a decoration. If so, what type: foreground (always drawn in front of the game objects) or background (always drawn behind the game objects). The scenery has no properties and does not participate in the game logic.
- Whether to use graphics for this object. Sometimes an object is needed only for some logic of the game process (for example, only for the pivot area) and does not need a graphic display
- Whether to ignore the graphic resources used by the object if there is not a single instance of this type of objects on the map. By default, when generating map data, optimization is enabled, which adds only the resources of those objects whose instances are on the map to the list of downloaded resources. This option allows you to disable optimization for a specific group of objects.
- Editing the default property values of objects of this type. Each instance of an object of this type, when installed on a card, receives the values set in this template. Important: changing the default values of properties does not affect the properties of instance objects of this type that are already at stake; for the forced change of values there is additional functionality in the drop-down list of the context menu of the object palette.
- The default state sets the state that is set to the instance of the object that is on the card.
Let's name the object SPACE_INVADER, set its default state to STATE_ACTIVE and go to the second tab, where we can create the animation.
Animation Editor Tab The very first thing to do is to select the desired animation name from the list and create the first frame. Select the animation "ANIM_ACTIVE", go down just below the animation selection field to the frame window, right-click on the context menu and select the "Add empty frame" item. We created the first frame of animation. Now you need to cut the graphic elements for the graphic component of the frame. To the right of the empty frame we see an auxiliary window. We make sure that in this window the active tab “Graphics” contains the active sub-tab “Standard”. Right-click on the still empty window-palette of graphic elements, call the context menu and select "Edit". A window for editing the graphic image of the object has appeared. Here graphic elements are created (cut out), from which animation frames will be created. First, create a new group into which we will collect the elements of aliens. To do this, right-click on the window of groups of graphic elements (the leftmost window with the inscription "General") call the context menu and select "Create Group". We call the group "INVADERS". Now we make this group active (left mouse button) and right-click in the group to call the context menu in which we select “Add” (or press the Insert button). An empty cell appeared in the group. We make it active. Go to the "Source File" window and select the "characters.png" file. After that, in the picture that appears, select the image area of the alien of the first phase of the animation (for convenience, use the arrow keys to move the selected area, as well as the combination of ctlr + arrows to resize the selected area, also use the sliders to zoom in). Add another frame to the INVADERS group and select the image area of the alien of the second phase of the animation. Click "Apply." We are back in the animation editor. Now is the time to create the alien animation frames. Select the desired alien image in the palette of graphic elements, put the mouse on the frame field, call the context menu with the right button and select the "Set" item. By analogy with the first frame, add another empty frame and set the second frame of the alien. Let's see what we got. We press the “Start” of the player and see how our first animation works. Are the frames changing too fast? Set the time for each frame. Click Stop. We switch with the mouse in the frame window for each frame and set in the "Frame Time" field of the "Current Frame" group to 200 (ms). Check again. Now the animation works as it should.
It's time to add a bit of a logical component to the frame: collision area (collision zone). It will be needed to determine the zone of a bullet entering an alien. It is important to know that in tengine an object’s graph does not take part in the logic of computing collisions or “visibility” zones. Two logical parameters have been introduced for these needs (these concepts are conditional, since tengine does not operate with these zones in any way):
- The working area of the facility. It is assumed that the "working zone of the object" will serve in the game process as a collision zone, the dimensions of this area are set in each frame of the animation separately.
- Object visibility zone. It is assumed that the “object visibility zone” takes part in the logic of object interactions or is the size of the animation frame. The size of this zone is the same for all frames of the animation.
There is another way to determine the collision area: using an additional “collision” raster map. For more information about working with this functionality, see the documentation (prHasAlphaCollideMap () and prGetAlphaCollideMapValue () functions).
Select the first frame of the animation. Switch the tab of the auxiliary window from “Graphics” to “Logic”. For convenience, the image graphics disappears. In this case, we need to see the image in order to outline it with a zone-zone. We put a tick on the option “Graphics and Logic” (the lower part of the animation creation window). In the auxiliary window we put a check mark on the properties "workspace of the object", thereby activating its editing. We enter the parameters W = 40, H = 30, then grab the resulting rectangle with the mouse and place it so that the “alien” is inside it (for the convenience of moving objects, you can use ctrl + arrows). Copy the selected area (if the selection is gone, click the mouse on the edge of the rectangle, thereby selecting it) using the keyboard shortcut ctrl + c, switch to the second frame and insert (ctrl + v) the zone zone for this frame as well. Thus, we get an animation of a space alien with a kolizh zone in each frame. One thing remains: create an icon for the object selection palette. We select the first frame, call the context menu of this frame and select the "Create Icon" option. Now that’s it, you can click “Apply”. Our first object appeared in the object palette.
We build on an alien map. To do this, grab the object with the mouse and drag it onto the map. Since we will have many aliens, you can use the "clone" function of the context menu of the object on the map.
To simplify working with objects, the editor has an object manager (ctrl + o). It is more convenient to monitor the number of objects, change their position in the rendering list, properties, etc.
By analogy, we create an animation of death for the alien ("ANIM_DAMAGED"). The only thing on the last frame of the animation in the "Event" field is to select "EVENT_END_ANIM_DAMAGE_INVADER" from the drop-down list. We also create objects with the TURRET cannon, the BASE base and the MISSILE rocket. We put them on the card. Moreover, we put several missiles on the card, set them properties PRP_ENABLE = 0, we need them for the pool.
A bit about pools: the tengine ideology forbids the generation of objects. Therefore, all the objects that you plan to “create” during the game must be in sufficient quantity on the map and have the property PRP_ENABLE = 0. Additional logic is also written in the game logic to use this pool.
Text fields and font creation
Some additional information about working with texts in me3:
- Support up to 8 languages. You can set how many languages will be used in the application in the settings tab “File-> Editor Settings-> Text Editor tab”. Here you can rename languages ("LNG_0..n") into more convenient names and check off which languages are participating in the current project. Width and height of the displayed area - default text window size
- Font support (font creation will be discussed a bit later)
- Separate editor subsystem for creating text messages
Text fields are dynamic and static. The text of dynamic fields can be changed from the application code using special functions. We do not change the text of static fields; an identifier is assigned to it for a string that automatically changes its value depending on the selected current language.
Create another map. We will use it to display text messages. This will be the logical layer of the game menu. “Project-> Create a map”, put the dimensions 25x19 (800x608), the dimensions of the map - 1x1 screen. Let two languages be available in our game: Russian and English. Go to “File-> Editor Settings”, select the “Text Editor” tab. We click on the "Edit" button under the window of available languages and in the window that appears, change the language "DEFAULT" to "LNG_ENG", "LNG_1" to "LNG_RUS". Then I found an annoying editor error, initially in the manager window that appears there is no choice of languages. You need to enter any letter in the search box and delete it, only then you can see the list. This will be fixed in the next version of me3. After that, click “Apply” and check off our languages “LNG_ENG” and “LNG_RUS”. Click Apply again. Now you need to check if the project has fonts available for use. If there are no files with the extension * .fnt in the “rawres” folder, you need to create a font.
A bit about fonts: all fonts for working with tengine and me3 are created by a separate utility “Bitmap font generator”. It was chosen due to its free and easy to learn, located in the "tengine \ tools \ BMFont" folder. More information about the utility is described on the website www.angelcode.com/products/bmfont , but in short, creating a font consists of several steps:
- “Options-> Font settings”, select the desired font, define the character set: ANSI or Unicode, set the size. Do not change any more values in the settings window.
- In the main window of the application, it is necessary to mark with the mouse the characters that will participate in the final font (do not forget the "space" character). If Unicode was selected in the settings, use the switch between the character sets in the right window. Remember, the larger the symbol - the larger the final atlas with bitmap images of the symbols.
- Go to the settings and set the size of the generated texture, bit, preset alpha channel and data type of fnt format. For greater optimization, the “Spacing” values can be set to 0, 0. The texture size should be large enough: if the characters do not fit into one texture, several of them are generated. In turn, tengine and me3 can only work with one texture per font, so you need to make sure that all the characters fit in the same texture, if more than one texture is created during generation, you need to increase the size. You can check whether the characters fit into the texture using "Options-> Visualize". The bit depth of the color depth can be used both 8 and 32. In the case of 8 bits, you will need to fill in all the space in any graphics editor, which should be a transparent color 0xff00ff. In case of 32 bits, you need to select the “Outlined text with alpha” setting in “Presets”. The data format needs to be set only in "Binary". The texture type is png (note: if the “BMP” graphic resource format is selected in the me3 settings, you should convert the texture to bmp format (32bpp) with any graphic converter)
- Font generation occurs by calling "Options-> Save bitmap font as ..". After generation, two files should appear in the specified folder: name.fnt and name.png.
- Optionally, to reduce the size of the graphic resource, you can open the generated texture in any graphic editor and remove the empty space.
Create a text message “The game is over”: “Project-> Text Editor”, switch to the tab “LNG_ENG”, click “Create”. We call this text “TXT_GAMEOVER”, set the desired font, write the text “GAME OVER”, and see how the text will look in the visualizer. Here, in the editor, you can set the alignment, set the color and size of the canvas for the current message. Close the text editor window, switch to the “LNG_RUS” tab, see that there is no text yet, click “Edit”, write “THE GAME IS FINISHED”. Thus, we localized the message “TXT_GAMEOVER” in two languages.
Now create a text object on the map. Go to the "System" tab of the object palette, put the TEXTBOX object on the map. This will be the text box for the static text TXT_GAMEOVER. We go into the properties of this object, select "Static text", call it TXTBOX_GAMEOVER, click the "..." button, select the desired text and click "Apply." An object inherits the color and dimensions of the canvas of a text message, but it can be changed individually for each object with the proposed settings.
Create another text object for fps output. We go into its properties, give it the name TXTBOX_FPS, set the “dynamic text” item, set “lines” to 1, “letters per line” - 10. Set the font to “system”, then set the background color and dimensions of the area displayed for the tex: 64x18
You can change the current language in "View-> Current language".
Game map generation and constants for use in tengine
We created everything we need in the game. It's time to generate maps and constants for tengine. For starters, in “Project-> Map Information” you can see on each map what resources are used and in what quantity. You can also find warnings about potential problems here. After that, you need to generate a * .h file with constants. To do this, run “Project-> Variable List” and save the constants in the “game” folder as “constants.h”. After that, run “File-> Save Map (s)” and specify the folder “assets \ data”. Now everything is ready to work with tengine, it remains only to convert resources.
Resource Conversion
Create an empty file “make_res_bmp.bat” in the root directory of our project with the following contents:
for %% i in (rawres \ *. Png) do .. \ .. \ tools \ bmpcvtr.exe %% i -5551 -2n -oassets / data
copy rawres \ arial_28.fnt assets \ data \
copy rawres \ system.fnt assets \ data \
copy rawres \ *. wav assets \ data \
pause
We will convert all * .png files to r5g5b5a1 format, automatically set all sizes to textures, multiples of 2 ^ n and copy them to the “assets / data” folder, then copy the font and sound files to the same folder. Please note that in the 32bpp resource (arial_28_0.png), when converting to 5551 format, additional data was created with information about the alpha channel, so even with 5551 format translucency is not lost. You can find out more about the parameters of the “bmpcvtr.exe” utility by running it without input parameters. Run the file "make_res_bmp.bat".
Game Code Writing
Now it remains only to write the logic of the game and compile the project. See source, more information is in “tengine \ src \ tengine \ manual”
All sources of this article are in the tengine repository tengine / samples / space_invaders
Ready-made game binaries space_invaders_demo1.zip