I'm currently developing a 2D isometric map editor.
I display entity(cube, player) which contains points and textures.
Each cubes are composed by 12 points.(12 points, but handled as 3 sides of 4 points when displayed by sfml(sf::VertexArray).
(I know I include some '.cpp' times to times, I have a problem with my IDE(visual studio) which I'm trying to resolve, please do not care about it.)
main.cpp
#pragma once
#include "globalfunctions.h" //global functions + main headers + class headers
int main() {
int mapSize = 0;
int cubeSize = 0;
cout << "Map size: "; cin >> mapSize; cout << endl;
cout << "Cube size: "; cin >> cubeSize; cout << endl;
int windowWidth = (mapSize * cubeSize) - (cubeSize * 2);
int windowHeight = ((mapSize * cubeSize) - (cubeSize * 2)) / 2;
renderWindow window(windowWidth, windowHeight, mapSize, cubeSize);
int nbMaxTextures = 9;
for (int t = 0; t < nbMaxTextures; t++) {
window.loadTexture("test", t);
}
window.run();
return EXIT_SUCCESS;
}
globalfunctions.h
#pragma once
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <math.h>
//#include <sstream>
#include <vector>
using namespace std;
sf::Vector2u isometricToCartesian(int i, int j, int cubeSize) {
sf::Vector2u carth;
carth.x = (j - i) * (cubeSize / 2);
carth.y = (j + i) * (cubeSize / 4);
return carth;
}
sf::Vector2u cartesianToIsometric(int x, int y, int cubeSize) {//TODO
sf::Vector2u iso;
iso.x = 0;
iso.y = 0;
return iso;
}
#include "entity.h"
#include "renderWindow.h"
renderWindow.h
#pragma once
class renderWindow {
public:
renderWindow(float WIDTH, float HEIGHT, int MAPSIZE, int CUBESIZE);
void run();
void loadTexture(sf::String folder, int numTexture);
//SETTERS
//...
//GETTERS
//...
private:
int mCurrentLayerID;
int mMapSize;
int mCubeSize;
int mSelectedTexture;
vector<entity> mMap;
sf::RenderWindow mWindow;
vector<sf::Texture> mTextures;
sf::Texture mMemoryTexture;
void processEvent();
void update(sf::Time deltaTime);
void render();
//CUBE ACTION-------------------------------------------
void addCube(int layerID, float x, float y);
entity& getCube(int ID);
entity& getCubeAt(float x, float y);
vector<sf::VertexArray> loadCube(int cubeID);//UPDATE DATA LIKE COORDINATES -> create/chnge the vertex
void drawCube(int cubeID);//draw the vertex
//VARIABLES
vector<sf::VertexArray> verticesSide1;
vector<sf::VertexArray> verticesSide2;
vector<sf::VertexArray> verticesSide3;
//CUBE ACTION-------------------------------------------
};
#include "renderWindow.cpp"
renderWindow.cpp
#pragma once
renderWindow::renderWindow(float WIDTH, float HEIGHT, int MAPSIZE, int CUBESIZE) : mWindow(sf::VideoMode(WIDTH, HEIGHT), "") {
mMapSize = MAPSIZE;
mCubeSize = CUBESIZE;
mSelectedTexture = 6;
mCurrentLayerID = -1;
int x = 0;
int y = 0;
//default layer
for (int j = 0; j < mMapSize; j++) {
for (int i = 0; i < mMapSize; i++) {
x = isometricToCartesian(i, j, mCubeSize).x;
y = isometricToCartesian(i, j, mCubeSize).y;
addCube(0, x, y);
}
}
for (int c = 0; c < mMap.size(); c++) {
verticesSide1.push_back(loadCube(c)[0]);
verticesSide2.push_back(loadCube(c)[1]);
verticesSide3.push_back(loadCube(c)[2]);
//then only do that when something the cube's coordinate changed
}
}
void renderWindow::run() {
sf::Clock clock;
sf::Time timeSinceLastUpdate = sf::Time::Zero;
sf::Time TimePerFrame = sf::seconds(1.f / 60.f);
while (mWindow.isOpen()) {
processEvent();
timeSinceLastUpdate += clock.restart();
while (timeSinceLastUpdate > TimePerFrame) {
timeSinceLastUpdate -= TimePerFrame;
processEvent();
update(TimePerFrame);
}
render();
}
}
void renderWindow::loadTexture(sf::String folder, int numTexture) {
if (mMemoryTexture.loadFromFile("textures/" + folder + "/" + to_string(numTexture) + ".jpg"))
mTextures.push_back(mMemoryTexture);
else
cout << "Texture n°" << numTexture << " as failed to load." << endl;
}
//SETTERS
//...
//GETTERS
//...
//PRIVATE METHODE
void renderWindow::processEvent() {
sf::Event event;
while (mWindow.pollEvent(event)) {
switch (event.type) {
case sf::Event::Closed:
mWindow.close();
break;
case sf::Event::KeyPressed:
if (event.key.code == sf::Keyboard::Escape)
mWindow.close();
break;
case sf::Event::MouseButtonPressed:
if (event.MouseButtonPressed == sf::Mouse::Left)
getCubeAt(event.mouseButton.x, event.mouseButton.y).setTexture(0, mSelectedTexture);//TEST
getCubeAt(event.mouseButton.x, event.mouseButton.y).setTexture(1, mSelectedTexture + 1);//TEST
getCubeAt(event.mouseButton.x, event.mouseButton.y).setTexture(2, mSelectedTexture + 2);//TEST
break;
/*case sf::Event::MouseMoved:
cout << "(" << event.mouseMove.x << ", " << event.mouseMove.y << ")" << endl;
break;*/
}
}
}
void renderWindow::update(sf::Time deltaTime) {
//REMEMBER: distance = speed * time
//MOVEMENT, ANIMATIONS ETC. ...
}
void renderWindow::render() {
mWindow.clear();
for (int c = 0; c < mMap.size(); c++) {
drawCube(c);
}
mWindow.display();
}
//CUBE ACTION-------------------------------------------
void renderWindow::addCube(int layerID, float x, float y) {
//Thoses make the code more readable:
int half_cubeSize = mCubeSize / 2;
int oneQuarter_cubeSize = mCubeSize / 4;
int twoQuarter_cubeSize = oneQuarter_cubeSize * 2;
int treeQuarter_cubeSize = oneQuarter_cubeSize * 3;
mCurrentLayerID = layerID;
entity dummy(mMap.size(), 0, layerID);
dummy.addPoint(12);
dummy.addTexture(6);
dummy.addTexture(7);
dummy.addTexture(8);
//SIDE 1------------------------------------------------
dummy.setPoint(0, x, y + oneQuarter_cubeSize);
dummy.setPoint(1, x + half_cubeSize, y + twoQuarter_cubeSize);
dummy.setPoint(2, x + half_cubeSize, y + mCubeSize);
dummy.setPoint(3, x, y + treeQuarter_cubeSize);
//SIDE 2------------------------------------------------
dummy.setPoint(4, x + half_cubeSize, y + twoQuarter_cubeSize);
dummy.setPoint(5, x + mCubeSize, y + oneQuarter_cubeSize);
dummy.setPoint(6, x + mCubeSize, y + treeQuarter_cubeSize);
dummy.setPoint(7, x + half_cubeSize, y + mCubeSize);
//SIDE 3------------------------------------------------
dummy.setPoint(8, x, y + oneQuarter_cubeSize);
dummy.setPoint(9, x + half_cubeSize, y);
dummy.setPoint(10, x + mCubeSize, y + oneQuarter_cubeSize);
dummy.setPoint(11, x + half_cubeSize, y + twoQuarter_cubeSize);
mMap.push_back(dummy);
}
entity& renderWindow::getCube(int ID) {
for (int c = 0; c < mMap.size(); c++) {
if (mMap[c].getID() == ID)
return mMap[c];
}
}
entity& renderWindow::getCubeAt(float x, float y) {//TO DO
return entity(-1, 0, 0);
}
vector<sf::VertexArray> renderWindow::loadCube(int cubeID) {
vector<sf::VertexArray> vertices;
vertices.push_back(sf::VertexArray());
vertices.push_back(sf::VertexArray());
vertices.push_back(sf::VertexArray());
vertices[0].setPrimitiveType(sf::Quads);
vertices[0].resize(4);
vertices[1].setPrimitiveType(sf::Quads);
vertices[1].resize(4);
vertices[2].setPrimitiveType(sf::Quads);
vertices[2].resize(4);
sf::Vector2f tv0 = sf::Vector2f(0, 0);
sf::Vector2f tv1 = sf::Vector2f(mCubeSize, 0);
sf::Vector2f tv2 = sf::Vector2f(mCubeSize, mCubeSize);
sf::Vector2f tv3 = sf::Vector2f(0, mCubeSize);
sf::Vector2f v0 = sf::Vector2f(getCube(cubeID).getPoint(0, 0), getCube(cubeID).getPoint(0, 1));
sf::Vector2f v1 = sf::Vector2f(getCube(cubeID).getPoint(1, 0), getCube(cubeID).getPoint(1, 1));
sf::Vector2f v2 = sf::Vector2f(getCube(cubeID).getPoint(2, 0), getCube(cubeID).getPoint(2, 1));
sf::Vector2f v3 = sf::Vector2f(getCube(cubeID).getPoint(3, 0), getCube(cubeID).getPoint(3, 1));
sf::Vector2f v4 = sf::Vector2f(getCube(cubeID).getPoint(4, 0), getCube(cubeID).getPoint(4, 1));
sf::Vector2f v5 = sf::Vector2f(getCube(cubeID).getPoint(5, 0), getCube(cubeID).getPoint(5, 1));
sf::Vector2f v6 = sf::Vector2f(getCube(cubeID).getPoint(6, 0), getCube(cubeID).getPoint(6, 1));
sf::Vector2f v7 = sf::Vector2f(getCube(cubeID).getPoint(7, 0), getCube(cubeID).getPoint(7, 1));
sf::Vector2f v8 = sf::Vector2f(getCube(cubeID).getPoint(8, 0), getCube(cubeID).getPoint(8, 1));
sf::Vector2f v9 = sf::Vector2f(getCube(cubeID).getPoint(9, 0), getCube(cubeID).getPoint(9, 1));
sf::Vector2f v10 = sf::Vector2f(getCube(cubeID).getPoint(10, 0), getCube(cubeID).getPoint(10, 1));
sf::Vector2f v11 = sf::Vector2f(getCube(cubeID).getPoint(11, 0), getCube(cubeID).getPoint(11, 1));
vertices[0][0] = sf::Vertex(v0, tv0);
vertices[0][1] = sf::Vertex(v1, tv1);
vertices[0][2] = sf::Vertex(v2, tv2);
vertices[0][3] = sf::Vertex(v3, tv3);
vertices[1][0] = sf::Vertex(v4, tv0);
vertices[1][1] = sf::Vertex(v5, tv1);
vertices[1][2] = sf::Vertex(v6, tv2);
vertices[1][3] = sf::Vertex(v7, tv3);
vertices[2][0] = sf::Vertex(v8, tv0);
vertices[2][1] = sf::Vertex(v9, tv1);
vertices[2][2] = sf::Vertex(v10, tv2);
vertices[2][3] = sf::Vertex(v11, tv3);
return vertices;
}
void renderWindow::drawCube(int cubeID) {
mWindow.draw(verticesSide1[cubeID], &mTextures[getCube(cubeID).getTexture(0)]);
mWindow.draw(verticesSide2[cubeID], &mTextures[getCube(cubeID).getTexture(1)]);
mWindow.draw(verticesSide3[cubeID], &mTextures[getCube(cubeID).getTexture(2)]);
}
//CUBE ACTION-------------------------------------------
entity.h
#pragma once
class entity {
public:
entity();
entity(int id, int type, int numlayer);
void addPoint(int nbPoints);
void addTexture(int numTexture);
//SETTERS
void setPoint(int numPoint, float x, float y);
void setTexture(int textureID, int numTexture);
//GETTERS
int getID();
float getPoint(int numPoint, int numIndex);//if numIndex = 0 -> x || if numIndex = 1 -> y
int getType();
int getNumLayer();
int getTexture(int numTexture);
private:
int mID;
int mType;
int mNumLayer;
vector<sf::Vector2u> mPoints;
vector<int> mTextures;
};
#include "entity.cpp"