I wrote a Tutorial about Editor-Programming today for a friend, and thought that I could post it to the forums when it's finished. Because I don't know what to add... I post it here now.
It's about programming a 2D-Game-Editor, but also contains some information on 3D-Editors and other stuff like camera-systems and collision.
If you want to read it, the best would be to download the rar-file including 9 word-documents and also the 3 sourcecodes I am talking about through the tutorial.
Apart from that there's not much code, some pseudo-code, and in Chapter 3 also a basic editor-framework-code.
I hope that it helps someone... if you have any questions, suggestions, criticism or whatever please tell me.
Download can be found here:
http://www.yourfilehost.com/media.php?cat=other&file=DBP_Editor_Tutorial.rar
At first the Tutorial-Structure:
Quote: "
1. Getting Started
2. Concept
3. The Basics
4. Editor-Types
5. General Techniques
6. Interface
7. Formats
8. Finally
9. Sourcecodes
"
And for the people who don't want to download it, here the whole tutorial:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Editor-Programming-Tutorial
1_Getting Started
This tutorial is supposed to help you designing and programming an editor for any of your games. I started writing this tutorial, because Game King from the forums asked me to help him with creating an editor for his game Vaelore. There seemed to miss most of the basic ideas he needed to make an editor, so I decided to write this tutorial.
At first I have to apologize for my language, I am from Germany, so English is not my native language, and as you may have already noticed I have some problems with opressing my thougths…
However, back to topic.
Editor-Programming-Tutorial
2_The Concept
As in all kinds of games you also have to make a detailled plan of how you editor will look.
So the first thing to do is taking a sheet of paper (or a text-file) and a pen (or a keyboard), and writing down your ideas. I prefer noting the main-features of the editor, and ignoring things like the GUI.
So if you are making a Jump and Run-game, like Game King does, the first small concept could look like this:
Concept for Vaelore-Editor
Features:
-Different Platforms
-Placement and Creation of characters
-Trigger- and Event-Zones
-Changing of global variables like Level-Gravity, Weather, Ambient-Light
-Included Platform- and Item-Designer
-Placement of items
-Script-Editor
…
That, in fact, is not really detailled, but covers the most important features. Now you should improve the list:
…
Different Platforms
- Variable Attributes: Maximum Speed, Jump-Height
- Image-File of used Sprite
- Collision-Size
- Angle
…
You can go even more into detail and also plan, how the features will be integrated in the GUI, which will be handled internal, which will be set by default and so on.
The aim is to avoid the situation, in which you can’t continue programming because you have to think about a feature and how you want to realize it. Such situations are really unmotivating, because you can’t program and have to work on your concept again. There might also appear some problems you didn’t know before, and that’s why you should write the whole concept before you start coding.
So in the end your concept should contain all the main-features you want to include into the editor, the way they will work and possibly how the GUI will connect the user with this feature.
When this concept is finished you can draw some sketches of the interface, you don’t even need every button or checkbox, but at least how your work-window will be divided. Possibly you want to have a menu-bar at the top, a toolbar below, an info-frame at the left side and a movable window for different operations. Or you use tabs to separate the different main-features (like Map-Building, Character-Design, Item-Design etc. in this case), that’s all up to you.
This is also a very basic sketch because it just demonstrates the structure, and nothing of the GUI itself. Normally you would include more information into the sketch, e.g. what items the menubar has, what will be in the toolbar, what information will be shown in the info-frame etc. To be honest I am just to lazy to make a more detailled plan for you, because I think it’s kind of obvious how to do that.
Now you have a detailled concept of the editor and it’s GUI, and you are ready for coding.
Editor-Programming-Tutorial
3_The Basics
Now you have to think about how you will program the editor. I use in most cases the tab-technique, so I use one main Tab- or Mode-Variable defining which Mode is actually active:
Global Editor_Mode as integer
Now I define some constants for the different editor-modes:
#constant MODE_WORLD = 0
#constant MODE_CHAR = 1
#constant MODE_PLATFORM = 2
#constant MODE_ITEM = 3
#constant MODE_COUNT = 3
This constants can be used later on to check which mode is currently active. The last constant “Mode_Count” defines how much modes are set up, for the case that you switch between modes using keys (At first I always define on scancode which changes the mode, because I never include the GUI at the beginning).
So with this simple technique you can use one Main-Loop for all parts of your editor. This main-loop handles your Mode-Management (Changing between Editor-Modes and the change’s consequences (for instance some parts of your GUI are diables and other enabled)) and the modes.
Managing the active mode is quite easy and can be done with a simple select-case-statement in the mainloop:
Select Editor_Mode
Case MODE_WORLD
UpdateWorldBuilding()
Endcase
Case MODE_CHAR
UpdateCharacterDesign()
Endcase
Case MODE_PLATFORM
UpdatePlatformDesign()
Endcase
Case MODE_ITEM
UpdateItemDesign()
Endcase
Endselect
As you can see you will need functions for the different modes, that’s at least how I do it. You could also use labels if you want, but NEVER write all this operations directly into the select-codeblock, that would result in a crazy unreadable “code”.
Just in case – if your editor doesn’t have such different modes, and can e.g. just load sprites (or objects) and place them into a level, you wouldn’t need the part above. But even then you would maybe need it later, because it’s possible to realize very useful things like Finite State Machines with such simple methods.
OK, fine, now we made a plan how to realize the Editor-Modes, but what next? One possibility would be settings up global Variables. At least that’s what I would do now.
We can divide the globals into 2 main-sections: Editor and Level. Some variables are just needed in the editor, for instance this Editor_Mode, or the actual mouse-Position etc. so all variables you won’t save with the map later. The other section, Level-variables, would include things like Gravity, Map-Size, Number of Platforms/Characters/Items and so on.
For an easier-to-read code we’ll give each variable a prefix, defining if it’s an Editor- or a Level-Variable.
Rem Editor-Variables
Global Editor_Mode as integer
Global Editor_MouseX as integer
Global Editor_MouseY as integer
Rem Level-Variables
Global Level_Gravity as float = 9.81
Global Level_SizeX as integer = 0
Global Level_SizeY as integer = 0
Global Level_PlatformCount as integer = 0
That’s just a part of the global-declarations, but I have to make a cut here: The declaration of the Platfor-Count-Variable can in fact be made in a function like SetupPlatforms(), that’s much easier to use when you have to do multiple operations to set the platforms up.
This function would also include the creation of the platform-array, and could look like this:
Function SetupPlatforms()
Global Level_PlaformCount as integer = 0
Dim Platform(0) as PlatformType
Endfunction
For now the function includes just 2 lines, but the setup-functions will grow later in the project. Such functions are created for everything working this way, so also for Characters, Items, Zones, Sprites, Dynamic Objects and whatever will be integrated into your game.
By the way you don’t even need the Level_-Prefix here, because you could also use a Platform_-Prefix, so you divided your variables into the categories “Editor”, “Level”, “Platform”, “Character”, “Item” etc., that’s how I do it. (Of course you also can write “Edit” instead of editor or “Char” instead of “Character”, in fact you could even just take the first letter, but that might be confusing sometimes)
One more advice: Write everything into functions. Your mainloop should just include Function-Calls, apart from the Mode-Managing-Part from the top, and maybe a “sync” and Debug-Operations. Normally I have functions for all operations like “UpdateSelection”, “RepositionPlatform”, “AddPlatform”, “SaveMap” (More about saving in one of the next chapters) etc. So in the end your code will be very structured, and every single procedure can be selected in your function-list (if your editor supports such a list, the default DBP-IDE has one). Also debugging gets much easier, and if you change something you can just change one function instead of searching your whole code for the operation you want to change. In my opinion functions are better then labels, because you can call them with parameters, which makes the whole code easier to understand. ( “AddPlatform(mousex(),mousey())”, where the parameters are the X- and Y-Position, is easier to understand than “Xpos=mousex() : Ypos=mousey() : gosub AddPlatform”, and it’s also less code)
Maybe you noticed it, we used the type “PlatformType” when creating the platform-array in SetupPlatforms():
Dim Platform(0) as PlatformType
So we will create a simple type before finishing this chapter.
We will ignore the concept for now to avoid complications and try to make everything as simple as possible. So the type will include some basic values: Position and Sprite-ID. Normally we would also include values for collision-behaviour, maybe something about animation etc.
So the type looks like this:
type PlatformType
PosX as integer
PosY as integer
SpriteID as integer
Endtype
The used values are all integers, in fact SpriteID could also be a word (unsigned 2-byte value from 0 to 65535) because it covers the possible range of Sprite-IDs and just needs half as much memory, but we will ignore this fact for now, because we should first concentrate on other things than memory-management.
Now we are ready for the first working sourcecode. It incluces all things we’ve done yet and some lines more to make the program work correctly.
Copy it into the DBP-Editor and run it to see the result.
rem At first the standard-operations, even if I didn't mention them. ;)
rem Because it's an editor I use the window mode here
set display mode 800,600,32
set window on
sync on
sync rate 0
randomize timer()
rem Some of the globals we decided to define
Rem Editor-Variables
Global Editor_Mode as integer
Global Editor_MouseX as integer
Global Editor_MouseY as integer
Rem Level-Variables
Global Level_Gravity as float = 9.81
Global Level_SizeX as integer = 0
Global Level_SizeY as integer = 0
rem Setting up the "Objects"
SetupPlatforms()
`SetupChars()
`SetupItems()
`SetupZones()
`Setup anything else here
rem Definition of the Editor-Mode-Constants
#constant MODE_WORLD = 0
#constant MODE_CHAR = 1
#constant MODE_PLATFORM = 2
#constant MODE_ITEM = 3
#constant MODE_COUNT = 3
rem =========================================================================
rem ==========================================================================
rem ============================ MAIN-LOOP ===================================)
rem ==========================================================================/
rem =========================================================================/
DO
rem Clear screen
cls
rem Mode-Selection here, just temporary, not very professional or user-friendly ;)
ud = upkey()-downkey()
if ud<>0
rem Change the mode
inc Editor_Mode, ud
rem Check if the mode has an undefined value
if Editor_Mode < 0 then Editor_Mode = MODE_COUNT else if Editor_Mode > MODE_COUNT then Editor_Mode = 0
rem Wait 200ms
t = timer()
repeat : until timer()-t>200 or scancode()=0
endif
rem Show some Debug-Information
print "<=== Demonstration of Edit-Mode-Management, Editor-Tutorial Chapter 3 ===>"
print
print "FPS: ", screen fps()
print "Press Up or Downkey to change the Edit-Mode"
print
print "Edit-Mode: ", Editor_Mode
rem The actions, which are executed depending on the Editor-Mode
Select Editor_Mode
rem World Building
Case MODE_WORLD
UpdateWorldBuilding()
Endcase
rem Character-Design
Case MODE_CHAR
UpdateCharacterDesign()
Endcase
rem Platform-Design
Case MODE_PLATFORM
UpdatePlatformDesign()
Endcase
rem Item-Design
Case MODE_ITEM
UpdateItemDesign()
Endcase
Endselect
rem Setup screen
sync
LOOP
rem =========================================================================
rem ==========================================================================
rem ============================ FUNCTIONS ====================================)
rem ==========================================================================/
rem =========================================================================/
function UpdateWorldBuilding()
print "You are currently in World-Building-Mode"
endfunction
function UpdateCharacterDesign()
print "Here you can design your characters"
endfunction
function UpdatePlatformDesign()
print "This Mode is for platform-design"
endfunction
function UpdateItemDesign()
print "Items can be created here"
endfunction
Function SetupPlatforms()
Global Level_PlaformCount as integer = 0
Dim Platform(0) as PlatformType
Endfunction
rem =========================================================================
rem ==========================================================================
rem =============================== TYPES =====================================)
rem ==========================================================================/
rem =========================================================================/
type PlatformType
PosX as integer
PosY as integer
SpriteID as integer
Endtype
Editor-Programming-Tutorial
4_Editor Types
The aspects I mentioned in the last chapters might be useful for all kinds of editor. But now we have to decide what kind of editor we want to make. That is one of the most important aspects of the concept, because nearly all other aspects are depending on the editor-type, so you should normally already know how your editor will look.
There are some main-types of editors:
- Landscape-Editor
- Object-Placement
- Tilebased Map-Building
- Object-Designer
- Text-Editor
- Probably much more I forgot
Lets go more into detail.
Landscape-Editors are 3D-Editors in which you can build your levels by building a heightmap and apply textures, such editors can be used for nearly all games using landscapes, because the normally export the heightmaps in common formats like BMP, JPG or PNG-Greyscale-Images. But that’s not really what we are doing in our small example.
Object-Placement is an important feature for most specialized editors, and sometimes even for more general ones. Our Editor should be able to place platforms, characters, items etc., and they are all kinds of “objects”. So that’s one aspect we need in our editor.
Tilebased Map-Building is a technique used in many old 2D RPGs. The maps are divided into a grid of constant size, and each tile of this grid has an own texture and in most cases settings defining if you e.g. can walk over it, if it damages units or if one can build a building there. The problem of tilebased maps is, that they are rather unnatural because of the grid.
Object-Designers are Editors, which can create/edit “objects” (This can be real 3D-Objects or Sprites or whatever) by defining general values like Object/Texture/Image-File, Hitpoints, Speed, Physics, Shaders and so on. Our editor uses object-designers for Platforms, Units and Items.
Text-Editors are what they are. Editors to edit texts. So MS Word is a text-editor and the Dark Basic IDE is a text-editor. If you need scripts in your game/editor you should also have an editor for this scripts, supporting things like syntax-highlightning and maybe saving into encoded formats. The concept from Chapter 02 included scripts, but we will maybe talk about that later. So at first we can forget about Text-Editors.
OK, that are the differend editor-types. Our editor we started in the last chapter includes mainly 2 of them: Object-Placement and Object-Design. The game it will be good for should be a 2D Sidescrolling jump-and-run like Vaelore, so we don’t need landscapes, and tilebased maps are not good to use because they are better for games with top-down-view, and definetly not for side-view.
Even if our editor doesn’t support the other editor-types, maybe some hints how to make them.
If you want to make an own editor, one not being just for Object-Design and Placement, you should read the rest of the chapter. Otherwise you can simply jump to Chapter 05.
Landscape-Editors
I already wrote, that they are mainly 3D-editors, because 2D-Games normally don’t need landscapes (although 2D-Matrices are very cool!).
So they are 3D and can work in different ways.
1. They can use heightmaps
2. They can be objects
So where’s the difference? Right, heightmaps aren’t very flexible, and objects are. But on the other hand heightmaps are much easier to manage. In heightmaps each vertex has a predefined X- and Z-Position, so it’s not possible to create caves or cliff-overhangs. But that has the advantages, that lightmapping-calculations are very easy to realize, and that the collision-system of the game will be easier, because it doesn’t have to check the collision in Y-Direction (At least in case you don’t have bridges etc. on your maps).
Realtime Heightmap-Editing can be realized in different ways. You can edit the greyscale-image, which runs fast if you e.g. use memblocks, or you try to make it in 3D, by using a matrix (which is, compared to the other methods, rather slow) or realtime vertex-manipulation of a heightmap-object (which is the most complicated version).
Editing an object is also rather complicated, because you don’t really have alternatives, and so you have to use the vertex-manipulation-method.
Another aspect is saving the landscape: Normal heightmaps can simply be saved as Bitmap, but objects have to be saved as X-File (or any other 3D-Object-File) or in your own format.
All in all such editors were bad if they just were able to create heightmaps or objects. They need more features like texturing (If possible 3D direct-paint) and lightmapping. But I let figure out yourself how that works, if you are interested.
So, all in all, if I was working on a rather small 2D-Project I would prefer heightmaps, because making an easy-to-use Realtime 3D-Object-Editor is much harder.
Tilebased Maps
Everyone knows games using tilebased maps. In past they were used everywhere, mostly in RPGs or Strategy-Games. For instance Rollercoaster Tycoon uses a pseudo-3D-Tile-System, and as far as I know also games like Diablo 2 do. Maybe also Age of Empires 1 and 2, but all in all I have no clue.
However, tilebased maps are very easy to used compared to other techniques. In fact the whole map is stored in a 2-dimensional-array containing information about each field.
Dim Tile(TilesX,TilesY) as integer
In small games the integer-value of each tile just stores the Image (or Sprite)-ID which is pasted at the tile’s position. If the game is more advanced, the integer-value points into another array, storing the tile-information. This could be realized this way:
Dim TileTemplate(NumberOfTileTemplates) as TileTemplateType
Type TileTemplateType
ImageID as integer
Walkable as boolean
Endtype
This would be a rather easy tile-template-system. Each tile-template gets a pointer to the image-ID and a boolean, defining if units can walk other this tile. Each tile gets a pointer to the template then.
Many people, mainly the ones being new to programming, ask how they can include a scrolling system for their 2D-Games, because it’s very uncomfortable to reposition each sprite one time per loop to the scrolled position.
The way I’m doing it can be used to all kinds of 2D-worlds, so also in tilebased games. Then you don’t create an own sprite for each tile, but one hidden sprite that’s pasted at eachs tile-position (that’s also how the code above is meant to work, just one sprite for each template, and not for each tile). The position can be calculated this way: AbsolutTilePosition-CameraPosition.
So you simply substract 2 Camera-Variables (e.g. X_Scroll and Y_Scroll) from the absolute positions of your tiles (or characters or whatever is pasted) and get your screen-position. That’s extremely uncomplicated and easy to use, more about this technique in a later chapter.
Text Editors
To be honest I don’t know what to say about text editors, apart from that they should support syntax-highlightning and saving/loading of text. Other possible features could be debugging (even if this should be done by a compiler or interpreter normally), an own preprocessor (for things like #constant or #include, in DBP this operations are managed by the compiler, not by the IDE) and maybe Project-Files like in DBP, including general information which are not in the text/code.
I already thought about how to realize syntax-highlightning in past, but had no good idea, so I can’t say you anything about it.
Editor-Programming-Tutorial
5_General Techniques
This part of the tutorial is about different techniques you can always use in such Editors, and maybe also in games.
I talked about a simple Camera-System in the last part of Chapter 04, and that’s one of the aspects I will describe here.
Camera/Scroll System
So, here we go, the camera system.
There are different possibilities, how to make such a system, I prefer my 2D-Camera-System I wrote in summer 07, which can convert Screen- to world- and world- to screen-coordinates, depending on the actual camera (Camera’s can be created, positioned, sized etc. using the functions). So you always have to separate Screen- and World- (or absolute) Coordinates. All kind of calculation (Collision etc.) should use the World-Coordinates, and the Screen-Coordinates are just important for pasing images to screen. In an editor you would have to check, if the mouse clicks on an world-object. In this case you’d have to transform your mouse-screen-position to world-coordinates and check for all objects, if the mouse hit them.
If you don’t want to use such a system, you can also make your own. If there’s no need for features like Camera-Zoom (which is useful in editors though) you can take 2 variables (or a vector2) which represent the Camera-Position (Scroll-Value). The coordinate-transformations are really easy then:
WorldPos = ScreenPos + ScrollPos
ScreenPos = WorldPos – ScrollPos
If your camera is at the world-position (100,50), an object with the world-coordinates (500,500) will be pasted to (400,450), because the camera-value is substracted from the object-position to get the screenposition. If you want to get your mouse-position as worldcoordinates, you’d have to calculate MousePos + ScrollPos, so a Camera at (300,-220) and a mouse at (200,350) would result in a world-position of (500,230).
The system is quite easy, but you always have to know in which direction you have to calculate, which can sometimes be a bit confusing, but all in all is not really a problem.
Collision
Another part of game-development. And one of the harder parts, because you need much maths to calculate collisions, even in 2D.
I don’t know why, but many people think that the Editor should do the collision. That in fact is wrong (as far as I know at least, I had no idea how to let the editor check collisions, and none of the commercial games seems to handle collision with the editor). Collision is always calculated in realtime in your game. Even though it has nothing to do with editors, I will tell you something about it. So if you already know everything about 2D-Collision, you can go to Chapter 06.
There are some different kinds of collision:
- Per-Pixel-Collision
- Box-Collision
- Bounding-Box-Collision
- Polygon-Collision
- Distance-Collision
- And, like always, probably even more
So, that’s it. Five different types of collision for your games. Programming them is partly hard… I never used
per-pixel-collision and have no idea how to implement it, but maybe it’s done somehow with memblocks, but really, don’t ask me.
Box-Collision on the other hand is very easy. I used it for games like Doyle, it’s fast and really very easy to code. All you do is comparing two X- and two Y-Values, e.g. of a character and a platform. If the addition of the X or Y-Distance is lower than the addition of the half X or Y-Sizes, then there’s a collision.
Bounding-Box-Collision (I am not sure if it’s really called like that, but as far as I remember it was “Bounding Boxes” ^^) is basically the same like box-collision, but has some very important differences: You can also used rotated boxes. Normal Box-Collision just allows “static”, unrotated boxes to collide with each other. Bounding boxes use different, more complex calculations. Normally I do it this way: Every time a platform is moved I calculate it’s 4 edge-points. When I check if two platforms (normally I don’t check platform-collisions, but that doesn’t matter here) collide, I check for each of the 4 edges of one platform, if it is in the other platform-box. This can be checked with some 2D-Projections onto the sides of the other bounding box, however, maybe the image below demonstrates it better.
If you use
Polygon-Collision, you define some 2D-Vertices for your objects (e.g. characters) using an own system (Because DBP doesn’t have any 2D-Vertex-Functions). When checking the collision you can use a simple line-collision-algorithm (with a bit of algebra that’s really easy to code), the only problem is, that the other colliding object also has to use a line-collision then, and you probably need to calculate it’s colliding lines first.
Distance-Collision (in 3D Sphere-Collision) is the easiert of them all, and I use it to check Character-Bullet-Collisions, because they don’t need to be very precise. You compare the centered positions of both objects by calculating the squared distance (Normally you don’t use SQRT because it’s rather slow and you just can compare the squared distance-values) and checking, if it’s below a certain other squared distance. In this case both objects collide.
Info: In the drawing above there’s just shown point-object-collision, where the objects collision-type changes. Also the polygon-collision in this case is a 3-vertex-polygon, which uses another algorithm then n-vertex-polygons.
Editor-Programming-Tutorial
6_Interface
Now I will tell you something about interface, even if I don’t know anything about it. I just think this topic should be covered.
Without advertising I want to say that you should use BlueGUI when developing an editor with DBPro. It’s fast, easy and has an acceptable amount of bugs (to be honest I never downloaded an update, so maybe all the bugs I know are fixed…). You can of course code your own GUI, but that’s very time-intensive, runs much slower (at least if you use Sprites or 2D-commands) and normally doesn’t look so professional.
However, your editor’s GUI should be structured and as much as possible self-explaining. Gadget-Overloads make other users directly close the editor again, so if you want others to use your editor (e.g. to create own maps) you should make it easy to use. Also there shouldn’t be no gadgets.
The user must see that there are many features, but if possible not to much at once. The core-features must be usable directly, and not through 5 different menus.
I think you probably already knew all that, so sorry for this waste of time… I won’t say anything more about it.
Editor-Programming-Tutorial
7_Map-Formats
The probably most important feature of an editor was not discussed so far: Saving and loading your creations.
Why would you need an editor, if you wasn’t able to save your progress? Absolutely right, that would be totally senseless. So this chapter is about Saving and Loading maps from external files.
An easy but unprofessional way is to save your game-data with “save array”. I really hate this method and never used it, if it was possible to avoid it, but however, it’s up to you what method you want to use.
One of the problems of this technique is, that you in most cases have to save several arrays. For instance platforms, characters, Items, Zones… and also the Level-Information (Gravity). So you’d need to save an extra array including this level-information, which is really uncomfortable. Also you can’t save UDT (User defined Type)-Arrays, as far as I know.
So, all in all, just forget it!
Making an own format is much more professional, easier for the user, and all in all also easier, in my opinion.
But before I tell you something about the map-formats, here’s something about Versions:
In most of my program I define one constant as Map-Format-Version-ID.
#constant MAP_VERSION_ID = 7
Where ‘7’ in this case stands for the number of changes I made with my Save/Load-Function. The Version is saved into the map-file, and when a map-file is loaded, the program checks, if MAP_VERSION_ID and the saved version-ID are equal. In this case the map is loaded, otherwise it gives the user an errormessage, that the mapfile is saved in an incompatible version. With this technique you avoid errors, which may occur sometimes, where you load an old level of a wrong format (which will result in totally senseless maps…) and by accident save it (Saving my progress is kind of a reflex of me, so that happened kind of often to me), in this case your map would probably be lost and not, or at least not easy, to restore.
So with this constant you just load maps of the right version, to avoid such mistakes.
Another tip: Save all versions of your save/load-functions to another DBA-File, so if anyone ever makes a good map, you can convert it to the actual format, so the map is not lost but can be used again.
OK, now you know how to manage your map-versions, but how can you save your maps to external files?
That’s quite easy, but is also a bit tricky, because your load-function must to exactly the same like the save-function – just the other way round.
Mainly my Map-Files are always structured in 2 parts: The header and the body. The header includes general information about the level, the body contains information about all the single objects (once more: This can be platforms, characters, items etc.).
So here’s a piece of pseudo-code for a save-function:
Open SaveFile$
//Header
Write VersionID
Write Gravity
Write MapSizeX
Write MapSizeY
//Body
Write Platforms
Write Characters
Write Items
Write Rest
Close SaveFile$
The header is just a group of 3 variables at the moment, but this will get more, e.g. the background-image-file etc.
Now let’s have a look at the “Write Platforms”-Procedure. This part could for instance look like this:
Write PlatformCount
ForAllPlatforms {
WritePosition
WriteImageFile
}
That’s how the body-procedures should all look. At first the amount of objects, and then for each object all needed information.
By the way, I normally don’t save an imagefile for each platform, but instead use Platform-Templates, the same way I did it with Tiles some chapters before, so I wouldn’t save the ImageFile, but the pointer to the specific Platform-Template, and in this case I would maybe also save the platform-templates into the file.
So, let’s say the map is saved now. How would you load and build it?
This part often causes problems, because you easily forget changing one function after you changed the other.
But in this case it would be rather simple:
Open LoadFile$
//Header
Read V_ID
If V_ID <> VersionID then return “Incompatible Map-Version”
Read Gravity
Read MapSizeX
Read MapSizeY
//Body
ReadPlatforms
ReadCharacters
ReadItems
ReadRest
Close LoadFile$
Sounds quite easy so far, doesn’t it? This way you can load the map, but how to build it? Let’s have a look at “ReadPlatforms”.
ClearPlatforms
Read P_Count
For Platform = 1 to P_Count {
Read Position
Read ImageFile (or TemplatePointer)
CreatePlatform(Position,ImageFile)
}
So the first thing you do is clearing your array, after that you read all platform-information and add a new platform using your add-platform-function for each. And this way you also do it for characters and items.
And finally you have your own, working mapfile-format. The Load-Function can normally also be used in your game, because of of course also want to load your files there, you just have to be carefull because the editor normally uses other Array-UDTs then the game, but the Load-Function must still stay the same.
Editor-Programming-Tutorial
8_Finally…
Now you know the basics of programming an editor (I hope you learned at least something with this tutorial), and basically you could start one right now.
Let’s put it all together:
Quote: "
1. You need a detailled concept of your editor
2. And a concept of your GUI
3. You have to know what kind of editor you want to make
4. If you use different Modes in your editor, write a small Mode-System like in Chapter 3
5. Use UDT-Arrays to manage your game-objects
6. If you use the same object several times (e.g. for platforms) you should make a Template-Array and give each object a pointer to one of the templates
7. Decide, how you want to manage your 2D-Camera
8. When the main-features of your editor are included start integrating your GUI
9. Write functions to Save/Load your maps, maybe with a map-version-system
10. When all that’s done… start debugging and optimizing :/
11. Have fun
12. Be successful
13. Give me a link to your finished editor!
14. Tell me if this guide helped you or not… and if you want to know anything more, or if something I wrote is totally wrong, or whatever you want
"
Editor-Programming-Tutorial
9_Sourcecodes
I added 3 Sourcecodes which might maybe help you.
Quote: "
1. My 2D Camera-System
2. Doyle-Map-Editor (Not very easy to use)
3. Stick Suicide 2 – Alternative Editor (Without media, just the code)
"
They are partly not very good and also not really easy to read, well remarked or whatever, but they more or less do their job. ^^
You may use the Camera-System for whatever you want, but please inform me if you want to use it for commercial products. ;-D
Thanks for your interest, I hope you will give me some feedback about this tutorial, and that you learned… something. If not, sorry for the waste of time, I gave my best, really.
Mr Kohlenstoff