Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: My (bad) level editor  (Read 7749 times)

0 Members and 1 Guest are viewing this topic.

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
My (bad) level editor
« on: June 29, 2013, 06:39:44 pm »
Hi all, I recently decided I want to learn sfml, since I heard some good things about it. I haven't used c++ before, but I know C and C# relatively okay.

I decided I want to learn how to make a game so I figured first thing first; make an engine, and make a map, then add on top of it.

So this project is hence kind of like that. It will eventually become an in game level maker, using the game engine to render everything, etc.

Here's a video of how it's coming along:
The minimap down the bottom right is going the be the box that holds the tileset, I just made it a minimap to test it was working functionally. I'm going to read in one big image; this image will be then split up in to many smaller images within the code. I'm not sure how to do that. Does anyone have any idea?



I absolutely know it sucks... I only just started the other day and I'm probably 5 or 10% finished.

I was hoping someone could give me some feedback on my code, etc, since I'm not very fluent in sfml, quite yet. One thing I've noticed is that the program uses 10% CPU, which I guess is okay; however, it uses 300 MB Ram!. I don't see how it can use that much memory... It's really high usage for what I'm doing. Does anyone know why my code is causing so much ram to be used?

Anyway, here's the code: If you notice anything you think I'm doing badly/inefficiently/should be doing different, can you please tell me :)

#include <SFML/Window.hpp>
#include <SFGUI/SFGUI.hpp>
#include <SFML/Graphics.hpp>
#include <cmath>

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "Windows.h"
using namespace std;
const int tileSize = 40;
#define SIZE 1000

typedef struct {
        sf::Sprite sprite;
        bool changed;
} grid;

bool SpriteDown(sf::Sprite &sprite, sf::RenderWindow &window, int buttonNum, sf::Event &evt)
{

        if (evt.type == sf::Event::MouseButtonReleased)
        {

#pragma region Left Click
                if (buttonNum == 0)
                {
                        if (evt.mouseButton.button == sf::Mouse::Left)
                        {
                                sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
                                sf::FloatRect bounds = sprite.getGlobalBounds();
                                if (bounds.contains(mouse))
                                        return true;
                        }
                        return false;
                }
#pragma endregion

#pragma region Right Click
                else if (buttonNum == 1)
                {
                        {
                                if (evt.mouseButton.button == sf::Mouse::Right)
                                {
                                        sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
                                        sf::FloatRect bounds = sprite.getGlobalBounds();
                                        if (bounds.contains(mouse))
                                        {
                                                return true;
                                        }
                                }
                        }
                }
#pragma endregion

        }
        return false;
}

bool SpriteClicked(sf::Sprite &sprite, sf::RenderWindow &window, int buttonNum)
{

#pragma region Left Click
        if (buttonNum == 0)
        {
                if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
                {
                        // transform the mouse position from window coordinates to world coordinates
                        sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));

                        // retrieve the bounding box of the sprite
                        sf::FloatRect bounds = sprite.getGlobalBounds();

                        // hit test
                        if (bounds.contains(mouse))
                                return true;

                }
                return false;
        }
#pragma endregion

#pragma region Right Click
        else if (buttonNum == 1)
        {
                {
                        if(sf::Mouse::isButtonPressed(sf::Mouse::Right))
                        {
                                // transform the mouse position from window coordinates to world coordinates
                                sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));

                                // retrieve the bounding box of the sprite
                                sf::FloatRect bounds = sprite.getGlobalBounds();

                                // hit test
                                if (bounds.contains(mouse))
                                {
                                        return true;
                                }
                                return false;
                        }
                }
        }
        return false;
#pragma endregion
}

void InitButtons(sf::Sprite & okBtn, sf::Sprite &zoomBtn, sf::Sprite &unzoomBtn, sf::Sprite &refreshBtn, sf::Texture & texture, sf::Texture &zoomTex, sf::Texture &unZoomTex, sf::Texture &refreshTex)
{
        //load textures
        texture.loadFromFile("C:\\Users\\Kevin Mallinson\\Documents\\Visual Studio 2012\\Projects\\MapMaker\\MapMaker\\btn.png");
        zoomTex.loadFromFile("C:\\Users\\Kevin Mallinson\\Documents\\Visual Studio 2012\\Projects\\MapMaker\\MapMaker\\zoom.png");
        unZoomTex.loadFromFile("C:\\Users\\Kevin Mallinson\\Documents\\Visual Studio 2012\\Projects\\MapMaker\\MapMaker\\unzoom.png");
        refreshTex.loadFromFile("C:\\Users\\Kevin Mallinson\\Documents\\Visual Studio 2012\\Projects\\MapMaker\\MapMaker\\refresh.png");
        //ok button

        okBtn.setTexture(texture);
        okBtn.setScale(sf::Vector2f(0.2f, 0.2f)); // absolute scale factor
        okBtn.setPosition(sf::Vector2f(1450, 815));
        //zoom button
        zoomBtn.setTexture(zoomTex);
        zoomBtn.setPosition(sf::Vector2f(1550, 15));
        //unzoom button
        unzoomBtn.setTexture(unZoomTex);
        unzoomBtn.setPosition(sf::Vector2f(1450, 15));
        //refresh button
        //refreshBtn.setTexture(refreshTex);
        //refreshBtn.setPosition(sf::Vector2f(1450, 515));
}

void MoveView(sf::View &view, sf::RenderWindow &window, sf::FloatRect &screenRect)
{

        int a = view.getCenter().y + view.getSize().y / 2;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                if (SIZE * tileSize > view.getCenter().x + view.getSize().x / 2)
                        view.move(5, 0);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                if ((view.getCenter().x - view.getSize().x/ 2) - 40 > 0) //since im rendering an extra tile, minus 40 to take that in to consideration
                        view.move(-5, 0);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                if (SIZE * tileSize > view.getCenter().y + view.getSize().y / 2)
                        view.move(0, 5);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                if ((view.getCenter().y - view.getSize().y / 2) - 40 > 0)
                        view.move(0, -5);
}

void RenderMap(int & startX, int & startY, int & endX, int & endY, grid gridArray[][SIZE], sf::RenderWindow & window, sf::View & view, sf::Event & event, sf::Vector2f & worldPos)
{
        for (int i = startX; i < endX; i++)
        {                      
                for (int j = startY; j < endY; j++)
                {
                        window.draw(gridArray[i][j].sprite);

                        if (worldPos.x < view.getCenter().x + view.getSize().x / 2
                                && worldPos.x >  view.getCenter().x - view.getSize().x/ 2
                                && worldPos.y >  view.getCenter().y - view.getSize().y / 2
                                && worldPos.y <  view.getCenter().y + view.getSize().y / 2)
                        {                      
                                if (SpriteClicked(gridArray[i][j].sprite, window, 0) && gridArray[i][j].changed == false)
                                {
                                        gridArray[i][j].sprite.setColor(sf::Color(0, 255, 0));
                                        gridArray[i][j].changed = true;
                                }
                                else if (SpriteDown(gridArray[i][j].sprite, window, 1, event) && gridArray[i][j].changed == true)
                                {
                                        gridArray[i][j].sprite.setColor(sf::Color(255, 255, 255));
                                        gridArray[i][j].changed = false;       
                                }
                        }
                }
        }
}

void FindIndexCollider(int & startX, int & startY, int & endX, int & endY, sf::FloatRect & screenRect)
{
        startX = floor(screenRect.left / tileSize - 1);
        startY = floor(screenRect.top / tileSize - 1);
        //bounds checking
        if (startX < 0)
                startX = 0;
        if (startY < 0)
                startY = 0;
        if (startX > SIZE)
                startX = SIZE;
        if (startY > SIZE)
                startY = SIZE;
        //end variables
        endX = startX + 50;
        endY = startY + 50;
        //bounds checking
        if (endX < 0)
                endX = 0;
        if (endY < 0)
                endY = 0;
        if (endX > SIZE)
                endX = SIZE;
        if (endY > SIZE)
                endY = SIZE;

}

int main()
{

        #pragma region Variable Declarations

                //Variable Declarations
                int startX = 0, endX = 0, startY = 0, endY = 0;
                static float FPS;
                static float nextSecond;
                static float prevSecond;
                auto gridArray = new grid[SIZE][SIZE]();
                sf::Text atext;
                sf::Font MyFont;
                sf::Clock clock;
                sf::Texture texture, gridTex, zoomTex, unZoomTex, refreshTex;
                sf::Sprite okBtn, zoomBtn, unzoomBtn, refreshBtn;
                sf::Vector2f worldPos;
                gridTex.loadFromFile("grid.png");
                InitButtons(okBtn, zoomBtn, unzoomBtn, refreshBtn, texture, zoomTex, unZoomTex, refreshTex);

        #pragma endregion

        #pragma region Initialize the grid array

                //I start at 1 simply so i can use these variables in my arithmatic, as something * 0 is 0
                for (int i = 1; i <= SIZE; i++)
                {
                        for (int j = 1; j <= SIZE; j++)
                        {
                                gridArray[i-1][j-1].sprite.setTexture(gridTex);
                                gridArray[i-1][j-1].sprite.setPosition(sf::Vector2f(i*tileSize, j*tileSize));
                                gridArray[i-1][j-1].changed = false;
                        }
                }
        #pragma endregion

        #pragma region Window initialization

        //Initiate the SFML window
        sf::RenderWindow window(sf::VideoMode(1600, 900), "Level Editor", sf::Style::Titlebar | sf::Style::Close );
        sf::Vector2i pixelPos = sf::Mouse::getPosition(window);
        window.setFramerateLimit(60);
        window.setVerticalSyncEnabled(true);

        //Create the views
        sf::View gridView(sf::Vector2f(1400, 440), sf::Vector2f(1160, 880));
        gridView.setViewport(sf::FloatRect(0.027f, 0.047f, 0.7f, 0.91f));
        sf::View tileSetView(sf::Vector2f(1400, 440), sf::Vector2f(1160, 880));
        tileSetView.setViewport(sf::FloatRect(0.74f, 0.404f, 0.25f, 0.55f));
        sf::View defaultView(sf::Vector2f(1600, 900), sf::Vector2f(800, 450));

        //loop to reset the views position at top left. figure out an programmatic way to do this with an algorithm
        gridView.move(0, 100);
        while ((gridView.getCenter().x - gridView.getSize().x/ 2) - 40 > 0)
                gridView.move(-5, 0);
        while ((gridView.getCenter().y - gridView.getSize().y / 2) - 40 > 0)
                gridView.move(0, -5);

        sf::Vector2f defaultSize = gridView.getSize();
        #pragma endregion
       
        #pragma region Container Stuff
        //Create the containers for the GUI
        sfg::SFGUI sfgui;
        sfg::Window::Ptr window2, window3;
        window2 = sfg::Window::Create();
        window3 = sfg::Window::Create();

        //Set style, position and size for the virtual windows
        window2->SetStyle(sfg::Window::Style::BACKGROUND &&  sfg::Window::Style::NO_STYLE );
        window2->SetRequisition(sf::Vector2f(1144,50));
        window2->SetPosition(sf::Vector2f(31,850.5));
        window3->SetStyle(sfg::Window::Style::BACKGROUND &&  sfg::Window::Style::NO_STYLE );
        window3->SetRequisition(sf::Vector2f(50, 871));
        window3->SetPosition(sf::Vector2f(2.5f, 30));

        //Create two boxes to hold each scroll bar
        sfg::Box::Ptr box, box2;
        box = sfg::Box::Create( sfg::Box::VERTICAL );
        box2 = sfg::Box::Create( sfg::Box::VERTICAL );

        //Horizontal and vertical scroll bars for the main grid
        sfg::Scrollbar::Ptr scrollX = sfg::Scrollbar::Create(sfg::Scrollbar::HORIZONTAL);
        sfg::Scrollbar::Ptr scrollY = sfg::Scrollbar::Create(sfg::Scrollbar::VERTICAL);

        box->Pack(scrollX);
        box2->Pack(scrollY);
        box->SetSpacing( 5.f );
        box2->SetSpacing( 5.f );
        window2->Add( box );
        window3->Add( box2 );
        #pragma endregion

        #pragma region Main Loop
                while (window.isOpen())
                {
                        sf::Event event;

                        while (window.pollEvent(event))
                        {
                                window2->HandleEvent( event );
                                window3->HandleEvent( event );
                                // "close requested" event: we close the window
                                if (event.type == sf::Event::Closed)
                                        window.close();
                        }

                        //Clear the screen
                        window.clear(sf::Color::White);

                        //Move the main View when pressing arrow keys
                        sf::FloatRect screenRect(sf::Vector2f(gridView.getCenter().x - (gridView.getSize().x)/2, gridView.getCenter().y - (gridView.getSize().y)/2) , gridView.getSize());
                        sf::FloatRect screenRect2(sf::Vector2f(tileSetView.getCenter().x - (tileSetView.getSize().x)/2, tileSetView.getCenter().y - (tileSetView.getSize().y)/2) , tileSetView.getSize());
                        MoveView(gridView, window, screenRect);

                        //Render the main grid
                        window.setView(gridView);
                        pixelPos = sf::Mouse::getPosition(window);
                        FindIndexCollider(startX, startY, endX, endY, screenRect);
                        RenderMap(startX, startY, endX, endY, gridArray, window, gridView, event, window.mapPixelToCoords(pixelPos));

                        //Render the tileset grid
                        window.setView(tileSetView);
                        pixelPos = sf::Mouse::getPosition(window);
                        FindIndexCollider(startX, startY, endX, endY, screenRect2);
                        RenderMap(startX, startY, endX, endY, gridArray, window, tileSetView, event, window.mapPixelToCoords(pixelPos));

                        //NOTE: SFGUI IS BUGGY; you must render at least ONE thing AFTER setting the new view,
                        //in order for SFGUI to KNOW that you set the view, otherwise it will use the old view.
                        window.setView(window.getDefaultView());

                        //Draw buttons from sprites
                        window.draw(zoomBtn);
                        window.draw(unzoomBtn);

                        //Button clicked events
                        if (SpriteClicked(unzoomBtn, window, 0))
                                if (defaultSize.x >= gridView.getSize().x)
                                        gridView.zoom(1.02f);
                        if (SpriteClicked(zoomBtn, window, 0))
                                gridView.zoom(0.98f);

                        //Finally, draw everything.
                        window2->Update(60);   
                        window3->Update (60);
                        sfgui.Display( window );
                        window.display();

                }
        #pragma endregion

}
« Last Edit: June 29, 2013, 06:42:03 pm by Anteara »

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: My (bad) level editor
« Reply #1 on: June 30, 2013, 09:37:14 am »
Good job, keep it up ;)

The editor is consuming a lot of memory because of this line.

auto GridArray = grid[SIZE][SIZE];

The "grid" structure contains a sprite and a boolean. Let's ignore the boolean and just focus on the size of the sprite: if you use "sizeof", you will know that each sprite uses around 272 bytes of memory. You are making an array of 1000x1000 of those sprites. so, let's do some calculations:

272 bytes x 1000 x 1000 = 272,000,000 bytes = 259 MB !!!

So yeah, that's the reason.

You need to figure out how to represent the exact same map but using less sprites. For instance, you don't really NEED that many sprites if only a small bunch of them are showed onscreen at a given time  :P

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #2 on: June 30, 2013, 11:35:42 am »
Hi, thanks for responding.

Yep i thought that might be the culprit. since the function sprite takes a reference to the texture, I didn't think it would be making new sprites for EVERY element.

Could this work: Instead of using an array of sprites, use an array of sprite pointers. This way, say I want a 'blank' sprite, and a 'green sprite', It will only store the memory address of that sprite in the array, NOT the sprite itself.

Furthermore, if the tileset is 10 images, I just use the pointers to those images, and form the map using only 10 images, instead of recreating it, and using 10,000 images.

Do I understand pointers correctly in this context? Do you think that would work?

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: My (bad) level editor
« Reply #3 on: June 30, 2013, 05:48:41 pm »
I don't think that would work.

See, an sprite contains a reference to a texture plus its own data like position, scale and things like that. So, lets say that you create two sprites; a white one and a green one, and both of them are initialized with position 0x0. If you use an array of pointers to those sprites -and let's say that the whole array points to the green sprite because you want a full map of green sprites- then when you draw the array, it will draw a green sprite at position 0x0 again and again, 1 million times (as the array is 1000x1000). So, the end result will be just a single lonely green sprite at position 0x0 that was drawn 1 million times each frame.

Sorry for the bad explanation, but I hope you get the idea  :P

It's good to use a lot of sprites, as they use very little memory and each of them has their own position and other data, but you are using way too many of them, that's the problem. Even an array of 1000x1000 integers will use a lot of memory.

One solution could be that instead of using an array of 1000x1000 sprites, you use an array of 1000x1000 numbers (an array of booleans, chars, ints, floats, whatever) to have the data for each tile of the map (0 = white, 1 = green, 2 = red, etc). Then, to actually show the map on screen, you create a small array of sprites (let's say 30x30, as you can only see 30x30 sprites on screen at most). You read a 30x30 chunk of numbers from the big array, and depending of the values, you change the color of the sprites accordingly.

So, let's say that you have your 30x30 sprites in place: you can see a nice map. Then, if you move the camera to the right, you move all your sprites to the right as well, read a new chunk of numbers and update the colors. It will give the illusion that it's one big map but actually it's just a small amount of sprites that are moving and changing underneath.

Again, sorry for the bad explanation. Hopefully you'll get the general idea.

Now, calculating the memory usage:

30x30 sprites = 272 bytes x 30 x 30 = 244,800 bytes = 0.2 MB.
1000x1000 chars = 1 byte x 1000 x 1000 = 1,000,000 = 1 MB
Total = 1,2 MB.

Why an array of chars instead of ints? They use less memory, simple as that (1 byte versus 4). With chars you will only have a range of 0 - 256 numbers, but that's more than enough; I doubt that you'll have a map with more than 256 different types of tiles.

That's just one solution. I bet that there are better ones, you just need to be creative :P
« Last Edit: June 30, 2013, 05:51:34 pm by AFS »

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #4 on: June 30, 2013, 11:24:20 pm »
    Awesome, I like that idea. Honestly, the only reason I did it the way I did is because I didn't know how to do it better. :P

    So essentially:

    • I have a "master" array, which in a realistic sense might be 300x300 tiles.
      • The master array ONLY holds letters. It's index in the array is what holds the position on the grid, so essentially the master array is just a char [][] instead of a structure array of char.
      • The master array will contain the finished level data, when saving to disk, the index of the array element is also saved, OR the ORDER in which things are saved define their index.
        i.e. a 01; b02; c03 OR abc. the latter would probably be faster.
    • I have a "tileset" array, which I could make a struct, to which each element has a corresponding letter to it.

    • The "RenderTile" array, for lack of a better name is a 30x30 array at the start of its creation.
      If I scroll right, I resize to make it say 35x30, and so on. If I use this method, I will NOT allow scrolling unless all other tiles have been taken up on that axes. In the case of resizing it might instead be wiser to use a vector.
      • The render tile array is what actually contains the sprite. I get the sprite information; reading from master (if I read a, and i is 0, and j is 0, it means the RenderTile[0][1] will be whatever that corresponds to, but the actual sprite of it.)

    Sorry if that doesn't make sense, I just woke up and had 2 hours sleep, and am drinking loads of coffee. :X
    But do you think that would work? That's how I interpreted your post, and I think your idea is a good one.
« Last Edit: June 30, 2013, 11:54:33 pm by Anteara »

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: My (bad) level editor
« Reply #5 on: July 01, 2013, 12:43:37 am »
Yeah, that's kind of the idea. Very hard to explain, isn't it?

So, you have your master array which contains the data of every tile of the whole map: I recommend using numbers (yes, you can store numbers in a char; a character is basically a number).

And you have an array of sprites. 30x30 was just an example; use whatever size is enough to fill the camera with tiles. However, this array will always be of the size you choose, you don't need to resize it, you just move it around the map, so it always follows the camera, and each time it moves, you update the colors by reading the master array.

Look at the following ilustration:



Focus on the image of the left. All the numbers are the "master array", this is the actual data that is modified, saved, whatever. The red rectangle is the camera, this is what you see on screen. Finally, the 3x3 colored rectangles are your sprites (3x3 in this example, which is enough to fill the camera). The sprites are colored depending of the value of the master array (1 = white, 2 = green, 3 = red, etc).

Now check the second image: you moved the camera enough to actually get out of the positions of the sprites and the camera will show empty space. So, to avoid this, you move all the sprites some space to the right (a space equal to the width of the tile), and read the data from the master array again (you need to read the data corresponding to the new position, be careful with this). After reading, update the colors/change the textures of the sprites accordingly, and there you have it, you are showing a map of who knows how many tiles but using only 3x3 sprites (in this example at least).

It's a difficult to implement, but once you manage to get it right it's so satisfying. :P

I insist, though: this may not be the best solution, but it's the only thing that occurred to me when I was making my map editor, and I liked the results.

Finally, if you plan to create a game that uses small maps, don't bother with this. Use this only if you need big maps for some reason. Otherwise, it's not worth it.
« Last Edit: July 01, 2013, 01:03:20 am by AFS »

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #6 on: July 05, 2013, 11:18:22 am »
Hey, thanks. Sorry for the late reply, I was working on stuff.

So i took what you said above as well as modified the vertex array tutorial, and I came up with this:



Basically, when i hover over a tile on the tileset, it renders that specific individual tile.
So if I want to now, I could make code probably quite easily to now apply that to adding the tiles on my map.

Unfortunately, it uses 16% cpu :(

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #7 on: July 05, 2013, 04:16:20 pm »




New video, it uses like 2% CPU now.
« Last Edit: July 05, 2013, 04:19:40 pm by Anteara »

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: My (bad) level editor
« Reply #8 on: July 05, 2013, 07:43:49 pm »
Nice!

I wasn't aware of the VertexArray method, and it seems to be much better than the solution I described, so go for it.

I watched your new videos, but what about scrolling the map? Still working on it?

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #9 on: July 07, 2013, 01:12:43 pm »
Nice!

I wasn't aware of the VertexArray method, and it seems to be much better than the solution I described, so go for it.

I watched your new videos, but what about scrolling the map? Still working on it?



Here is the progress I'm up to now.
And I used the method with using a "master array" creating the image, and I will do scrolling of the map.

However, as it is now, I'm not entirely sure If it will be worth it to use a culling method to render only what is in the scope of the window, as a) vertex arrays use virtually no cpu, and even a 5000x5000 map would only use 5mb of ram; however depending on where I'm publishing the game (i.e. on mobile devices I would need to make that ram usage lower.) However, I think on a PC, a 5mb map is fine.

But I am using a culling algorithm at the moment, and hence I probably should keep it for the sake of not changing what isn't broken.

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #10 on: July 07, 2013, 10:15:40 pm »
Here are some screenies of my editor

This editor is created by me.
It is free to use if it fits your purpose so cheers!

Pros:
Free to use
Supports huge map size(5000x5000) with ease (no minimap, gl scrolling ;p )
Two layers support
Each layer/coolision can be turned on and off for better visibility
Completely customable enemies in mapEditor
Cons:
It has bean made in few hours.
The list is too big...

The file format is saved in .txt files
Its writen like this (mapSizeX(integer value) mapSizeY(integer value) \nLayer1(integer value):Layer2(integer value):Collision(integer value);
A example map would be
[3 3
1:0:3 1:0:2 1:0:2
2:3:0 1:2:0 1:0:2
1:2:3 1:1:1 1:23333:91102]

Just random image of loaded map
http://s24.postimg.org/kd9yie869/image.jpg?noCache=1373227286
http://s8.postimg.org/upo4kcg8h/image.png?noCache=1373227325
http://s8.postimg.org/sz53iuypd/image.png?noCache=1373227325

This is tile layer1 selection
http://s8.postimg.org/yxiwt3ho1/image.png?noCache=1373227325

This is tile layer2 selection
http://s8.postimg.org/i8hgx6l2p/image.png?noCache=1373227325

This is enemy editor
http://s8.postimg.org/m9yk2uddd/image.png?noCache=1373227325

Keep up the good work!
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Anteara

  • Newbie
  • *
  • Posts: 40
    • View Profile
    • Email
Re: My (bad) level editor
« Reply #11 on: July 09, 2013, 01:06:17 pm »
Thanks, I find it odd that I can't find a tileset which i can make nice patterns from. Like for example, if I use 32x32, I can't make a "path" only squares of paths. This is fixed if I use 16x16. It's strange though because I thought 32x32 is what is widely used.

I made my engine work with both, and any other size, so I guess that's okay. Perhaps I should make the layer system be able to use different sizes too (i.e. layer 1 32x32, layer 2 16x16 etc)