🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Isometric not working correctly

Started by
2 comments, last by m_waddams 3 years ago

Hello,

I've been messing with GoDot and came across an isometric tutorial. I decided to try it in C++ using SFML because the formula they used to display isometric tiles never works for me, yet I've seen it before many times. I have a working formula, but I'm trying to figure out why this one specifically never works for me.

Here a screenshot of how it displays the tiles

Here is the isometric Godot tutorial

It seems that it is ONE tile off as if it's something simple that doesn't translate to SFML like it would Godot. One reason I like this tutorial is it involves an imaginary Z position for the layers.

#include <SFML/Graphics.hpp>
#include <vector>
#include <fstream>
#include <string>
#include <iostream>

sf::Vector2f operator*(const sf::Vector2f v, const int t)
{
	return sf::Vector2f(v.x * t, v.y * t);
}

std::ostream& operator<<(std::ostream& os, const sf::Vector2f& v)
{
	os << "X: " << v.x << " Y: " << v.y << "\n";
	return os;
}

const int TEXTURE_SCALE = 3;

const int texture_w = 24;
const int texture_h = 25;
const sf::Vector2f SINGLE_X = 
              sf::Vector2f(texture_w / 2, texture_h / 4) * TEXTURE_SCALE;
const sf::Vector2f SINGLE_Z = 
              sf::Vector2f(-texture_w / 2, texture_h / 4) * TEXTURE_SCALE;
const sf::Vector2f SINGLE_Y = 
              sf::Vector2f(0, -texture_h / 2) * TEXTURE_SCALE;
const int map_width  = 6;
const int map_height = 6;


sf::Vector2f game_to_engine(int x, int y, int z)
{
	sf::Vector2f rtn{ 0,0 };
	rtn += SINGLE_X * x;
	rtn += SINGLE_Z * z;
	rtn += SINGLE_Y * y;
	return rtn;
}

sf::Sprite newMovable(sf::RenderWindow& window, sf::Texture& t, int x, int y, int z)
{
	sf::Sprite sprite(t);
	auto pos = game_to_engine(0, 0, 0);
	sprite.setPosition({ texture_w * pos.x,texture_h * pos.y });
	sprite.setScale(TEXTURE_SCALE, TEXTURE_SCALE);
	return sprite;
}

struct Tile
{
	sf::Vector2f pos;
	sf::Sprite spr;
};

sf::Vector2f offset{ 200,250 };

int main()
{
	sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");

	sf::Texture grid_texture;  grid_texture.loadFromFile("grid.png");
	sf::Texture block_texture; block_texture.loadFromFile("movable.png");

	std::vector<Tile> floor_tiles(map_width * map_height);
	for (int x = 0; x < map_width; x++)	{
		floor_tiles.emplace_back();
		for (int z = 0; z < map_height; z++) {
			auto tile = new Tile;

			tile->pos = sf::Vector2f{ game_to_engine(x ,z ,0) };
			tile->spr.setPosition(tile->pos);
			tile->spr.setTexture(grid_texture);
			tile->spr.scale(TEXTURE_SCALE,TEXTURE_SCALE);
		
			floor_tiles.push_back(*tile);
		}
	}


	while (window.isOpen())	{
		sf::Event event;
		while (window.pollEvent(event))	{
			if (event.type == sf::Event::Closed)
				window.close();
		}

		window.clear(sf::Color::White);

		for (auto t : floor_tiles) {
			t.spr.move(offset);
			window.draw(t.spr);
		}

		newMovable(window, block_texture, 0, 1, 0);

		window.display();
	}

	return 0;
}

Any help would be appreciated.

Thanks, be safe, and have a good one.

Advertisement

game_to_engine(int x, int y, int z)

doesn't match

tile->pos = sf::Vector2f{ game_to_engine(x ,z ,0) };

Pass (x, 0, z).

@m_waddams Omg! Thank you man. I can't believe I missed that.

Thanks again, greatly appreciated.

If you don't mind can you explain to me why some people use:

const sf::Vector2f x = sf::Vector2f(texture_w / 2, texture_h / 4) * TEXTURE_SCALE; 
const sf::Vector2f y = sf::Vector2f(-texture_w / 2, texture_h / 4) * TEXTURE_SCALE;

(I just realized I lost all my projects and didn't save them to my external drive or github when I formatted my computer ?)

I had a specific formula I would always use. I believe it went like this and correct me if I'm wrong.

pos.x= x * (TILE_WIDTH/2)  - y *-TILE_HEIGHT;
pos.y= x * (TILE_HEIGHT/2) + y *(TILE_HEIGHT/2);

I can't recall if this was correct. But assuming that was my original isometric formula I used, why do people use that one or the previous one and what's the benefit? Does it have to do with the size of the tile? I typically see the /2 & /4 formula in older books.

I have no idea ?

I've used Clint Bellanger's tutorials forever, I've actually never seen the vector addition method you showed. Very interesting.

This topic is closed to new replies.

Advertisement